web-dev-qa-db-ja.com

PHP配列をMySQLに保存しますか?

単一のmysqlフィールドにデータの配列を保存する良い方法は何ですか?

また、mysqlテーブルでその配列を照会すると、配列形式に戻す良い方法は何ですか?

答えをシリアライズおよびアンシリアライズしますか?

83
JasonDavis

配列を単一のフィールドに格納するgood方法はありません。

リレーショナルデータを調べて、スキーマに適切な変更を加える必要があります。このアプローチのリファレンスについては、以下の例を参照してください。

must配列を単一のフィールドに保存する必要がある場合、 serialize() および unserialize() 関数はトリック。ただし、実際のコンテンツに対してクエリを実行することはできません。

シリアル化関数の代替として、 json_encode() および json_decode() もあります。

次の配列を考えます

$a = array(
    1 => array(
        'a' => 1,
        'b' => 2,
        'c' => 3
    ),
    2 => array(
        'a' => 1,
        'b' => 2,
        'c' => 3
    ),
);

データベースに保存するには、このようなテーブルを作成する必要があります

$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
$r = mysql_query(
    'DROP TABLE IF EXISTS test');
$r = mysql_query(
    'CREATE TABLE test (
      id INTEGER UNSIGNED NOT NULL,
      a INTEGER UNSIGNED NOT NULL,
      b INTEGER UNSIGNED NOT NULL,
      c INTEGER UNSIGNED NOT NULL,
      PRIMARY KEY (id)
    )');

レコードを操作するには、次のようなクエリを実行できます(はい、これは例です、注意してください!)

function getTest() {
    $ret = array();
    $c = connect();
    $query = 'SELECT * FROM test';
    $r = mysql_query($query,$c);
    while ($o = mysql_fetch_array($r,MYSQL_ASSOC)) {
        $ret[array_shift($o)] = $o;
    }
    mysql_close($c);
    return $ret;
}
function putTest($t) {
    $c = connect();
    foreach ($t as $k => $v) {
        $query = "INSERT INTO test (id,".
                implode(',',array_keys($v)).
                ") VALUES ($k,".
                implode(',',$v).
            ")";
        $r = mysql_query($query,$c);
    }
    mysql_close($c);
}

putTest($a);
$b = getTest();

connect()関数はmysql接続リソースを返します

function connect() {
    $c = mysql_connect($server, $username, $password);
    mysql_select_db('test');
    return $c;
}
83
Peter Lindqvist

一般的に、はい、シリアル化と非シリアル化は行く方法です。

ただし、データが単純なものである場合は、コンマ区切りの文字列として保存する方がストレージスペースとしてはおそらく良いでしょう。たとえば、配列が単なる数字のリストであることがわかっている場合は、implode/explodeを使用する必要があります。 1,2,3a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}の違いです。

そうでない場合は、すべてのケースで作業をシリアライズおよびアンシリアライズします。

26
Matchu

DBに保存するための配列のシリアル化/非シリアル化

訪問 http://php.net/manual/en/function.serialize.php

PHPマニュアルから:

ページの「戻る」の下を見てください

どこにでも保存できる値のバイトストリーム表現を含む文字列を返します。

これは、nullバイトを含む可能性のあるバイナリ文字列であり、そのように格納および処理する必要があることに注意してください。たとえば、serialize()出力は通常、CHARまたはTEXTフィールドではなく、データベースのBLOBフィールドに格納する必要があります。

注:htmlをblobに保存する場合は、必ずbase64でエンコードしてください。そうしないと、シリアル化機能が破損する可能性があります。

エンコードの例:

$YourSerializedData = base64_encode(serialize($theHTML));

$YourSerializedDataはblobに保存する準備ができました。

Blobからデータを取得した後、base64_decodeを実行してから、デコード例をアンシリアル化する必要があります。

$theHTML = unserialize(base64_decode($YourSerializedData));
9
seaBass

Serialize PHP関数を使用するだけです:

<?php
$myArray = array('1', '2');
$seralizedArray = serialize($myArray);
?>

ただし、そのような単純な配列を使用している場合は、implodeとexplodeを使用することもできます。newの代わりに空の配列を使用します。

8
KramerC

私が見つけた最良の方法は、配列を区切り文字でデータ文字列として保存することです

$array = array("value1", "value2", "value3", "...", "valuen");
$array_data = implode("array_separator", $array);

$query = "INSERT INTO my_tbl_name (id, array_data) VALUES(NULL,'" . $array_data . "');";

その後、単純なクエリで配列に保存されたデータを検索できます

$query = "SELECT * FROM my_tbl_name WHERE array_data LIKE '%value3%'";

explode()関数を使用して、「array_data」文字列を配列に変換します

$array = explode("array_separator", $array_data);

これは多次元配列では機能しないため、「array_separator」が一意であり、配列値に存在しないことを確認してください。

注意してください !!!フォームデータを取得してデータベースに格納するだけの場合、フォームデータはSQLセーフではないため、トラップに陥ります。フォーム値を mysql_real_escape_string で処理するか、MySQLiを使用する場合 mysqli :: real_escape_string または値が整数またはブールキャスト(int)(ブール)の場合

$number = (int)$_POST['number'];
$checked = (boolean) $_POST['checked'];

$name = mysql_real_escape_string($db_pt, $_POST['name']);
$email = mysqli_obj->real_escape_string($_POST['email']);
8
Harry

シリアル化と非シリアル化はそのために非常に一般的です。また、json_encodeおよびjson_decodeを介してJSONを使用して、PHP固有の形式を減らすこともできます。

6
ceejayoz

前述のように-配列内のデータを検索する必要がない場合は、serializeを使用できますが、これは「phpのみ」です。したがって、パフォーマンスのためだけでなく、移植性のためにもjson_decode/json_encodeを使用することをお勧めします。

4
Sebastian Lasse

ええと、誰もがアレイのシリアル化を提案する理由はわかりません。

最善の方法は、実際にデータベーススキーマに適合させることです。配列内のデータの実際のセマンティックな意味についてはわかりません(そして手がかりはありません)が、一般的にそのようなシーケンスを格納する2つの方法があります

create table mydata (
  id int not null auto_increment primary key,
  field1 int not null,
  field2 int not null,
  ...
  fieldN int not null
)

このようにして、配列を単一の行に格納します。

create table mydata (
    id int not null auto_increment primary key,
    ...
)

create table myotherdata (
    id int not null auto_increment primary key,
    mydata_id int not null,
    sequence int not null,
    data int not null
)

最初の方法の欠点は、明らかに、配列に多くの項目がある場合、そのテーブルでの作業が最もエレガントなものではないことです。また、可変長のシーケンスを処理することは実用的ではありません(可能ですが、非常に洗練されていません-列をNULL可能にするだけです)。

2番目の方法では、任意の長さのシーケンスを使用できますが、タイプは1つのみです。もちろん、1つの型のvarcharまたは何かを作成し、配列の項目をシリアル化できます。最善の方法ではありませんが、アレイ全体をシリアル化するよりも確かに優れています。

いずれにせよ、これらのメソッドはいずれもシーケンスの任意の要素にアクセスできるという明確な利点があり、配列のシリアル化やそのようないことを心配する必要はありません。

それを取り戻すために。さて、クエリで適切な行/行のシーケンスを取得し、loop .. right?を使用しますか?

3
shylent

配列をjsonとして保存できます。
jsonデータ型のドキュメントがあります: https://dev.mysql.com/doc/refman/5.7/en/json.html
これが最善の解決策であり、クレイジーな機能を回避することでコードをより読みやすく維持するのに役立ちます。
これはあなたの役に立つと思います。

2
Roberto Murguia

implode関数をチェックしてください。値は配列にあるため、配列の値をmysqlクエリに入れて、値をテーブルに挿入します。

$query = "INSERT INto hardware (specifications) VALUES (".implode(",",$specifications).")";

配列の値がテキスト値である場合、引用符を追加する必要があります

$query = "INSERT INto hardware (specifications) VALUES ("'.implode("','",$specifications)."')";

mysql_query($query);

また、重複する値が必要ない場合は、「INto」を「IGNORE」に切り替えると、一意の値のみがテーブルに挿入されます。

1
user213559

個々の配列項目のいずれにも含まれないことがわかっている文字で、爆発/爆発を使用することをお勧めします。次に、それを文字列としてSQLに保存します。

1
user1478500

シリアル化されたオブジェクト(配列)をmysqlに挿入できます。例serialize($object)と、オブジェクト例unserialize($object)をunserizeできます。

0
Vildan Bina

うん、シリアル化/非シリアル化は、私が多くのオープンソースプロジェクトで最も見たものです。

0
Eduardo