Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Speichern von Dateien als Blob in der Datenbank Ajax PHP PDO

Gemäß PHP/PDO/MySQL :Einfügen in MEDIUMBLOB speichert fehlerhafte Daten , versuchen Sie, die folgende Zeile zu verwenden, um Ihr PDO-Objekt zu erstellen:

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

Erklärung

Ich denke, wie Ben M in der verknüpften Frage feststellt, sind hier zwei schlechte Designentscheidungen am Werk.

Es gibt dieses Konzept eines Verbindungszeichensatzes. Die Idee ist, dass der SQL-Text in einem beliebigen Zeichensatz vorliegen kann und dann beim Abrufen durch den SQL-Server konvertiert wird.

Bei binären Daten funktioniert das nicht so gut, da es kein Text ist und somit per Definition in keinem Zeichensatz vorliegen darf, aber trotzdem mit String-Literalen übertragen wird .

Dieses Problem kann umgangen werden, indem BLOB-Daten während der Übertragung zitiert werden (entweder mit den BASE64_*-Funktionen oder mit Hex-Escape ) und tatsächlich tun das viele Leute.

Die zweite Entwurfsentscheidung liegt in PDO/PHP:PDO führt keine Zeichensatzkonvertierung durch (kann es nicht, da Strings in PHP von Natur aus zeichensatzunabhängig sind), sodass PHP die einzige (oder eine der wenigen Sprachen) ist, bei der die Wahl zwischen Der SQL-Übertragungszeichensatz ist eigentlich wichtig, da er mit der Codierung übereinstimmen muss, in der sich die Eingabezeichenfolgen tatsächlich befinden.

In anderen Sprachen muss der Übertragungszeichensatz nur ausdrucksstark genug sein, um alle Zeichen zu umfassen, die möglicherweise in Zeichenfolgen verwendet werden. In der heutigen Welt der Emojis wird dies höchstwahrscheinlich nur durch Unicode-Zeichensätze (utf-8 und dergleichen) gewährleistet. Allerdings ist keine davon binärsicher (da nicht jede mögliche Kombination von Bytes eine gültige Zeichenfolge ergibt). Selbst wenn wir das PHP-Problem umgehen könnten, blieben wir immer noch bei Problem Nr. 1.

In einer idealen Welt würden SQL-Befehle während der Übertragung immer im ASCII-Zeichensatz sein und jeder String-Wert würde ein Zeichensatz-Argument, von dem „binär“ ein möglicher Wert sein könnte, mit sich führen. MySQL hat tatsächlich ein solches Konstrukt für Strings, das es „Introducer“ nennt. „_binary“ scheint jedoch kein gültiger Wert zu sein.

Diese Zeichensatzinformationen würden dann vom anderen Ende verwendet, um den Zeichenfolgenwert in seinen nativen Zeichensatz umzuwandeln (entweder den der Spalte für Client-zu-Server-Übertragungen oder den Zeichenfolgenzeichensatz der Programmiersprache für Server-zu-Client-Übertragungen).

Auf diese Weise wäre das einzige, was in BLOB-Werten maskiert werden müsste, das Zeichenfolgentrennzeichen (" oder ' ).