이전 글 CodeIgniter 라이브러리에 ZendAMF 추가하기를 마치셨다면 이번에는 Flex와 연동하는 것을 시작하겠습니다.
대부분은 글은 머드초보님의 글을 바탕으로 진행할 예정입니다.(출처: [Flex/PHP] Zend AMF를 이용한 PHP와 FLEX의 연동삽질후기)

①. 먼저 DB를 생성하고 데이터입력입니다

DROP TABLE IF EXISTS `sosi`.`sosi`; 
CREATE TABLE  `sosi`.`sosi` ( 
  `idx` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  `sosiname` varchar(45) NOT NULL, 
  `height` int(10) unsigned NOT NULL, 
  `blood` varchar(45) NOT NULL, 
  PRIMARY KEY (`idx`) 
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; 
 
INSERT INTO `sosi` (`idx`,`sosiname`,`height`,`blood`) VALUES  
 (1,'윤아',166,'B'), 
 (2,'수영',170,'O'), 
 (3,'효연',160,'AB'), 
 (4,'유리',167,'AB'), 
 (5,'태연',162,'O'), 
 (6,'제시카',163,'B'), 
 (7,'티파니',162,'O'), 
 (8,'써니',158,'B'), 
 (9,'서현',168,'A');

 

②. Flex Project 'ZendAmfTest'를 만듭니다. 머드초보님은 Application server type을 php으로 하셨는데 저는 서버가 외부에 있어서 None/Other로 하였습니다. 로컬이라면 php를 선택하신 다음에 아파치나 iis가 돌아가는 폴더를 지정하면 됩니다. 지정하게 되면 SWF가 서버로 바로 위치하게 되므로 테스트하기 편합니다.

③. 그런 다음 system>application>libraries에 sosimember.php라는 파일을 만듭니다. CI특성상 파일명은 소문자로 만드셔야합니다.


 

④. 다음은 DB에서 데이터를 가져오고 반환하는 모델을 만듭니다. system>application>models에 sosimodel.php를 생성하시고 아래 코드입력합니다.
load->library("SosiMember");
    	
        $query = $this->db->query('SELECT idx, sosiname, height, blood FROM sosi;');
        
        $ret = array();
        foreach ($query->result() as $row){        
            $tmp = new SosiMember(); 
            $tmp->idx = $row->idx; 
            $tmp->sosiname = $row->sosiname; 
            $tmp->height = $row->height; 
            $tmp->blood = $row->blood; 
            $ret[] = $tmp; 
        } 
        return $ret; 
    }
}  
?>

⑤. 다음은 controllers를 만듭니다. 여기에 ZendPHP가 들어갑니다. system>application>controllers에 remote.php를 생성하시고 아래 코드입력합니다.
load->model('SosiModel');    
    }
    
    public function index()
    {
        $this->load->library("Apps");
        $this->apps->load("Zend/Amf/Server");
        $server = new Zend_Amf_Server();
        $server->setClass("SosiModel"); 
		$server->setClassMap("SosiMember", "SosiMember"); 
		echo($server -> handle()); 
        
    }
}  
?>

⑥. 이제 Flex에게 PHP를 연결할 설정을 역할을 하는 service-config.xml을 만듭니다.
 
  
      
         
             
                    
              
             
                  
                    *  
                     
                
          
      
      
          
             
          
     

