Comment passer un tableau dans une chaîne de requête?

354

Existe-t-il un moyen standard de passer un tableau via une chaîne de requête?

Pour être clair, j'ai une chaîne de requête avec plusieurs valeurs, dont l'une serait une valeur de tableau. Je veux que cette valeur de chaîne de requête soit traitée comme un tableau - je ne veux pas que le tableau soit éclaté de sorte qu'il soit impossible de le distinguer des autres variables de chaîne de requête.

En outre, selon cette réponse , l'auteur suggère que la prise en charge des chaînes de requête pour les tableaux n'est pas définie. Est-ce exact?

ÉDITER:

Sur la base de la réponse de @ Alex, il n'y a pas de moyen standard de le faire, donc mon suivi est alors quel est un moyen facile de reconnaître que le paramètre que je lis est un tableau à la fois en PHP et en Javascript ?

Serait-il acceptable de nommer plusieurs paramètres du même nom, et de cette façon je saurais qu'ils appartiennent à un tableau? Exemple:

?myarray=value1&myarray=value2&myarray=value3...

Ou serait-ce une mauvaise pratique?

Yarin
la source
Quel cadre utilisez-vous? Certains frameworks ont des méthodes pour aider à passer des tableaux aux chaînes de requête.
keyboardP
@ keyboardP- PHP et Javascript, selon le cas d'utilisation
Yarin
2
Pourquoi voudriez-vous faire cela alors que vous pouvez simplement faire:? Myarray = value1, value2, value3
Serodis
18
@seroids: que faire s'il doit passer des virgules, des points d'interrogation, des signes égaux et des caractères non imprimables?
Berry Tsakala

Réponses:

430

Voici ce que j'ai compris:

La soumission de champs de formulaire à valeurs multiples, c'est-à-dire la soumission de tableaux via des variables GET / POST, peut être effectuée de différentes manières, car une norme n'est pas nécessairement expliquée.

