$fileCount = count($_FILES);
for ($i = 0; $i < $fileCount; $i++) {
$fp = fopen($_FILES[\"file_\".$i][\'tmp_name\'], \'rb\');
$stmt4 = $dbh - > prepare(\"IN
As per PHP/PDO/MySQL: inserting into MEDIUMBLOB stores bad data, try using the following line to construct your PDO object:
$dbh = new PDO($dsn, $username, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1 COLLATE latin1_general_ci"));
Explanation
I think there are, as Ben M notes in the linked question, two bad design decisions at work here.
There is this concept of a connection charset. The idea is that the SQL text can be in any charset and is then converted upon retrieval by the SQL server.
This does not work that well with binary data as it is not text and, thus, must not, by definition, be in any charset, but is still transferred using string literals.
This issue can be worked around by quoting BLOB data during transfer (either using the BASE64_* functions or by hex-escaping) and, indeed, that is what many people are doing.
The second design decision is in PDO/PHP: PDO does not do any charset conversion (it can’t, because strings in PHP are inherently charset-agnostic) so PHP is the only (or one of the few languages) where the choice of the SQL transfer charset is actually important because it needs to match the encoding the input strings are actually in.
In other languages, the transfer charset just needs to be expressive enough to encompass any characters that might be used in strings. In today’s world of emojis, this, most likely is only guaranteed by unicode charsets (utf-8 and the like). However, none of these are binary-safe (in that not every possible combination of bytes yields a valid string) so even if we could work around the PHP issue, we’d still be left with problem #1.
In an ideal world, SQL commands would always be in the ASCII charset during transfer and every string value would have a charset argument, of which “binary” could be a possible value, supplied with it. MySQL actually has such a construct for strings, which it calls an “introducer”. “_binary”, however, does not seem to be a valid value.
This charset information would then be used by the other end to convert the string value into its the native charset (either the column’s for client-to-server transfers or the programming language’s string charset for server-to-client transfers).
That way, the only thing that would have to be escaped in BLOB values would be the string delimiter ("
or '
).