⑦. Flex파일 ZendAmfTest.mxmlf에 아래 코드를 입력합니다.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml
    layout="vertical"
    creationComplete="creationCompleteHandler()">
 <mx:Script>
  <![CDATA[
   import mx.controls.Alert;
   import mx.rpc.events.ResultEvent;
   import mx.rpc.events.FaultEvent;
   
   private function creationCompleteHandler():void
   {
    roSosi.getData();
   }
   
   private function faultHandler(event:FaultEvent):void
   {
    Alert.show(event.message.toString());
   }
   
   private function resultGetDataHandler(event:ResultEvent):void
   {
    dgSosi.dataProvider = event.result as Array;
   }
  ]]>
 </mx:Script>
 
 <mx:RemoteObject id="roSosi" fault="faultHandler(event)" destination="zend" source="SosiModel">
  <mx:method name="getData" result="resultGetDataHandler(event)" />
 </mx:RemoteObject>
 
 <mx:DataGrid id="dgSosi" width="100%" height="100%">
  <mx:columns>
   <mx:DataGridColumn headerText="아이디" dataField="idx"/>
   <mx:DataGridColumn headerText="소녀시대이름" dataField="sosiname"/>
   <mx:DataGridColumn headerText="신장" dataField="height" />
   <mx:DataGridColumn headerText="혈액형" dataField="blood" />
  </mx:columns>
 </mx:DataGrid>  
</mx:Application>

SyntaxHighlighter가 Flex를 지원하지 않네요ㅠ
만약 다른 서비스를 추가하게 된다면, <mx:RemoteObject>에서 endpoint를 다른 url로 잡아주면 됩니다.
<mx:RemoteObject id="roAnother" fault="faultHandler(event)"  
       
destination="zend" source="AnothorService"  
       
endpoint="http://localhost/ZendAmfTest-debug/another_amf.php">


그렇게 Flex를 컴파일 하게 되면 아래와 같이 출력됩니다.


이상입니다. 혹시 에러나 잘못된 점은 지적해주시기 바랍니다.

참고사이트:

http://corlan.org/2008/11/13/flex-and-php-remoting-with-zend-amf/ 
http://mudchobo.tomeii.com/tt/398

Posted by Finebe
,



AMF(Action Message Format
)이란?

-한마디로 말해서 서버와 SWF(플래시)의 통신이 AMF라고 불리는 Binary형식의 프로토콜을 사용하여 이루어지며 서버상에 있는 원격지 객체를 호출합니다.

-가장 작은 패킷 크기에 데이터 통신에 필요한 거의 모든 옵션을 넣을 수 있는 바이너리 메세징 프로토콜

-HTTP(80포트), HTTPS(443)를 통해 통신하기 때문에 방화벽을 무시할 수 있습니다.

-AMF는 플래시 플레이어가 인식 가능한 기본 메세징 포맷이므로 클라이언트에서 데이터 직렬화와 역직렬화가 자동으로 처리되며 속도도 빠릅니다.

-게이트웨이는 HTTP(80포트), HTTPS(443)를 통해 AMF패킷 송수신, AMF직렬화/역직렬화, 적절한 서비스에 요청위임 등을 수행할 수 있는 게이트웨이 라이브러리가 필요합니다. 이러한 게이트웨이 라이브러리 여러 종류 중에 우리는 여기서 ZendAMF라는 것을 사용할 것입니다.


AMF의 구조 :
 http://wiki.gnashdev.org/AMF


Actionscript & PHP Type Mapping

   

PHP to ActionScript mapping

  

PHP

ActionScript

null

null

boolean

boolean

string

string

DomDocument

xml

DateTime

date

float

number

integer

number

Associative Array w/ mix of keys

Object

Associative Array w/ Numeric index of keys

Array

object

object

RemoteClass Zend_Amf_Value_TypedObject

typed object

Zend_Amf_Value_ByteArray

flash.utils.ByteArray

Zend_Amf_Value_ArrayCollection

  

 

원본 위치 <http://framework.zend.com/wiki/display/ZFPROP/Zend_Amf+-+Wade+Arnold>


ZendAMF란?

-Remoting Gateway Library로써 Adobe가 공식지원하여 Zend 프레임워크에서 만들었습니다. AMF3 스펙를 사용하여 AMF0스펙를 사용한 AMFPHP보다 뛰어난 성능을 발휘합니다.    

----------------------------------------------------------------------------------------------------------------------

   

