IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Mettre à jour un champs de type json avec une valeur de type array


Sujet :

PHP & Base de données

  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2009
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 171
    Par défaut Mettre à jour un champs de type json avec une valeur de type array
    Bonjour,

    J'ai un petit code pour insérer des données en type array dans un champs type json.

    Structure de la table, le champs concerné est restaurant_order:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    describe restaurant_list;
    +------------------+--------------+------+-----+---------+----------------+
    | Field            | Type         | Null | Key | Default | Extra          |
    +------------------+--------------+------+-----+---------+----------------+
    | id               | int unsigned | NO   | PRI | NULL    | auto_increment |
    | restaurant_name  | varchar(50)  | NO   |     | NULL    |                |
    | timing           | json         | NO   |     | NULL    |                |
    | meals            | json         | NO   |     | NULL    |                |
    | restaurant_order | json         | NO   |     | NULL    |                |
    +------------------+--------------+------+-----+---------+----------------+
    5 rows in set (0.10 sec)

    Pour insérer ces données, j'utilise une class PDO, voici un petit morceau de la class:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
    public function jsonArray($table, $item, $values, $where = null)
    {
        // i.e of updating data which works
     
        //UPDATE restaurant_list SET restaurant_order = JSON_ARRAY('1', '2') WHERE `id` = 1;
     
        $values   = ':'.$values;
     
        $sql = 'UPDATE '.$table.' SET '.$item.' = JSON_ARRAY('.$values.')';
     
        if ($where != null) {
            $sql .= ' WHERE ' . $where;
        }
     
        $this->sql    = $sql;
        return $this->sql;
    }
     
    /*** function to prepare query Start ***/
    public function prepare()
    {
        return $this->stmt = $this->dbh->prepare($this->sql);
    }
    /*** function to prepare query EnD ***/
     
    /*** function to bind query Start ***/
    public function bind($param, $value, $type = null)
    {
        if (is_null($type)) :
            switch (true):
                case is_int($value):
                    $type = PDO::PARAM_INT;
                    break;
     
                case is_bool($value):
                    $type = PDO::PARAM_BOOL;    
                    break;
     
                case is_null($value):
                    $type = PDO::PARAM_NULL;
                    break;
     
                case is_string($value):
                    $type = PDO::PARAM_STR;
                    break;
     
                default: // array
                    $type = null;
                    //echo "string 44444<br>";
     
            endswitch; // end switch (true):
        endif; // end if (is_null($type)):
     
        if(is_array($value)):
     
     
            $value  = $value;
        else:
            $value = $this->strSafe($value);
        endif;
     
        $this->stmt->bindParam($param, $value, $type);
    }
     
    /*** function to bind query EnD ***/
     
    /*** function to execute query Start ***/
    public function execute()
    {
        return $this->stmt->execute();
    }
    /*** function to execute query EnD ***/
     
    /*** function to execute and fetch Start ***/
    public function resultset()
    {
        $this->execute();
        return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    /*** function to execute and fetch EnD ***/
     
    public function strSafe($string)
    {
        $string = trim(strip_tags(($string)));
        $string = preg_replace('/\s+/', ' ', $string); // remove more than one space
        $this->string    = $string;
     
        return $this->string;
    }
    Le code d'insertion est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    require_once 'crud.php';
    // initialize the connection class
    $dbh    = new Database();
     
    $p_cat      = [1,5];
     
    $upOn   = $dbh->jsonArray('restaurant_list', 'restaurant_order', 'value', 'id = :id');
     
        $dbh->prepare($upOn);
     
        foreach($p_cat as $pc):
        $dbh->bind('value', implode('","', $p_cat));
        endforeach;
     
     
        $dbh->bind('id', 1);
     
        $dbh->execute();
    Quand j'insère les données, je reçois ce résultat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT restaurant_order FROM restaurant_list;
    +----------------------+
    | restaurant_order     |
    +----------------------+
    | ["1\",\"5"]          | ===> Le nouveau champs
    | ["1", "2", "3", "4"] |
    | ["1", "2", "4"]      |
    +----------------------+
    3 rows in set (0.00 sec)
    * Comment puis-je mettre à jour les données pour avoir un résultat similaire à ["1","5"]?
    * Est ce que cette méthode est sécurisée? Sinon, y a-t il un autre moyen pour effectuer cette opération?

    Merci à vous

  2. #2
    Membre Expert Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 895
    Par défaut
    Bonjour,

    Comment puis-je mettre à jour les données pour avoir un résultat similaire à ["1","5"]?
    Je ne comprends pas, c'est déjà ce que vous faites... bien que personnellement, je préfère utliser json_encode() plutôt que de laisser MySQL faire son tableau
    Cela permet de pouvoir contrôler les données AVANT l'insert/update et de retourner une erreur si le format est incorrect (à condition que le type de champ soit bien JSON)

    Est ce que cette méthode est sécurisée? Sinon, y a-t il un autre moyen pour effectuer cette opération?
    Difficile à dire. Vous donnez des valeurs sorties de nul part et votre exemple n'est pas fonctionnel car vous avez écrit : $dbh->jsonArray('restaurant_list', 'restaurant_order', 'value', 'id = :id');.
    C'est le 3e paramètre qui devrait nous intéresser mais il s'agit ici d'un string, il y a forcément erreur. J'imagine qu'il s'agit de la variable $p_cat mais vu qu'on ne sait pas d'où elle vient, difficile à dire.

    En tout cas, personnellement, je trouve ça extrêmement compliqué de lire une requête séparée à 2 endroits. Rien que pour la lire ici ça m'a retourné le cerveau.
    Vous écrivez la requête dans une fonction par contre vous faites les bind et exécuté la requête en dehors. Ca serait plus simple que tout se fasse soit dans la fonction soit directement dans le code.

  3. #3
    Inactif  
    Homme Profil pro
    Webmaster
    Inscrit en
    Juin 2021
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juin 2021
    Messages : 645
    Par défaut
    Bonjour,

    Citation Envoyé par darkstar123456 Voir le message
    ...votre exemple n'est pas fonctionnel car vous avez écrit : $dbh->jsonArray('restaurant_list', 'restaurant_order', 'value', 'id = :id');.
    C'est le 3e paramètre qui devrait nous intéresser mais il s'agit ici d'un string, il y a forcément erreur....
    @darkstar123456
    1- En fait, non, c'est "correct"... mais la fonction jsonArray ne fait QUE la moitié du travail !
    jsonArray ne retourne QUE la partie SQL de la requête, SANS les paramètres associés (variables).
    Le reste se trouve dans le code d'insertion !

    En réalité, cette fonction n'a (quasiment) AUCUN intérêt, puisqu'il suffit de remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $upOn   = $dbh->jsonArray('restaurant_list', 'restaurant_order', 'value', 'id = :id');
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $upOn = "UPDATE restaurant_list SET restaurant_order = JSON_ARRAY(:value) WHERE id = :id";
    2- Concernant le problème ["1\",\"5"] :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $dbh->bind('value', implode('","', $p_cat)); // 1","5
    il manque des " pour compléter les chaines :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $dbh->bind('value', '"'.implode('","', $p_cat).'"'); // "1","5"

  4. #4
    Membre Expert Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 895
    Par défaut
    1- En fait, non, c'est "correct"...
    En effet, j'ai relu grâce à toi et comme de fait, cette façon d'écrire m'a complètement retourné le cerveau... encore plus que je l'imaginais
    Je trouvais déjà que c'était inutile mais c'est encore pire que ça, ça retire toute lisibilité !! D'autant que le fait de séparer la requête de ses binds est propice à faire n'importe quoi

    mais la fonction jsonArray ne fait QUE la moitié du travail !
    On se rejoint là-dessus :p

  5. #5
    Membre confirmé
    Inscrit en
    Juillet 2009
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 171
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    En réalité, cette fonction n'a (quasiment) AUCUN intérêt, puisqu'il suffit de remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $upOn   = $dbh->jsonArray('restaurant_list', 'restaurant_order', 'value', 'id = :id');
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $upOn = "UPDATE restaurant_list SET restaurant_order = JSON_ARRAY(:value) WHERE id = :id";
    Si je remplace par la requete ci-dessus: je recois cette erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Notice: Undefined property: Database::$sql in CRUD.php on line 151
    Ligne 151 est le return de cette fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public function prepare()
        {
            return $this->stmt = $this->dbh->prepare($this->sql); // ligne 151
        }
    2- Concernant le problème ["1\",\"5"] :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $dbh->bind('value', implode('","', $p_cat)); // 1","5
    il manque des " pour compléter les chaines :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $dbh->bind('value', '"'.implode('","', $p_cat).'"'); // "1","5"
    J'ai corrigé le code, mais ce n'est pas le résultat souhaité:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    [0] => Array
            (
                [id] => 1
                [restaurant_name] => L'Adresse
                [timing] => {"amc": "null", "amo": "07:00", "pmc": "23:00", "pmo": "null"}
                [meals] => [1, 2, 3, 4]
                [restaurant_order] => ["\"2\",\"1\",\"8\""] => Toujours des anti-slash
            )

Discussions similaires

  1. [AC-97] Mettre à jour un champ du côté un d'une relation un-à-plusieurs.
    Par cacoubalboa dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 25/05/2009, 13h47
  2. Mettre à jour 1 champ avec un compteur
    Par Mvu dans le forum ASP
    Réponses: 2
    Dernier message: 18/12/2008, 23h09
  3. Mettre à jour plusieurs champs avec la même requête, est-ce possible ?
    Par marchand_de_sable dans le forum Langage SQL
    Réponses: 6
    Dernier message: 13/06/2008, 17h36
  4. Comment mettre à jour un champ BLOB avec une TIBQUERY ?
    Par colorid dans le forum Bases de données
    Réponses: 4
    Dernier message: 26/02/2008, 19h00
  5. Mettre à jour un champ Boolean avec une clause "WHERE"
    Par niano dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 02/10/2007, 11h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo