Codage de caractères PDO DBLIB multi-octets (chinois) – Serveur SQL

Sur une machine Linux, j'utilise PDO DBLIB pour me connecter à une database MSSQL et insert des données dans une table SQL_Latin1_General_CP1_CI_AS . Le problème est que lorsque j'essaie d'insert des caractères chinois (multioctets), ils sont insérés comme 哈市香åŠåŒºç æ±Ÿè·¯å· .

Mon (partie de) code est le suivant:

 $DBH = new PDO("dblib:host=$myServer;dbname=$myDB;", $myUser, $myPass); $query = " INSERT INTO UserSignUpInfo (FirstName) VALUES (:firstname)"; $STH = $DBH->prepare($query); $STH->bindParam(':firstname', $firstname); 

Ce que j'ai essayé jusqu'ici:

  1. Faire mb_convert_encoding à UTF-16LE sur $firstname et CAST comme VARBINARY dans la requête comme:

    $firstname = mb_convert_encoding($firstname, 'UTF-16LE', 'UTF-8');

     VALUES (CAST(:firstname AS VARBINARY)); 

    Ce qui entraîne l'insertion correcte des caractères, jusqu'à ce qu'il y ait des caractères non multi-octets, qui rompent l'exécution du PDO.

  2. Définir ma connection comme utf8:

     $DBH = new PDO("dblib:host=$myServer;dbname=$myDB;charset=UTF-8;", $myUser, $myPass); $DBH->exec('SET CHARACTER SET utf8'); $DBH->query("SET NAMES utf8"); 
  3. Définition du client charset de client charset sur UTF-8 dans mon file freetds.conf

    Qui n'a eu aucun impact.

Est-il possible d'insert des données multi-octets dans cette database SQL? Y at-il une autre solution de contournement? J'ai pensé essayer PDO ODBC ou même mssql, mais j'ai pensé qu'il vaut mieux requestr ici avant de perdre plus de time.

Merci d'avance.

MODIFIER:

J'ai fini par utiliser MSSQL et le préfixe de type de données N Je vais échanger et essayer PDO_ODBC quand j'ai plus de time. Merci à tous pour les réponses!

Est-il possible d'insert des données multi-octets dans cette database SQL? Y at-il une autre solution de contournement?

  1. Si vous pouvez basculer vers PDO_ODBC, Microsoft fournit des pilotes ODBC SQL Server gratuits pour Linux (uniquement pour Red Hat Enterprise Linux 64 bits et SUSE Linux Enterprise 64 bits) prenant en charge Unicode.

  2. Si vous pouvez changer en PDO_ODBC, alors le préfixe N pour l'insertion d'Unicode va fonctionner.

  3. Si vous pouvez changer la table affectée de SQL_Latin1_General_CP1_CI_AS à UTF-8 (qui est la valeur par défaut pour MSSQL), alors ce serait idéal.

Votre cas est plus restreint. Cette solution est adaptée au cas où vous avez mélangé des caractères multi-octets et non-multi-octets dans votre string d'input, et vous devez les save dans une table latine, et le préfixe de type N ne fonctionne pas, et vous ne voulez pas pour s'éloigner de PDL DBLIB (car Unicode PDO_ODBC de Microsoft est à peine supporté sous linux). Voici une solution de contournement.

Coder conditionnellement la string d'input en tant que base64 . Après tout, c'est ainsi que nous pouvons transporter en toute security des images en ligne avec des courriels.

Exemple de travail:

 $DBH = new PDO("dblib:host=$myServer;dbname=$myDB;", $myUser, $myPass); $query = " INSERT INTO [StackOverflow].[dbo].[UserSignUpInfo] ([FirstName]) VALUES (:firstname)"; $STH = $DBH->prepare($query); $firstname = "输入中国文字!Okay!"; /* First, check if this ssortingng has any Unicode at all */ if (strlen($firstname) != strlen(utf8_decode($firstname))) { /* If so, change the ssortingng to base64. */ $firstname = base64_encode($firstname); } $STH->bindParam(':firstname', $firstname); $STH->execute(); 