AMF3 스펙 기반으로 만들어진 ZendAMF 라이브러리를 가볍고 막강한 성능을 자랑하는 CI에 추가해보도록 하겠습니다.

   

  1. 준비물:
    1. CodeIgniter (http://codeigniter.com)
    2. ZendAMF (http://framework.zend.com/download/amf)
       
  2. CodeIgniter를 서버에 설치한 후 ZendAMF를 압축해제합니다. 그러면

    이 생성됩니다. 여기서 사용할 것은 library폴더에 들어있는 Zend라는 넘만 쓸 것입니다. Zend폴더를 복사하여
    system>application>libraries>Zend폴더에 넣습니다.

  3. CI의 config파일의 내용변경

    $config['enable_hooks'] = FALSE; --> $config['enable_hooks'] = TRUE;로 변경합니다.

  4. 후킹을 통한 프레임워크 코어확장
    코어파일을 해킹하지 않고도 내부작동방식을 변경하게 하는 기능인 후킹(설명)을 이용하여 컨트롤러가 호출되기 직전(pre-controller)에 실행하게 되게 추가합니다.

    위 hooks.php 파일에 아래 코드를 추가하시면 됩니다.

$hook['pre_controller'][] = array(

  'class' => 'App_hook',

  'function' => 'index',

  'filename' => 'app_hook.php',

  'filepath' => 'hooks'

);


5.    app_hook파일을 hooks폴더에 추가합니다.
 
app_hook.php 파일 안의 코드는

<?php 

if(!defined('BASEPATH')) exit('No direct script access allowed');

   

class App_hook

{

    function index()

    {

        ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.BASEPATH.'application/libraries/');

    }

}

?>

이는 기존의 include_path의 값에 appliaction/libraries/를 추가한 것입니다.

6.    Zend 클래스와 다른 프레임워크 클래스를 이용하기 위해 하나의 사용자 라이브러리 파일을 만듭니다.

 

     그 파일 안의 코드는 다음과 같습니다.

<?php if (!defined('BASEPATH')) {exit('No direct script access allowed');}

   

class Apps

{

    function __construct($class NULL)

    {

        if(!empty($class) && is_array($class))

        {

            foreach($class as $item)

            {

                $this->load($item);

            }

        }

    }

      

    function load($class)

    {

        require_once (string) $class EXT;

    }

?>


7.    이제 ZendAMF 라이브러리를 사용할 준비는 끝났습니다. 테스트로 ZendAMF를 로드하는 Remoting Class를 만들어보겠습니다. 여기서 주의하실 점은 폴더명의 대소문자입니다. 이 글의 참고사이트에는 대문자로 되어있어서 그대로 하시면 오류가 생기십니다.
 
        파일을 만드신 후에 안에 코드는 아래와 같습니다.

<?php

class Remote extends Controller 

{

    function Remote()

    {

        parent::Controller();    

    }

      

    function index()

    {

        $this->load->library("Apps");

        $this->apps->load("Zend/Amf/Server"); //여기서 AMF가 아니라 Amf입니다. 각자 다를 수 있으니 확인하세요

          

        $server = new Zend_Amf_Server();

        $server->setClass($this);

        echo $server->handle();

    }

      

    function getData()

    {

        return array(1,2,3,4,5);

    }

?>


8.     Remote클래스를 호출합니다.
 
이라고 뜬다면 성공입니다. 그 외에 폴더명이 잘못되서 에러가 발생할 수 있습니다. 다시 한번 대소문자를 꼭 확인!! 

   

  
 
참고사이트

http://codeigniter.com/wiki/AMF_Flash_Remoting_with_Zend_and_CI/
http://www.cyworld.com/duck_info/3856801
http://framework.zend.com/wiki/display/ZFPROP/Zend_Amf+-+Wade+Arnold

Posted by Finebe
,


여러개의 이미지 업로드할 수 있는 소스입니다.
참고사이트는
http://codeigniter.com/forums/viewthread/80610/
http://codeigniter.com/forums/viewthread/129011/

Controller

 
class Upload extends Controller {

    function Upload()
    {
        parent::Controller();
        $this->load->helper(array('form','url','file'));
        
    
    }
    
    function index()
    {
        
        $this->load->view('upload/upload_index'); //Upload Form
        
    }

    function picupload()
    {
        //Load Model
        $this->load->model('Process_image');

        $config['upload_path'] = './uploads/';
        $config['allowed_types'] = 'gif|jpg|png';
        $config['max_size']    = '2048'; //2 meg


        $this->load->library('upload');

        foreach($_FILES as $key => $value)
        {
            if( ! empty($key['name']))
            {
                $this->upload->initialize($config);
        
                if ( ! $this->upload->do_upload($key))
                {
                    $errors[] = $this->upload->display_errors();
                    
                }    
                else
                {

                    $this->Process_image->process_pic();

                }
             }
        
        }
        
        
        $data['success'] = 'Thank You, Files Upladed!';

        $this->load->view('upload/upload_pictures', $data); //Picture Upload View

        
        
        
    } 


Model
class Process_image extends Model {
    
    function Process_image()
    {
        parent::Model();
        
        $this->load->library('image_lib');
        //Generate random Activation code
        
        function generate_code($length = 10){
    
                if ($length <= 0)
                {
                    return false;
                }
            
                $code = "";
                $chars = "abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ123456789";
                srand((double)microtime() * 1000000);
                for ($i = 0; $i < $length; $i++)
                {
                    $code = $code . substr($chars, rand() % strlen($chars), 1);
                }
                return $code;
            
                }

    }

function process_pic()
    {   
        //Connect to database
        $this->load->database();
        
        //Get File Data Info
        $uploads = array($this->upload->data());
        
        $this->load->library('image_lib');

        //Move Files To User Folder
        foreach($uploads as $key[] => $value)
        {
            
                        //Gen Random code for new file name
            $randomcode = generate_code(12);
            
            $newimagename = $randomcode.$value['file_ext'];
            
            //Creat Thumbnail
            $config['image_library'] = 'GD2';
            $config['source_image'] = $value['full_path'];
            $config['create_thumb'] = TRUE;
            $config['thumb_marker'] = '_tn';
            $config['master_dim'] = 'width';
            $config['quality'] = 75;
            $config['maintain_ratio'] = TRUE;
            $config['width'] = 175;
            $config['height'] = 175;
            $config['new_image'] = '/pictures/'.$newimagename;

            //$this->image_lib->clear();
            $this->image_lib->initialize($config);
            //$this->load->library('image_lib', $config);
            $this->image_lib->resize();
            
            //Move Uploaded Files with NEW Random name
            rename($value['full_path'],'/pictures/'.$newimagename);
            
            //Make Some Variables for Database
            $imagename = $newimagename;
            $thumbnail = $randomcode.'_tn'.$value['file_ext'];
            $filesize = $value['file_size'];
            $width = $value['image_width'];
            $height = $value['image_height'];
            $timestamp = time();
            
            //Add Pic Info To Database
            $this->db->set('imagename', $imagename);
            $this->db->set('thumbnail', $thumbnail);
            $this->db->set('filesize', $filesize);
            $this->db->set('width', $width);
            $this->db->set('height', $height);
            $this->db->set('timestamp', $timestamp);
            
            //Insert Info Into Database
            $this->db->insert('pictures');

        }
        
        
        
    }


View


Table
CREATE TABLE IF NOT EXISTS `img_pictures` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `imagename` varchar(100) NOT NULL,
  `thumbnail` varchar(100) DEFAULT NULL,
  `folder` varchar(255) DEFAULT NULL,
  `filesize` int(11) NOT NULL,
  `width` int(11) NOT NULL,
  `height` int(11) NOT NULL,
  `thumb_width` int(11) DEFAULT NULL,
  `thumb_height` int(11) DEFAULT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8; 
Posted by Finebe
,



CentOS 5.2 APM 구축 매뉴얼

 

 

1. APM설치 전 확인사항

APM을 설치 하기 위해서는 gcc와 gcc-c++ 컴파일러가 설치되어 있어야 한다. 추가적으로 설치해도 상관없지만
리눅스를 설치할때 추가적으로 이 라이브러리들을 선택하여 설치하면 수월하게 설치할 수 있다.

 

또한 phpmyadmin을 사용하기 위해서는 libmcrypt가 필요하며 yum으로 설치를 해봤으니 정상적으로 작동을 하지 않는것

같다. libmcrypt를 tar.gz파일을 다운받아 ./configure && make && make install 을 이용하여 설치하자

 

1.1 APM이 설치 되어 있는 확인

[root@kimsr /]# rpm -qa httpd php mysql
- 아무것도 출력되지 않을 경우 설치되지 않은것이며 패키지가 출력될 경우 아래 명령어로 제거하도록 합니다.


1.2 기존에 설치 되어 있는 Apache(httpd), php, mysql를 제거

[root@kimsr /]# yum remove -y httpd php mysql


1.3 라이브러리 및 컴파일 확인

[root@kimsr amp]# rpm -qa gcc* cpp* compat-gcc* flex*
[root@kimsr amp]# rpm -qa libjpeg* libpng* freetype* gd-*


1.4 라이브러리 및 컴파일 설치

[root@kimsr amp]# yum -y install gcc cpp gcc-c++ compat-gcc32-g77 flex
[root@kimsr amp]# yum -y install libjpeg-devel libpng-devel freetype-devel gd-devel


1.5 APM설치 파일 다운 로드

[root@kimsr /]# mkdir /amp
[root@kimsr /]# cd /amp
[root@kimsr amp]# wget http://apache.mirror.cdnetworks.com/httpd/httpd-2.2.10.tar.gz
[root@kimsr amp]# wget http://kr2.php.net/get/php-5.2.8.tar.gz/from/this/mirror
[root@kimsr amp]# wget http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.30.tar.gz/from/http://mysql.holywar.net/

 

2. MySQL 설치

[root@kimsr amp]# tar -zxvf mysql-5.1.30.tar.gz
[root@kimsr amp]# useradd -M -s /bin/false mysql
[root@kimsr mysql-5.1.30]# ./configure --prefix=/usr/local/server/mysql --with-charset=utf8 --with-extra-charsets=all
[root@kimsr mysql-5.1.30]# make && install

 

* configure시 아래와 같이 오류가 발생될 경우
checking for termcap functions library... configure: error: No curses/termcap library found

[root@kimsr apm]# yum -y install ncurses-devel


3. Apache 설치
[root@kimsr apm]# tar -zxf httpd-2.2.10.tar.gz
[root@kimsr httpd-2.2.10]# ./configure --prefix=/usr/local/server/apache --enable-mods-shared=alkl --enable-so --enable-rewrite
[root@kimsr httpd-2.2.10]# make && make install


4. PHP 설치
[root@kimsr apm]# tar -zxf php-5.2.7.tar.gz
[root@kimsr apm]# cd php-5.2.7
[root@kimsr php-5.2.7]# ./configure \
--prefix=/usr/local/server/php --with-apxs2=/usr/local/server/apache/bin/apxs \
--with-mysql=/usr/local/server/mysql --with-config-file-path=/usr/local/server/apache/conf \
--disable-debug --enable-safe-mode --enable-track-vars --enable-sockets \
--with-mod_charset --with-charset=utf8 --with-xml --with-language=korean \
--enable-mailparse --enable-calender --enable-sysvsem=yes --enable-sysvshm=yes \
--enable-ftp --enable-magic-quotes --enable-gd-native-ttf --enable-url-includes \
--enable-trans-id --enable-inline-optimization --enable-bcmath \
--with-jpeg --with-png --with-zlib --with-jpeg-dir=/usr --with-png-dir=/usr/lib \

--with-freetype-dir=/usr --with-libxml-dir=/usr --enable-exif --with-gd --with-ttf \

--with-gettext --enable-sigchild --enable-mbstring --with-mcrypt

컴파일 시 error: mcrypt.h not found 오류가 나면

libmcrypt가 정상적으로 설치되지 않은 것이다. libmcrypt.tar.gz 파일을 다운 받아 ./configure && make && make install로 설치

 

컴파일 시 configure: error: xml2-config not found. Please check your libxml2 installation. 오류가 나오면

yum install *-devel 이것도 안되면 아래와 같이 수행

 

libxml2 설치 - XML C 파서(Parser)
다운로드 :
ftp://xmlsoft.org/libxml2/
[root@localhost apm]# tar xvfz libxml2-2.6.16.tar.gz
[root@localhost apm]# cd libxml2-2.6.16
[root@localhost libxml2-2.6.16]# ./configure && make && make install
[root@localhost libxml2-2.6.16]# cd ..

[root@kimsr php-5.2.7]# make && make install


4.1 PHP 환경설정 파일 복사
[root@kimsr php-5.2.7]# cp php.ini-dist /usr/local/server/apache/conf/php.ini


본인도 APM을 설치하기위해 무단한 노력을 한거 같다. 몇번의 실패와 역경을 딛고 설치에 성고하였다.
모두 오류없이 설치할 수 있기를 기원하며 설치방법을 만들어 보았다.

 

이 내용은 어디까지나 설치까지만의 내용을 정리한 것이면 설치 완료 후 세팅해야 하는 사항들이 있다

mysql 기본 DB을 설정하거나 Apache httpd.conf 파일등을 수정해야 한다. 이 부분에 대해서는 추후에 올리는 내용에서

설명하도록 하겠다.

Posted by Finebe
,



처음 시도 php 함수 mb_detect_encoding으로 검사

파라미터에 대해서 인코딩방식이 어떤 것인지 판별하여 Return해준다.

string mb_detect_encoding ( string $str [, mixed $encoding_list= mb_detect_order() [, bool $strict= false ]] )

예제


사용은 대충 이런식으로 하게 된다.

/* Detect character encoding with current detect_order */
echo mb_detect_encoding($str);

/* "auto" is expanded to "ASCII,JIS,UTF-8,EUC-JP,SJIS" */
echo mb_detect_encoding($str, "auto");

/* Specify encoding_list character encoding by comma separated list */
echo mb_detect_encoding($str, "JIS, eucjp-win, sjis-win");

/* Use array to specify encoding_list  */
$ary[] = "ASCII";
$ary[] = "JIS";
$ary[] = "EUC-JP";
echo mb_detect_encoding($str, $ary);

하지만 한글에 대해선 완벽하게 지원해주지 않는 걸 확인했다. URL의 파라미터에 직접 한글을 입력하여 한 결과 처음 자음이 ㅈ~ㅎ으로 시작하면 UTF-8로 인식한다.

따라 함수를 따로 만들거나 해야 함.



1. detect_encoding함수
Another light way to detect character encoding:

function detect_encoding($string) {  
  static $list = array('utf-8', 'windows-1251');
  
  foreach ($list as $item) {
    $sample = iconv($item, $item, $string);
    if (md5($sample) == md5($string))
      return $item;
  }
  return null;
}

2. Function to detect UTF-8, when mb_detect_encoding is not available it may be useful.
Function to detect UTF-8, when mb_detect_encoding is not available it may be useful.

function is_utf8($str) {
    $c=0; $b=0;
    $bits=0;
    $len=strlen($str);
    for($i=0; $i<$len; $i++){
        $c=ord($str[$i]);
        if($c > 128){
            if(($c >= 254)) return false;
            elseif($c >= 252) $bits=6;
            elseif($c >= 248) $bits=5;
            elseif($c >= 240) $bits=4;
            elseif($c >= 224) $bits=3;
            elseif($c >= 192) $bits=2;
            else return false;
            if(($i+$bits) > $len) return false;
            while($bits > 1){
                $i++;
                $b=ord($str[$i]);
                if($b < 128 || $b > 191) return false;
                $bits--;
            }
        }
    }
    return true;
}

3. conver to Utf8 if $str is not equals to 'UTF-8'

/* 
*QQ: 290359552 
* conver to Utf8 if $str is not equals to 'UTF-8' 
*/ 
function convToUtf8($str){ 
     if( mb_detect_encoding($str,"UTF-8, ISO-8859-1, GBK")!="UTF-8" ){ 
         return  iconv("gbk","utf-8",$str); 

     }else{ 
         return $str; 
     }
} 

4. from PHPDIG

function isUTF8($str) {
        if ($str === mb_convert_encoding(mb_convert_encoding($str, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")) {
            return true;
        } else {
            return false;
        }
    } 

5. Much simpler UTF-8-ness checker using a regular expression created by the W3C:

// Returns true if $string is valid UTF-8 and false otherwise.
function is_utf8($string) {
    
    // From http://w3.org/International/questions/qa-forms-utf-8.html
    return preg_match('%^(?:
          [\x09\x0A\x0D\x20-\x7E]            # ASCII
        | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
        |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
        | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
        |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
        |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
        | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
        |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
    )*$%xs', $string);
    
} // function is_utf8



6. Sometimes mb_detect_string is not what you need. When using pdflib for example you want to VERIFY the correctness of utf-8. mb_detect_encoding reports some iso-8859-1 encoded text as utf-8. To verify utf 8 use the following:

//
//    utf8 encoding validation developed based on Wikipedia entry at:
//    http://en.wikipedia.org/wiki/UTF-8
//
//    Implemented as a recursive descent parser based on a simple state machine
//    copyright 2005 Maarten Meijer
//
//    This cries out for a C-implementation to be included in PHP core
//
    function valid_1byte($char) {
        if(!is_int($char)) return false;
        return ($char & 0x80) == 0x00;
    }
    
    function valid_2byte($char) {
        if(!is_int($char)) return false;
        return ($char & 0xE0) == 0xC0;
    }

    function valid_3byte($char) {
        if(!is_int($char)) return false;
        return ($char & 0xF0) == 0xE0;
    }

    function valid_4byte($char) {
        if(!is_int($char)) return false;
        return ($char & 0xF8) == 0xF0;
    }
    
    function valid_nextbyte($char) {
        if(!is_int($char)) return false;
        return ($char & 0xC0) == 0x80;
    }
    
    function valid_utf8($string) {
        $len = strlen($string);
        $i = 0;    
        while( $i < $len ) {
            $char = ord(substr($string, $i++, 1));
            if(valid_1byte($char)) {    // continue
                continue;
            } else if(valid_2byte($char)) { // check 1 byte
                if(!valid_nextbyte(ord(substr($string, $i++, 1))))
                    return false;
            } else if(valid_3byte($char)) { // check 2 bytes
                if(!valid_nextbyte(ord(substr($string, $i++, 1))))
                    return false;
                if(!valid_nextbyte(ord(substr($string, $i++, 1))))
                    return false;
            } else if(valid_4byte($char)) { // check 3 bytes
                if(!valid_nextbyte(ord(substr($string, $i++, 1))))
                    return false;
                if(!valid_nextbyte(ord(substr($string, $i++, 1))))
                    return false;
                if(!valid_nextbyte(ord(substr($string, $i++, 1))))
                    return false;
            } // goto next char
        }
        return true; // done
    }

for a drawing of the statemachine see: http://www.xs4all.nl/~mjmeijer/unicode.png and http://www.xs4all.nl/~mjmeijer/unicode2.png 


Posted by Finebe
,


Posted by Finebe
,