sql >> Database teknologi >  >> RDS >> Mysql

Gemmer filer som blob i databasen ajax php pdo

Ifølge PHP/PDO/MySQL :indsættelse i MEDIUMBLOB gemmer dårlige data , prøv at bruge følgende linje til at konstruere dit PDO-objekt:

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

Forklaring

Jeg tror, ​​der er, som Ben M bemærker i det linkede spørgsmål, to dårlige designbeslutninger på arbejde her.

Der er dette koncept med et forbindelsestegnsæt. Ideen er, at SQL-teksten kan være i et hvilket som helst tegnsæt og derefter konverteres ved hentning af SQL-serveren.

Dette fungerer ikke så godt med binære data, da det ikke er tekst og derfor ikke pr. definition må være i noget tegnsæt, men det stadig overføres ved hjælp af streng-literals .

Dette problem kan løses ved at citere BLOB-data under overførsel (enten ved at bruge BASE64_*-funktionerne eller ved at hex-escaping ), og det er faktisk, hvad mange mennesker gør.

Den anden designbeslutning er i PDO/PHP:PDO udfører ingen tegnsætkonvertering (det kan den ikke, fordi strenge i PHP i sagens natur er tegnsæt-agnostiske), så PHP er det eneste (eller et af de få sprog), hvor valget af SQL-overførselstegnsættet er faktisk vigtigt, fordi det skal matche den kodning, som inputstrengene faktisk er i.

På andre sprog skal overførselstegnsættet blot være udtryksfuldt nok til at omfatte alle tegn, der kan bruges i strenge. I dagens verden af ​​emojis er dette højst sandsynligt kun garanteret af unicode-tegnsæt (utf-8 og lignende). Men ingen af ​​disse er binært sikre (ved at ikke alle mulige kombinationer af bytes giver en gyldig streng), så selvom vi kunne omgå PHP-problemet, ville vi stadig stå tilbage med problem #1.

I en ideel verden ville SQL-kommandoer altid være i ASCII-tegnsættet under overførslen, og hver strengværdi ville have et tegnsæt-argument, hvoraf "binær" kunne være en mulig værdi, leveret med den. MySQL har faktisk sådan en konstruktion til strenge, som den kalder en "introducer". "_binary" ser dog ikke ud til at være en gyldig værdi.

Disse tegnsætoplysninger vil så blive brugt af den anden ende til at konvertere strengværdien til dens oprindelige tegnsæt (enten kolonnens for klient-til-server-overførsler eller programmeringssprogets streng-tegnsæt for server-til-klient-overførsler).

På den måde ville det eneste, der skulle escapes i BLOB-værdier være strengeafgrænseren (" eller ' ).



  1. Hvorfor er udførelsestiden for oracle-lagrede procedurer stærkt forøget afhængigt af, hvordan den udføres?

  2. Hvad er der galt med denne MySQL-sætning:DECLARE @ID INT

  3. Oracle SQL Where-klausul for at finde datoposter, der er ældre end 30 dage

  4. Advarsel:mysql_num_rows():det angivne argument er ikke en gyldig MySQL-resultatressource