Ensuite, pour revenir en arrière, vous pouvez tester les strings base64 et les décoder uniquement sans endommager vos inputs existantes, comme ceci:

 while ($row = $STH->fetch()) { $entry = $row[0]; if (base64_encode(base64_decode($entry , true)) === $entry) { /* Decoding and re-encoding a true base64 ssortingng results in the original entry */ print_r(base64_decode($entry) . PHP_EOL); } else { /* Previous ensortinges not encoded will fall through gracefully */ print_r($entry . PHP_EOL); } } 

Les inputs seront enregistrées comme ceci:

 Guan Tianlang 5pys6Kqe44KS5a2maGVsbG8= 

Mais vous pouvez facilement les convertir en:

 Guan Tianlang输入中国文字!Okay! 

La collation ne devrait pas avoir d'importance ici.

Les caractères nchar deux octets doivent être stockés dans les champs nvarchar , nchar ou ntext . Vous n'avez pas besoin d'effectuer de casting.

Le préfixe de type de données n signifie National et SQL Server enregistre le text en tant qu'Unicode (UTF-16).

Modifier:

PDO_DBLIB ne prend pas en charge Unicode et est désormais obsolète.

Si vous pouvez basculer vers PDO_ODBC, Microsoft fournit des pilotes ODBC SQL Server gratuits pour Linux qui prennent en charge Unicode.

Microsoft – Documentation du pilote ODBC SQL Server

Blog – Installation et utilisation du pilote ODBC Microsoft SQL Server pour Linux

Vous pouvez utiliser le type de données compatible Unicode pour la colonne de table pour la prise en charge des langues étrangères (les exceptions sont indiquées dans EDIT 2).

(char, varchar, text) Versus (nchar, nvarchar, ntext)

Non-Unicode:

Meilleur pour l'anglais américain: "Un problème avec les types de données qui utilisent 1 octet pour encoder chaque caractère est que le type de données ne peut représenter que 256 caractères différents, ce qui force plusieurs spécifications d'enencoding (ou pages de code) pour différents alphabets européens, Il est également impossible de manipuler des systèmes tels que les kanji japonais ou les alphabets coréens Hangul qui ont des milliers de caractères

Unicode

La spécification Unicode définit un schéma de encoding unique pour la plupart des caractères largement utilisés dans les entresockets du monde entier.Tous les ordinateurs traduisent systématiquement les templates de bits dans datatables Unicode en caractères en utilisant le seul Unicode Cela garantit que le même model de bits est toujours converti en un même caractère sur tous les ordinateurs.Les données peuvent être transférées librement d'une database ou d'un ordinateur à un autre sans craindre que le système de réception ne traduise correctement les configurations de bits.

Exemple :

Aussi j'ai essayé un exemple, vous pouvez voir ses écrans ci-dessous, il serait utile pour les questions relatives aux insertions de langue étrangère comme la question est en ce moment.La colonne comme on le voit ci-dessous dans nvarchar et il supporte la langue chinoise

entrez la description de l'image ici

EDIT 1:

Une autre question connexe est discutée ici

EDIT 2:

Les scripts Unicode non pris en charge sont affichés ici

il suffit d'utiliser nvarchar, ntext, nChar et quand vous voulez insert puis utiliser

 INSERT INTO UserSignUpInfo (FirstName) VALUES (N'firstname'); 

N se référera au charactor Unicode et il est standard dans le monde entier.

Ref:

https://aalamrangi.wordpress.com/2012/05/13/storing-and-resortingeving-non-english-unicode-characters-hindi-czech-arabic-etc-in-sql-server/

https://technet.microsoft.com/en-us/library/ms191200(v=sql.105).aspx

https://irfansworld.wordpress.com/2011/01/25/what-is-unicode-and-non-unicode-data-formats/

Ce lien Explique le caractère chinois dans MYSQL. Impossible d'insert un caractère chinois dans MySQL . Vous devez créer une table nom_table () CHARACTER SET = utf8; Use UTF-8 lorsque vous insérez dans la table

 set username utf8; INSERT INTO table_name (ABC,VAL); 

abd create Base de données dans CHARACTER SET utf8 COLLATE utf8_general_ci;

alors vous pouvez insert dans le caractère chinois dans la table