web-dev-qa-db-fra.com

PHP + SQL Server - Comment définir un jeu de caractères pour la connexion?

J'essaie de stocker des données dans une base de données SQL Server via php.

Le problème est que les caractères spéciaux ne sont pas convertis correctement. Le jeu de caractères de mon application est iso-8859-1 Et celui utilisé par le serveur est windows-1252.

Convertir les données manuellement avant l’insertion n’aide en rien, il semble y avoir une conversion En cours.

L'exécution de la requête SQL 'set char_convert off' n'aide pas non plus.

Quelqu'un sait-il comment je peux le faire fonctionner?

EDIT: J'ai essayé ini_set ('mssql.charset', 'windows-1252'); aussi, mais aucun résultat avec celui-là non plus.

23
Maurice

Le jeu de caractères client est nécessaire mais non suffisant:

ini_set('mssql.charset', 'UTF-8');

J'ai cherché pendant deux jours comment insérer des données UTF-8 (issues de formulaires Web) dans MSSQL 2008 via PHP. Je lis partout où vous ne pouvez pas, vous devez d'abord convertir à UCS2 (comme le recommande la solution de cypher) . Sous Windows, SQLSRV est une bonne solution que je ne pouvais pas essayer car je développe sous Mac OSX. .

Cependant, le manuel FreeTDS (ce que PHP mssql utilise sous OSX) ajoute l’ajout de la lettre "N" avant le début de la citation:

mssql_query("INSERT INTO table (nvarcharField) VALUES (N'űáúőűá球最大的采购批发平台')", +xon);

Selon cette discussion, le caractère N indique au serveur de convertir en Unicode . https://softwareengineering.stackexchange.com/questions/155859/why-do-we-neo-to-put-n-before- strings-in-Microsoft-sql-server

22
Mano Kovacs

J'ai eu le même problème et ini_set('mssql.charset', 'utf-8') n'a pas fonctionné pour moi ..__ Cependant, cela a fonctionné en majuscule:

ini_set('mssql.charset', 'UTF-8');
5
Jaime Neto

Je suggère de regarder les points suivants:

  1. Vérifiez que les colonnes dans lesquelles vous stockez les informations sont nchar ou nvarchar, car char et nvarchar ne prennent pas en charge UCS-2 (SQLServer ne stocke pas au format UTF-8 btw)
  2. Si vous vous connectez avec mssql library/extension pour PHP, exécutez: ini_set('mssql.charset', 'utf-8'); car il n’existe aucune fonction avec un argument charset (connect, query etc)
  3. Assurez-vous que le jeu de caractères de votre navigateur est également défini sur UTF-8
5
Matt Setter

Si vous utilisez le protocole TDS version 7 ou supérieure, TOUTES les communications filaires sont converties en UCS2. Le serveur convertira d'UCS2 en quelque que soit le classement de la table ou de la colonne, sauf si la colonne est nvarchar ou ntext. Vous pouvez stocker UTF-8 en varchar ou en texte normal, vous devez simplement utiliser une version du protocole TDS inférieure à 7, comme 6.0 ou 4.2. Le seul inconvénient de cette méthode est que vous ne pouvez pas interroger les tables nvarchar, ntext ou sys. * (Je pense que vous ne pouvez pas non plus faire de CAST () ing), car le serveur refuse d’envoyer des éléments pouvant éventuellement être convertis UTF-8 à tout client utilisant une version de protocole inférieure à 7.

Il n'est pas possible d'éviter de convertir les jeux de caractères lors de l'utilisation du protocole TDS version 7 ou supérieure (à peu près équivalente à MSSQL 2005 ou une version plus récente).

4
chugadie

Si ini_set('mssql.charset', 'UTF-8'); ne vous aide pas ET si vous ne disposez pas d'un accès root pour modifier le fichier freetds.conf à l'échelle du système, procédez comme suit:

1. Configurer le fichier /your/local/freetds.conf:

[sqlservername]
    Host=192.168.0.56
    port=1433
    tds version=7.0
    client charset=UTF-8

2. Assurez-vous que votre connexion DSN utilise le nom de serveur, pas l'adresse IP:

'dsn' => 'dblib:Host=sqlservername;dbname=yourdb

3. Demandez à FreeTDS d'utiliser votre fichier freetds.conf local en tant qu'utilisateur non privilégié à partir d'un script php via des variables env:

putenv('FREETDSCONF=/your/local/freetds.conf');
4
Attila Fulop

Pour moi, éditer ce fichier:
/etc/freetds/freetds.conf
... et changer/régler le paramètre 'tds version' sur '7.0' a aidé. Editez votre freetds.conf et essayez de changer ce paramètre pour votre configuration de serveur (ou globale).

Cela fonctionnera même sans redémarrage d’Apache.

2
bohdanbobrowski

J'ai eu de la chance dans une situation similaire (utilisation d'une connexion ODB PDO) en utilisant le code suivant pour convertir le codage avant l'impression:

$data = mb_convert_encoding($data, 'ISO-8859-1', 'windows-1252');

Je devais définir manuellement le codage source, car il était erronément signalé comme "ISO-8859-1" par mb_detect_encoding().

Mes données étaient également stockées dans la base de données par une autre application. Je suis donc peut-être dans une situation unique, même si j'espère que cela aidera!

2
Jacob Hume

Ne pouvez-vous pas simplement convertir vos tables au codage de votre application? Ou utilisez utf-8 dans les deux?

Je ne sais pas si MSSQL supporte les encodages au niveau des tables, cependant.

Aussi, essayez les fonctions de chaîne MB (multi-octets), si cela échoue.

0
Sandro Gržičić

Je n'ai pas remarqué que quelqu'un mentionne un autre moyen de convertir les résultats de la base de données MSSQL. Le bon vieux iconv() function:

iconv (string $in_charset, string $out_charset, string $str): string;

Dans mon cas, tout le reste n’a pas permis une conversion significative, à l’exception de celle lors de l’obtention des résultats. Bien entendu, cela se fait dans la boucle d'analyse des résultats de la requête - de CP1251 à UTF-8:

foreach ($records as $row=>$col) {
    $array[$row]['StatusName'] = iconv ('CP1251', 'UTF-8' , $records[$row]['StatusName']);
}

Moche, mais ça marche.

0
bodi0

Vous devez définir le jeu de caractères avec ini_set ('mssql.charset', 'windows-1252') avant la connexion. Si vous l'utilisez après le mssql_connect ça n'a aucun effet.

0
achos

Le simple fait d'ajouter ini_set('mssql.charset', 'UTF-8'); ne m'a pas aidé dans mon cas. Je devais spécifier le jeu de caractères UTF-8 sur la colonne:

$age = 30;  
$name = utf8_encode("Joe");    

$select = sqlsrv_query($conn, "SELECT * FROM Users WHERE Age = ? AND Name = ?",
    array(array($age), array($name, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('UTF-8')));
0
Maja S.

Dans mon cas, cela a fonctionné après que j'ai ajouté les paramètres "CharacterSet" dans l'option de connexion sqlsrv_connect().

$connectionInfo = array( 
        "Database"=>$DBNAME,
        "ConnectionPooling"=>0,
        "CharacterSet"=>"UTF-8"
);
$LAST_CONNECTION = sqlsrv_connect($DBSERVER, $connectionInfo);

Voir la documentation ici: https://docs.Microsoft.com/en-us/sql/connect/php/connection-options?view=sql-server-2017

0
Donovan P