Mysql
 sql >> Base de données >  >> RDS >> Mysql

Enregistrement de fichiers en tant que blob dans la base de données ajax php pdo

Selon PHP/PDO/MySQL :l'insertion dans MEDIUMBLOB stocke les données erronées , essayez d'utiliser la ligne suivante pour construire votre objet PDO :

$dbh = new PDO($dsn, $username, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1 COLLATE latin1_general_ci"));

Explication

Je pense qu'il y a, comme le note Ben M dans la question liée, deux mauvaises décisions de conception à l'œuvre ici.

Il y a ce concept de jeu de caractères de connexion. L'idée est que le texte SQL peut être dans n'importe quel jeu de caractères et est ensuite converti lors de la récupération par le serveur SQL.

Cela ne fonctionne pas très bien avec les données binaires car ce n'est pas du texte et, par conséquent, ne doit pas, par définition, être dans un jeu de caractères, mais est toujours transféré à l'aide de littéraux de chaîne .

Ce problème peut être contourné en citant les données BLOB lors du transfert (soit en utilisant les fonctions BASE64_* soit en échappement hexadécimal ) et, en effet, c'est ce que font beaucoup de gens.

La deuxième décision de conception concerne PDO/PHP :PDO ne fait aucune conversion de jeu de caractères (il ne le peut pas, car les chaînes en PHP sont intrinsèquement indépendantes du jeu de caractères), donc PHP est le seul (ou l'un des rares langages) où le choix de le jeu de caractères de transfert SQL est en fait important car il doit correspondre à l'encodage dans lequel se trouvent réellement les chaînes d'entrée.

Dans d'autres langues, le jeu de caractères de transfert doit simplement être suffisamment expressif pour englober tous les caractères pouvant être utilisés dans les chaînes. Dans le monde actuel des emojis, cela n'est probablement garanti que par les jeux de caractères Unicode (utf-8 et autres). Cependant, aucun de ceux-ci n'est binaire sûr (en ce sens que toutes les combinaisons possibles d'octets ne produisent pas une chaîne valide) donc même si nous pouvions contourner le problème PHP, il nous resterait toujours le problème n°1.

Dans un monde idéal, les commandes SQL seraient toujours dans le jeu de caractères ASCII pendant le transfert et chaque valeur de chaîne aurait un argument de jeu de caractères, dont "binaire" pourrait être une valeur possible, fournie avec. MySQL a en fait une telle construction pour les chaînes, qu'il appelle un "introducteur". "_binary", cependant, ne semble pas être une valeur valide.

Ces informations de jeu de caractères seraient ensuite utilisées par l'autre extrémité pour convertir la valeur de chaîne dans son jeu de caractères natif (soit la colonne pour les transferts client-serveur, soit le jeu de caractères de chaîne du langage de programmation pour les transferts serveur-client).

De cette façon, la seule chose qui devrait être échappée dans les valeurs BLOB serait le délimiteur de chaîne (" ou ' ).