Сохранить массив PHP к MySQL?

Что хороший путь состоит в том, чтобы сохранить массив данных к единственному mysql полю?

Также, как только я запрашиваю для того массива в mysql таблице, что хороший путь состоит в том, чтобы вернуть его в форму массива?

Сериализируют и не сериализируют ответ?

83
задан JasonDavis 30 December 2009 в 04:33
поделиться

8 ответов

Нет никакого хорошего способа хранения массива в одном поле.

Вам необходимо изучить данные ваших реляций и внести соответствующие изменения в схему. См. пример ниже для ссылки на этот подход.

Если вы должны сохранить массив в одном поле, то функции 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;
}
84
ответ дан 24 November 2019 в 08:52
поделиться

Вместо того, чтобы сохранять его в базу данных, сохраните его в файл, а затем вызовите позже.

Многие php-приложения (например, sugarcrm) просто используют var_export для передачи всех данных из массива в файл. Это то, что я использую для сохранения данных моих конфигураций:

private function saveConfig() {
    file_put_contents($this->_data['pathtocompileddata'],'<?php' . PHP_EOL . '$acs_confdata = ' . var_export($this->_data,true) . ';');        
}

Я думаю, что это лучший способ сохранить ваши данные!

-5
ответ дан 24 November 2019 в 08:52
поделиться

Да, сериализация/несериализация - это то, что я видел больше всего во многих проектах с открытым исходным кодом.

0
ответ дан 24 November 2019 в 08:52
поделиться

Не знаю, почему все предлагают сериализовать массив.

Я говорю, что лучший способ - это вписать его в схему вашей базы данных. Понятия не имею (и вы не дали подсказок) о реальном семантическом значении данных в вашем массиве, но обычно есть два способа хранения таких последовательностей

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
)

Недостатком первого способа, очевидно, является то, что если в вашем массиве много элементов, то работа с этой таблицей не будет самой элегантной вещью. Работать с последовательностями переменной длины также непрактично (возможно, но и весьма неудобно - просто сделайте столбцы нулевыми)

Для второго метода можно иметь последовательности любой длины, но только одного типа. Конечно же, можно сделать этот один тип бархаром или что-то в этом роде и сериализовать элементы массива. Не лучший вариант, но, конечно, лучший, чем сериализация всего массива, верно?

В любом случае, любой из этих методов получает явное преимущество в том, что можно получить доступ к произвольному элементу последовательности, и вам не нужно беспокоиться о сериализации массивов и подобных неприятных вещах.

Что же касается возврата. Получить соответствующую строку/последовательность строк с запросом и, ну, использовать цикл... верно?

.
3
ответ дан 24 November 2019 в 08:52
поделиться

Просто используйте функцию сериализации PHP:

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

Однако, если вы используете такие простые массивы, вы можете также использовать implode и explode.use an blank array instead a new.

.
8
ответ дан 24 November 2019 в 08:52
поделиться

проверьте функцию implode, так как значения находятся в массиве, вы хотите поместить значения массива в mysql запрос, который вставляет значения в таблицу.

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

Если значения в массиве являются текстовыми значениями, вам необходимо добавить кавычки

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

mysql_query($query);

Также, если вы не хотите дублировать значения, переключите "INto" на "IGNORE" и в таблицу будут вставлены только уникальные значения.

.
0
ответ дан 24 November 2019 в 08:52
поделиться

Сериализовать и несериализовать довольно часто. Вы также можете использовать JSON через json_encode и json_decode для менее специфичного для PHP формата.

.
6
ответ дан 24 November 2019 в 08:52
поделиться

Обычно, да, сериализовать и несериализовать - это то, что нужно.

Если ваши данные - это что-то простое, то сохранение их в виде строки, разделенной запятыми, наверное, было бы лучше для пространства хранения. Если вы знаете, что ваш массив будет просто списком номеров, например, то вам следует использовать implode/explode. Это разница между 1,2,3 и a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}.

Если нет, то сериализуйте и несериализуйте работу для всех случаев.

.
26
ответ дан 24 November 2019 в 08:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: