Τρόπος επίλυσης προβλημάτων character encoding με MySQL&PHP

Μια περιοχή όπου τα μέλη μας μπορούν να βάζουν τα PHP scripts που έχουν φτιάξει και θέλουν να τα μοιραστούν με τα υπόλοιπα μέλη.

Συντονιστές: Super-Moderators, WebDev Moderators, PHP Moderators

Απάντηση
panosru
WebDev Moderator
Δημοσιεύσεις: 1885
Εγγραφή: 13 Σεπ 2005 16:13
Τοποθεσία: Camp

Τρόπος επίλυσης προβλημάτων character encoding με MySQL&PHP

Δημοσίευση από panosru » 03 Μάιος 2006 12:26

με την αναβάθμιση του MySQL server σε 4.1 αντιμετωπίσαμε όλοι προβλήματα του τύπου να βλέπουμε περίεργους χαρακτήρες στα web site μας τα οποια σχετίζονται με κάποια βάση δεδομένων. Τελικά αργά η γρήγορα όλοι βρήκαμε κάποια λύση, άλλοι επίπονα άλλοι ανώδυνα. παρακάτω θα παρουσιάσω μια class που δημιούργησα για να γίνετε το connection με τις βάσεις δεδομένων μας.

Οι παράμετροι που δέχεται η παρακάνω class είναι το host (η φιλοξενία μας - συνήθως "localhost"-, το username (το όνομα χρηστη μας), το password (το "συνθηματικό" μας), το database name (το όνομα της βάσης δεδομένων μας), και το character encoding (το όνομα της κωδικοποίησης τον χαρακτήρων όπου θέλετε να χρησιμοποιήσετε)

Το όνομα της κωδικοποίησης που χρησιμοποιείτε θα το βρείτε ανάμεσα από τα παρακάτω, στην στήλη Charset (πχ για ελληνικά "greek" για utf-8 "utf8")

Κώδικας: Επιλογή όλων

+----------+-----------------------------+---------------------+
| Charset  | Description                 | Default collation   |
+----------+-----------------------------+---------------------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |
| dec8     | DEC West European           | dec8_swedish_ci     |
| cp850    | DOS West European           | cp850_general_ci    |
| hp8      | HP West European            | hp8_english_ci      |
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |
| latin1   | cp1252 West European        | latin1_swedish_ci   |
| latin2   | ISO 8859-2 Central European | latin2_general_ci   |
| swe7     | 7bit Swedish                | swe7_swedish_ci     |
| ascii    | US ASCII                    | ascii_general_ci    |
| ujis     | EUC-JP Japanese             | ujis_japanese_ci    |
| sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |
| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |
| tis620   | TIS620 Thai                 | tis620_thai_ci      |
| euckr    | EUC-KR Korean               | euckr_korean_ci     |
| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |
| gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |
| greek    | ISO 8859-7 Greek            | greek_general_ci    |
| cp1250   | Windows Central European    | cp1250_general_ci   |
| gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |
| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |
| armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci |
| utf8     | UTF-8 Unicode               | utf8_general_ci     |
| ucs2     | UCS-2 Unicode               | ucs2_general_ci     |
| cp866    | DOS Russian                 | cp866_general_ci    |
| keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  |
| macce    | Mac Central European        | macce_general_ci    |
| macroman | Mac West European           | macroman_general_ci |
| cp852    | DOS Central European        | cp852_general_ci    |
| latin7   | ISO 8859-13 Baltic          | latin7_general_ci   |
| cp1251   | Windows Cyrillic            | cp1251_general_ci   |
| cp1256   | Windows Arabic              | cp1256_general_ci   |
| cp1257   | Windows Baltic              | cp1257_general_ci   |
| binary   | Binary pseudo charset       | binary              |
| geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  |
| cp932    | SJIS for Windows Japanese   | cp932_japanese_ci   |
| eucjpms  | UJIS for Windows Japanese   | eucjpms_japanese_ci |
+----------+-----------------------------+---------------------+
referrer: MySQL.com

Παρακάτω είναι η class για την οποια αναφερόμουν παραπάνω. Η class αυτή λειτουργεί σε όλες τις εκδόσεις της php.

Κώδικας: Επιλογή όλων

<?php
/**
 * @name &#58; MySQLConnect
 * @author &#58; panosru
 * @version &#58; PHP 4 + && < PHP 5 
 * @param &#58; host,user,pass,db,char
 */
class MySQLConnect 
&#123;
  var $host,$user,$pass,$db,$char,$error;
    	
  function MySQLConnect&#40;$host,$user,$pass,$db,$char&#41; 
  &#123;
  	$this->host 	= $host;
  	$this->user 	= $user;
  	$this->pass 	= $pass;
  	$this->db 		= $db;
  	$this->char 	= $char;
  	$this->error 	= array&#40;&#41;;  
  	
  	$this->Execution&#40;&#41;;		
  &#125;
  
  function ActualizeDatabaseConnection &#40;&#41; 
  &#123;
      if&#40;!@mysql_connect&#40;$this->host,$this->user,$this->pass&#41;&#41; &#123;
          array_push&#40;$this->error,"Error conecting to database -> ".mysql_error&#40;&#41;." Error number&#58; ".mysql_errno&#40;&#41;&#41;;
      &#125;
  &#125; 
    
  function SelectDatabase &#40;&#41; 
  &#123;
      if&#40;!@mysql_select_db&#40;$this->db&#41;&#41;
      &#123;
          array_push&#40;$this->error,"Error selecting the database &#123;$this->db&#125;"&#41;;
      &#125;
  &#125;
  
  function DefineDatabaseCharset&#40;&#41; 
  &#123;
      if&#40;!&#40;@mysql_query&#40;"SET CHARACTER SET '&#123;$this->char&#125;'"&#41;&#41; && &#40;@mysql_query&#40;"SET NAMES '&#123;$this->char&#125;'"&#41;&#41;&#41; 
      &#123;
          array_push&#40;$this->error,"Error while changing character set to &#123;$this->char&#125;"&#41;;
          
      &#125;
  &#125;
  
  function Validator &#40;&#41;
  &#123;  	  	
	if &#40;count&#40;$this->error&#41; > 0&#41;
	&#123;
		foreach &#40;$this->error as $key => $value&#41;
		&#123;
			echo "&#91;".&#40;$key+1&#41;."&#93; > &#123;$value&#125;<br />";
		&#125;
		die&#40;"<p><strong>Can not display web page</strong></p>"&#41;;
	&#125;  	
  &#125;
  
  function Execution &#40;&#41;
  &#123;
	// MAKE THE CONNECTION
	$this->ActualizeDatabaseConnection&#40;&#41;;
	$this->SelectDatabase&#40;&#41;;
	$this->DefineDatabaseCharset&#40;&#41;; 
	
	// MAKE VALIDATION
	$this->Validator&#40;&#41;;		 	
  &#125;
&#125;
?>
Μπορείτε να αποθηκεύσετε αυτόν τον κώδικα σε κάποιο αρχείο λόγου χάρη MySQLConnect.class.php (σημείωση: το .class δεν χρησιμεύει σε τίποτε παραπάνω απλά για να καταλαβαίνουμε ότι πρόκειται περί class χωρίς να χρειαστεί να μπούμε στον κώδικα του αρχείου) και στο αρχείο όπου θέλετε να δημιουργήσετε την σύνδεση σας με την βάση δεδομένων σας μπορείτε να γράψετε τον παρακάτω κώδικα:

Κώδικας: Επιλογή όλων

<?php
require_once&#40;"./required/MySQLConnect.class.php"&#41;;
$myDB = new MySQLConnect&#40;"host", "username", "password", "database_name", "character_set"&#41;;
?>
Παρακάτω θα δώσω μια άλλη class η οποια έχει το ίδιο αποτέλεσμα με την παραπάνω η μονη διαφορα είναι πως είναι ποιο ασφαλής, λειτουργεί καλύτερα από την προηγουμενη και υποστηρίζεται μονο από php5.0 και πάνω.

Κώδικας: Επιλογή όλων

<?php
/**
 * @name &#58; MySQLConnect
 * @author &#58; panosru
 * @version &#58; PHP5 + 
 * @param &#58; host,user,pass,db,char
 */
class MySQLConnect 
&#123;	
	protected static $host,$user,$pass,$db,$char;
	public static $error = array&#40;&#41;;
	
	const ActualizeDatabaseConnectionErroText1 = 'Error conecting to database -> ';
	const ActualizeDatabaseConnectionErroText2 = ', Error number&#58; ';
	const SelectDatabaseErroText1 = 'Error selecting the database ';
	const DefineDatabaseCharsetErroText1 = 'Error while changing character set to ';
	const ValidationDieMessage = '<p><strong>Can not display web page</strong></p>';
	
	public function __construct&#40;$host,$user,$pass,$db,$char&#41; 
	&#123;
		self&#58;&#58;$host = $host;
		self&#58;&#58;$user = $user;
		self&#58;&#58;$pass = $pass;
		self&#58;&#58;$db 	= $db;
		self&#58;&#58;$char = $char;								
		
		self&#58;&#58;Execution&#40;&#41;;
	&#125;
	
	private static function ActualizeDatabaseConnection &#40;&#41; 
	&#123;		
		if&#40;!@mysql_connect&#40;self&#58;&#58;$host,self&#58;&#58;$user,self&#58;&#58;$pass&#41;&#41; 
		&#123;
			array_push&#40;self&#58;&#58;$error,self&#58;&#58;ActualizeDatabaseConnectionErroText1.mysql_error&#40;&#41;.self&#58;&#58;ActualizeDatabaseConnectionErroText2.mysql_errno&#40;&#41;&#41;;
		&#125;
	&#125;   
	private static function SelectDatabase &#40;&#41; 
	&#123;		
		if&#40;!@mysql_select_db&#40;self&#58;&#58;$db&#41;&#41;
		&#123;
			array_push&#40;self&#58;&#58;$error,self&#58;&#58;SelectDatabaseErroText1.self&#58;&#58;$db&#41;;
		&#125;
	&#125;
	private static function DefineDatabaseCharset &#40;&#41; 
	&#123;		
		if&#40;!&#40;@mysql_query&#40;"SET CHARACTER SET '".self&#58;&#58;$char."'"&#41;&#41; && &#40;@mysql_query&#40;"SET NAMES '".self&#58;&#58;$char."'"&#41;&#41;&#41; 
		&#123;
			array_push&#40;self&#58;&#58;$error,self&#58;&#58;DefineDatabaseCharsetErroText1.self&#58;&#58;$char&#41;;		
		&#125;
	&#125; 
	
	private static function Execution &#40;&#41;
	&#123;
		// MAKE THE CONNECTION
		self&#58;&#58;ActualizeDatabaseConnection&#40;&#41;;
		self&#58;&#58;SelectDatabase&#40;&#41;;
		self&#58;&#58;DefineDatabaseCharset&#40;&#41;;	
		
		// MAKE VALIDATION
		self&#58;&#58;Validator&#40;&#41;;			
	&#125;
	
	private static function Validator &#40;&#41;
	&#123;
		if &#40;count&#40;self&#58;&#58;$error&#41; > 0&#41;
		&#123;
			foreach &#40;self&#58;&#58;$error as $key => $value&#41;
			&#123;
				echo "&#91;".&#40;$key+1&#41;."&#93; > &#123;$value&#125;<br />";
			&#125;
			die&#40;self&#58;&#58;ValidationDieMessage&#41;;
		&#125;
	&#125;
&#125;
?>
Τέλος να επισημάνω πως εκτος από τα παραπάνω πρέπει να ορίζουμε και εμείς από την πλευρά μας τα collation στα αλφαριθμητικά παιδία μας (πχ VARCHAR, TEXT κτλ) τα collation που μπορείτε να χρησιμοποιήσετε ανάλογα με την γλώσσα που θέλετε μπορείτε να τα βρείτε από τον παραπάνω πινακα που έδωσα στην στήλη Default collation

Απάντηση

Επιστροφή στο “PHP τα δικά μας scripts”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες