Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapisywanie plików jako blob w bazie danych ajax php pdo

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 ' ).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. DODAJ KOLUMNĘ MySQL

  2. jak wybrać licznik z głównego zapytania do podzapytania

  3. Używanie % dla hosta podczas tworzenia użytkownika MySQL

  4. Jak mogę poprosić o pomoc w optymalizacji i naprawianiu zapytań w MySQL?

  5. Jak zignorować parametr w przygotowanym zapytaniu mysqli w PHP?