sql >> データベース >  >> RDS >> Mysql

データベースにblobとしてファイルを保存するajaxphppdo

    PHP / PDO/MySQLによる:MEDIUMBLOBに挿入すると、不正なデータが保存されます 、次の行を使用してPDOオブジェクトを作成してみてください:

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

    説明

    リンクされた質問でBenMが指摘しているように、ここでは2つの悪い設計上の決定が行われていると思います。

    接続文字セットのこの概念があります。 SQLテキストは任意の文字セットにすることができ、SQLサーバーによる取得時に変換されるという考え方です。

    これは、テキストではないため、バイナリデータではうまく機能しません。したがって、定義上、どの文字セットにも含めることはできませんが、文字列リテラルを使用して転送されます

    この問題は、転送中にBLOBデータを引用することで回避できます(BASE64_ *関数を使用するか、16進エスケープ )そして、実際、それは多くの人々がしていることです。

    2番目の設計上の決定はPDO/PHPです。PDOは文字セット変換を行いません(PHPの文字列は本質的に文字セットに依存しないため、できません)。したがって、PHPが唯一(または数少ない言語の1つ)であり、 SQL転送文字セットは、入力文字列が実際に含まれているエンコーディングと一致する必要があるため、実際には重要です。

    他の言語では、転送文字セットは、文字列で使用される可能性のあるすべての文字を包含するのに十分な表現力を備えている必要があります。今日の絵文字の世界では、これはおそらくユニコード文字セット(utf-8など)によってのみ保証されます。ただし、これらはいずれもバイナリセーフではありません (バイトのすべての可能な組み合わせが有効な文字列を生成するわけではないという点で)したがって、PHPの問題を回避できたとしても、問題#1が残ることになります。

    理想的な世界では、SQLコマンドは転送中は常にASCII文字セットに含まれ、すべての文字列値には文字セット引数があり、その「バイナリ」が可能な値である可能性があります。 MySQLには実際には、「イントロデューサー」と呼ばれる文字列の構造があります。ただし、「_binary」は有効な値ではないようです。

    次に、この文字セット情報は、文字列値をネイティブ文字セット(クライアントからサーバーへの転送用の列またはサーバーからクライアントへの転送用のプログラミング言語の文字列文字セット)に変換するために、もう一方の端で使用されます。

    >

    そうすれば、BLOB値でエスケープする必要があるのは、文字列区切り文字(")だけです。 または'



    1. データベースで継承を効果的にモデル化するにはどうすればよいですか?

    2. psql:サーバーに接続できませんでした:そのようなファイルまたはディレクトリはありません(Mac OS X)

    3. SQL-2つの列で同じ値を持つ行を選択します

    4. SQLiteのバージョンを確認してください