sql >> Base de Datos >  >> RDS >> Mysql

Guardar archivos como blob en la base de datos ajax php pdo

Según PHP/PDO/MySQL :insertar en MEDIUMBLOB almacena datos incorrectos , intente usar la siguiente línea para construir su objeto PDO:

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

Explicación

Creo que hay, como señala Ben M en la pregunta vinculada, dos malas decisiones de diseño en el trabajo aquí.

Existe este concepto de juego de caracteres de conexión. La idea es que el texto SQL pueda estar en cualquier conjunto de caracteres y luego se convierta al recuperarlo el servidor SQL.

Esto no funciona tan bien con datos binarios, ya que no es texto y, por lo tanto, no debe, por definición, estar en ningún juego de caracteres, pero aún se transfiere usando literales de cadena .

Este problema se puede solucionar citando datos BLOB durante la transferencia (ya sea usando las funciones BASE64_* o mediante hexadecimal-escape ) y, de hecho, eso es lo que mucha gente está haciendo.

La segunda decisión de diseño es en PDO/PHP:PDO no realiza ninguna conversión de juego de caracteres (no puede, porque las cadenas en PHP son inherentemente independientes del juego de caracteres), por lo que PHP es el único (o uno de los pocos idiomas) donde la elección de el juego de caracteres de transferencia SQL es realmente importante porque debe coincidir con la codificación en la que se encuentran realmente las cadenas de entrada.

En otros idiomas, el conjunto de caracteres de transferencia solo necesita ser lo suficientemente expresivo para abarcar cualquier carácter que pueda usarse en cadenas. En el mundo actual de los emojis, lo más probable es que esto solo esté garantizado por conjuntos de caracteres Unicode (utf-8 y similares). Sin embargo, ninguno de estos son binarios seguros (en el sentido de que no todas las combinaciones posibles de bytes producen una cadena válida), por lo que incluso si pudiéramos solucionar el problema de PHP, aún nos quedaría el problema n.º 1.

En un mundo ideal, los comandos SQL siempre estarían en el conjunto de caracteres ASCII durante la transferencia y cada valor de cadena tendría un argumento de conjunto de caracteres, del cual "binario" podría ser un valor posible, proporcionado con él. MySQL en realidad tiene una construcción de este tipo para cadenas, a la que llama "introductor". “_binary”, sin embargo, no parece ser un valor válido.

Esta información del juego de caracteres sería utilizada por el otro extremo para convertir el valor de la cadena en su juego de caracteres nativo (ya sea la columna para transferencias de cliente a servidor o el juego de caracteres de cadena del lenguaje de programación para transferencias de servidor a cliente).

De esa manera, lo único que tendría que escaparse en los valores BLOB sería el delimitador de cadena (" o ' ).