Trois façons possibles d'envoyer des champs ou des tableaux à valeurs multiples seraient:

  • ?cars[]=Saab&cars[]=Audi (Meilleur moyen - PHP lit ceci dans un tableau)
  • ?cars=Saab&cars=Audi (Mauvaise façon - PHP n'enregistrera que la dernière valeur)
  • ?cars=Saab,Audi (Je n'ai pas essayé ça)

Exemples de formulaires

Sur un formulaire, les champs à valeurs multiples peuvent prendre la forme d'une boîte de sélection définie sur plusieurs :

<form> 
    <select multiple="multiple" name="cars[]"> 
        <option>Volvo</option> 
        <option>Saab</option> 
        <option>Mercedes</option> 
    </select>
</form>

(REMARQUE: dans ce cas, il serait important de nommer le contrôle de sélection some_name[], afin que les variables de requête résultantes soient enregistrées en tant que tableau par PHP)

... ou comme plusieurs champs cachés du même nom :

<input type="hidden" name="cars[]" value="Volvo">
<input type="hidden" name="cars[]" value="Saab">
<input type="hidden" name="cars[]" value="Mercedes">

REMARQUE: l' utilisation field[]de plusieurs valeurs est vraiment mal documentée. Je n'en vois aucune mention dans la section sur les clés à valeurs multiples dans la chaîne de requête - Wikipedia , ou dans les documents du W3C traitant des entrées à sélection multiple.


MISE À JOUR

Comme l'ont souligné les commentateurs, cela est très spécifique au cadre. Quelques exemples:

Chaîne de requête:

?list_a=1&list_a=2&list_a=3&list_b[]=1&list_b[]=2&list_b[]=3&list_c=1,2,3

Rails:

"list_a": "3", 
"list_b":[
    "1",
    "2",
    "3"
  ], 
"list_c": "1,2,3"

Angulaire:

 "list_a": [
    "1",
    "2",
    "3"
  ],
  "list_b[]": [
    "1",
    "2",
    "3"
  ],
  "list_c": "1,2,3"

( Discussion angulaire )

Voir les commentaires pour des exemples dans node.js , Wordpress , ASP.net


Maintenir l'ordre: Une autre chose à considérer est que si vous avez besoin de maintenir l' ordre de vos éléments (c'est-à-dire un tableau en tant que liste ordonnée), vous n'avez vraiment qu'une seule option, qui est de passer une liste de valeurs délimitée et de la convertir explicitement en un tableau vous-même.

Yarin
la source
3
Je pense que la raison pour laquelle cette fonctionnalité n'est pas documentée dans des sources générales comme Wiki ou W3C est qu'elle n'est généralement pas prise en charge par les frameworks Web. PHP et je pense que Rails convertit automatiquement plusieurs paramètres de requête "clé []" en un tableau. D'autres non.
Carl G
3
Le module nodejs querystring utilise le ?cars=Saab&cars=Audiformulaire
SystemParadox
53
En express (node.js), les deux ?cars=Saab&cars=Audiet ?cars[]=Saab&cars[]=Audise transforment en tableaux. Cependant, ?cars=Saabse termine par une chaîne, mais ?cars[]=Saabest un tableau avec un seul élément.
Trevor Dixon
5
Pouvez-vous définir des clés en utilisant cette approche? Et qu'en est-il des tableaux multidimensionnels?
Qwerty
5
ASP.NET MVC ne semble pas lire le format ?cars[]=Saab&cars[]=AudiIl n'y a pas de crochets ou les crochets ont besoin d'index /
M. Flibble
37

Une chaîne de requête contient des données textuelles, il n'y a donc pas d'autre choix que d'exploser le tableau, de le coder correctement et de le passer dans un format de représentation de votre choix:

p1=value1&pN=valueN...
data=[value1,...,valueN]
data={p1:value1,...,pN:valueN}

puis le décoder dans votre code côté serveur.

Alex K.
la source
OK merci pour la clarification. Pouvez-vous voir ma question révisée - est-il nécessaire de faire p1 ... pn, pour les clés, ou puis-je simplement nommer plusieurs clés «p», et de cette façon je saurais qu'elles appartiennent toutes au même tableau?
Yarin
1
Vous pouvez utiliser le même nom; stackoverflow.com/questions/2203430/… ou simplement p = aa, bb, cc qui est le moyen le plus évident comme l'a commenté Serodis.
Alex K.
très utile avec JSON.stringifyet JSON.parse!
charliebrownie
1
Un format de représentation simple et commun est JSON, en PHP en utilisant json_encodepuis rawurlencodeet json_decodesur l'autre page.
Edward
20

Je ne pense pas qu'il existe une norme.
Chaque environnement Web fournit sa propre «norme» pour de telles choses. En outre, l'URL est généralement trop courte pour quoi que ce soit (limite de 256 octets sur certains navigateurs). Bien sûr, des tableaux / données plus longs peuvent être envoyés avec des requêtes POST.

Cependant, il existe quelques méthodes:

  1. Il existe une méthode PHP, qui utilise des crochets ( [, ]) dans les requêtes URL. Par exemple, une requête telle que celle-ci ?array_name[]=item&array_name[]=item_2a fonctionné, bien qu'elle soit mal documentée, avec PHP la convertissant automatiquement en tableau. Source: https://stackoverflow.com/a/9547490/3787376

  2. Les formats d'échange de données d'objets (par exemple JSON - site officiel , documentation PHP ) peuvent également être utilisés s'ils ont des méthodes de conversion de variables vers et depuis des chaînes comme le fait JSON.
    Un encodeur url (disponible pour la plupart des langages de programmation) est également requis pour les requêtes get HTTP afin d'encoder correctement les données de chaîne.

Bien que la "méthode des crochets" soit simple et fonctionne, elle est limitée à PHP et aux tableaux.
Si d'autres types de variables tels que des classes ou des variables de passage dans des chaînes de requête dans un langage autre que PHP sont requis, la méthode JSON est recommandée.

Exemple en PHP de la méthode JSON (méthode 2):

$myarray = array(2, 46, 34, "dfg");
$serialized = json_encode($myarray)
$data = 'myarray=' . rawurlencode($serialized);
// Send to page via cURL, header() or other service.

Code de réception de page (PHP):

$myarray = json_decode($_GET["myarray"]); // Or $_POST["myarray"] if a post request.
Berry Tsakala
la source
1
Express.js prend également en charge la notation entre crochets, testée sur 4.13.4.
Steve Kehlet
7

Je pense que ce serait utile pour quelqu'un qui cherche à passer le tableau dans une chaîne de requête à un servlet. J'ai testé la chaîne de requête ci-dessous et j'ai pu obtenir les valeurs du tableau à l'aide de req.getgetParameterValues ​​(); méthode. Vous trouverez ci-dessous la chaîne de requête que j'ai passée via le navigateur.

  http://localhost:8080/ServletsTutorials/*.html? 
  myname=abc&initial=xyz&checkbox=a&checkbox=b

la case à cocher est mon tableau de paramètres ici.

vara
la source
5

Cela fonctionne pour moi:

En lien, attribuer a une valeur:

to="/filter/arr?fruits=apple&fruits=banana"

Route peut gérer cela:

path="/filter/:arr"

Pour plusieurs tableaux:

to="filter/arr?fruits=apple&fruits=banana&vegetables=potato&vegetables=onion"

La route reste la même.

CAPTURE D'ÉCRAN

entrez la description de l'image ici

Alia
la source
2

Vous mentionnez PHP et Javascript dans votre question, mais pas dans les balises. J'ai atteint cette question avec l'intention de passer un tableau à une action MVC.Net.

J'ai trouvé la réponse à ma question ici : le format attendu est celui que vous avez proposé dans votre question, avec plusieurs paramètres portant le même nom.

DCShannon
la source
2
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien de référence. Les réponses de lien uniquement peuvent devenir invalides si la page liée change.
Andrew
@Andrew Ce n'est pas seulement une réponse de lien. "Le format attendu est celui que vous avez proposé dans votre question, avec plusieurs paramètres portant le même nom."
DCShannon
2

J'utilise React et Rails. J'ai fait:

js

  let params = {
    filter_array: ['A', 'B', 'C']
  }

  ...

  //transform params in URI

  Object.keys(params).map(key => {
    if (Array.isArray(params[key])) {
      return params[key].map((value) => `${key}[]=${value}`).join('&')
    }
  }
  //filter_array[]=A&filter_array[]=B&filter_array[]=C
Linielson
la source
1

Vous pouvez utiliser http_build_query pour générer une chaîne de requête codée URL à partir d'un tableau en PHP. Alors que la chaîne de requête résultante sera développée, vous pouvez décider du séparateur unique que vous souhaitez comme paramètre de la http_build_queryméthode, donc en ce qui concerne le décodage, vous pouvez vérifier quel séparateur a été utilisé. Si c'était l'unique que vous avez choisi, ce serait la chaîne de requête de tableau, sinon ce serait la chaîne de requête normale.

keyboardP
la source
1

Bien qu'il n'y ait pas de norme pour la partie URL, il existe une norme pour JavaScript. Si vous passez des objets contenant des tableaux à URLSearchParams, et appelez- toString()le, il le transformera en une liste d'éléments séparés par des virgules:

let data = {
  str: 'abc',
  arr: ['abc', 123]
}

new URLSearchParams(data).toString();  # ?str=abc&arr=abc,123
João Haas
la source
0

Vérifiez la parse_stringfonction http://php.net/manual/en/function.parse-str.php

Il renverra toutes les variables d'une chaîne de requête, y compris les tableaux.

Exemple de php.net:

<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str);
echo $first;  // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz

parse_str($str, $output);
echo $output['first'];  // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz

?>
Dan Murfitt
la source