Zgodnie z PHP/PDO/MySQL :wstawienie do MEDIUMBLOB przechowuje złe dane , spróbuj użyć następującego wiersza do skonstruowania obiektu PDO:
$dbh = new PDO($dsn, $username, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1 COLLATE latin1_general_ci"));
Wyjaśnienie
Myślę, że, jak zauważa Ben M w powiązanym pytaniu, działają tutaj dwie złe decyzje projektowe.
Jest taka koncepcja zestawu znaków połączenia. Pomysł polega na tym, że tekst SQL może być w dowolnym zestawie znaków, a następnie jest konwertowany po pobraniu przez serwer SQL.
Nie działa to tak dobrze w przypadku danych binarnych, ponieważ nie są one tekstowe, a zatem z definicji nie mogą znajdować się w żadnym zestawie znaków, ale nadal są przesyłane za pomocą literałów łańcuchowych .
Ten problem można obejść, cytując dane BLOB podczas przesyłania (za pomocą funkcji BASE64_* lub szesnastkowy kod ucieczki ) i rzeczywiście to właśnie robi wiele osób.
Druga decyzja projektowa dotyczy PDO/PHP:PDO nie dokonuje żadnej konwersji zestawu znaków (nie może, ponieważ łańcuchy w PHP są z natury niezależne od zestawu znaków), więc PHP jest jedynym (lub jednym z kilku języków), w którym wybór zestaw znaków transferu SQL jest tak naprawdę ważny, ponieważ musi pasować do kodowania, w którym faktycznie znajdują się ciągi wejściowe.
W innych językach zestaw znaków transferu musi być wystarczająco wyrazisty, aby objąć wszelkie znaki, które mogą być użyte w łańcuchach. W dzisiejszym świecie emoji jest to najprawdopodobniej gwarantowane tylko przez zestawy znaków Unicode (utf-8 i tym podobne). Jednak żadne z nich nie są bezpieczne dla plików binarnych (ponieważ nie każda możliwa kombinacja bajtów daje prawidłowy ciąg znaków), więc nawet gdybyśmy mogli obejść problem z PHP, nadal mielibyśmy problem nr 1.
W idealnym świecie polecenia SQL zawsze byłyby w zestawie znaków ASCII podczas przesyłania, a każda wartość ciągu miałaby argument zestawu znaków, którego „binarny” mógłby być możliwą wartością, dostarczoną wraz z nim. MySQL faktycznie ma taką konstrukcję dla łańcuchów, którą nazywa „wprowadzającym”. Jednak „_binary” nie wydaje się być prawidłową wartością.
Ta informacja o zestawie znaków byłaby następnie użyta przez drugi koniec do przekonwertowania wartości ciągu na jego natywny zestaw znaków (albo kolumna dla transferów klient-serwer, albo łańcuch znaków języka programowania dla transferów serwer-klient).
W ten sposób jedyną rzeczą, która musiałaby zostać zmieniona w wartości BLOB, byłby ogranicznik ciągu ("
lub '
).