web-dev-qa-db-fra.com

Sauvegarder PHP tableau à MySQL?

Quel est un bon moyen de sauvegarder un tableau de données dans un seul champ mysql? 

Aussi, une fois que je demande ce tableau dans la table mysql, quel est le bon moyen de le récupérer sous forme de tableau?

Est-ce que sérialiser et désérialiser la réponse?

81
JasonDavis

Il n'y a pas de bon moyen de stocker un tableau dans un seul champ.

Vous devez examiner vos données relationnelles et apporter les modifications appropriées à votre schéma. Voir l'exemple ci-dessous pour une référence à cette approche.

Si vous devez enregistrer le tableau dans un seul champ, les fonctions serialize() et unserialize() feront l'affaire. Mais vous ne pouvez pas effectuer de requêtes sur le contenu réel. 

En guise d'alternative à la fonction de sérialisation, il existe également json_encode() et json_decode() .

Considérons le tableau suivant

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

Pour le sauvegarder dans la base de données, vous devez créer une table comme celle-ci.

$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)
    )');

Pour utiliser les enregistrements, vous pouvez exécuter des requêtes telles que celles-ci (et oui, c’est un exemple, méfiez-vous!)

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();

La fonction connect() renvoie une ressource de connexion mysql

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

Généralement, oui, sérialiser et désérialiser sont la voie à suivre.

Cependant, si vos données sont simples, enregistrer sous forme de chaîne délimitée par des virgules serait probablement préférable pour l’espace de stockage. Si vous savez que votre tableau sera simplement une liste de nombres, par exemple, vous devriez alors utiliser implode/explode. C'est la différence entre 1,2,3 et a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}.

Si ce n'est pas le cas, sérialiser et désérialiser fonctionne pour tous les cas.

26
Matchu

Utilisez simplement la fonction serialize PHP:

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

Cependant, si vous utilisez des tableaux simples comme celui-ci, vous pouvez également utiliser implode et explode.

8
KramerC

Sérialiser/désérialiser un tableau pour le stockage dans une base de données

Visitez http://php.net/manual/en/function.serialize.php

Depuis le manuel PHP:

Regardez sous "Retour" sur la page

Renvoie une chaîne contenant une représentation sous forme de flux d'octets pouvant être stockée n'importe où.

Notez qu'il s'agit d'une chaîne binaire pouvant inclure des octets nuls. Elle doit être stockée et traitée comme telle. Par exemple, la sortie serialize () doit généralement être stockée dans un champ BLOB d'une base de données, plutôt que dans un champ CHAR ou TEXT.

Remarque: Si vous souhaitez stocker le code HTML dans un blob, veillez à le coder en base64, sinon la fonction de sérialisation pourrait être brisée. 

Exemple d'encodage: 

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

$YourSerializedData est maintenant prêt à être stocké dans un blob.

Après avoir obtenu les données de blob, vous devez baser64_decode puis désérialiser Exemple de décodage:

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

Le meilleur moyen que je me suis trouvé est de sauvegarder un tableau en tant que chaîne de données avec des caractères de séparation

$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 . "');";

Vous pouvez ensuite rechercher des données, stockées dans votre tableau avec une requête simple

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

utilisez la fonction explode () pour convertir la chaîne "array_data" en array

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

notez que cela ne fonctionne pas avec les tableaux multidimensionnels et assurez-vous que votre "array_separator" est unique et n'existait pas dans les valeurs de tableau. 

Faites attention !!! si vous voulez juste prendre des données de formulaire et les mettre dans une base de données, vous serez piégé, car les données de formulaire ne sont pas sécurisées pour SQL! vous devez gérer la valeur de votre formulaire avec mysql_real_escape_string ou si vous utilisez MySQLi mysqli :: real_escape_string ou si la valeur est un entier ou une conversion booléenne (int) (boolean) 

$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

Sérialiser et désérialiser sont assez communs pour cela. Vous pouvez également utiliser JSON via json_encode et json_decode pour un format moins spécifique à PHP.

5
ceejayoz

Comme mentionné précédemment - Si vous n'avez pas besoin de rechercher des données dans le tableau, vous pouvez utiliser la sérialisation - mais ceci est "php uniquement". Donc, je recommanderais d'utiliser json_decode/json_encode - non seulement pour la performance mais aussi pour la portabilité!

4
Sebastian Lasse

Euh, je ne sais pas pourquoi tout le monde suggère de sérialiser le tableau.

Je dis, le meilleur moyen est de l’intégrer dans votre schéma de base de données. Je n'ai aucune idée (et vous n'avez donné aucun indice) de la signification sémantique réelle des données de votre tableau, mais il y a généralement deux façons de stocker des séquences de ce type.

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

De cette façon, vous stockez votre tableau sur une seule ligne.

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
)

L’inconvénient de la première méthode est, bien évidemment, que si vous avez beaucoup d’éléments dans votre tableau, travailler avec cette table ne sera pas la chose la plus élégante. Il est également peu pratique (possible, mais tout à fait inélégant - il suffit de rendre les colonnes nuls) de travailler avec des séquences de longueur variable.

Pour la deuxième méthode, vous pouvez avoir des séquences de n'importe quelle longueur, mais d'un seul type. Vous pouvez, bien sûr, créer ce type, varchar ou autre, et sérialiser les éléments de votre tableau. Ce n’est pas la meilleure chose à faire, mais certainement meilleure que la sérialisation de l’ensemble, pas vrai?

Quoi qu’il en soit, l’une de ces méthodes présente l’avantage évident de pouvoir accéder à un élément arbitraire de la séquence et vous n’aurez plus à vous soucier de la sérialisation des tableaux ni de ces choses laides.

Quant à le récupérer. Bien, obtenez la ligne/séquence de lignes appropriée avec une requête et, bien, utilisez un loop .., non?

3
shylent

Vous pouvez enregistrer votre tableau en tant que JSON.
il existe une documentation pour le type de données json: https://dev.mysql.com/doc/refman/5.7/en/json.html
Je pense que c'est la meilleure solution et vous aidera à maintenir votre code plus lisible en évitant les fonctions folles.
Je m'attends à ce que cela vous soit utile. 

2
Roberto Murguia

vérifiez la fonction implode, puisque les valeurs sont dans un tableau, vous voulez mettre les valeurs du tableau dans une requête mysql qui insère les valeurs dans une table.

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

Si les valeurs du tableau sont des valeurs de texte, vous devrez ajouter des guillemets.

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

mysql_query($query);

De même, si vous ne souhaitez pas que les valeurs soient dupliquées, réglez "INto" sur "IGNORE" et seules les valeurs uniques seront insérées dans la table.

1
user213559

Je suggérerais d'utiliser implode/explode avec un caractère qui, vous le savez, ne sera contenu dans aucun des éléments du tableau individuel. Puis stockez-le en SQL sous forme de chaîne. 

1
user1478500

vous pouvez insérer un objet sérialisé (tableau) dans mysql, exemple serialize($object) et vous pouvez dé-ziffer exemple exemple unserialize($object)

0
Vildan Bina

Oui, sérialiser/désérialiser est ce que j'ai le plus souvent vu dans de nombreux projets open source.

0
Eduardo