web-dev-qa-db-fra.com

http_build_query () sans codage d'URL

Existe-t-il un moyen d'utiliser http_build_query() sans le coder par URL conformément à certaines normes RFC?

Pourquoi je ne veux pas tout encoder d'URL: Je demande à l'API Ebay. Ils insistent honnêtement pour que les noms de paramètres ne soient pas encodés en URL, en ce qui concerne les virgules entre parenthèses. Par exemple. DomainName (0) est un paramètre et la requête échoue si ces parenthèses sont codées.

52
bgcode

Vous pouvez utiliser urldecode() function sur une chaîne de résultat que vous obtenez de http_build_query()

117
UserJA

Non, il semble toujours vouloir encoder (ce qui devrait être l'encodage d'URL lors de la création d'une liste de paramètres pour une URL).

Vous pourriez faire votre propre ...

$params = array('a' => 'A', 'b' => 'B');

$paramsJoined = array();

foreach($params as $param => $value) {
   $paramsJoined[] = "$param=$value";
}

$query = implode('&', $paramsJoined);

CodePad .

6
alex

PHP 5.3.1 (Comportement dans le buggy) Http_build_queryNEéchappe au caractère '&' et qui joint les paramètres. Exemple: user_id=1&setting_id=2.

PHP 5.4+ Http_build_query NE FAIT PAS échappe au caractère '&' qui relie les paramètres. Exemple: user_id=1&setting_id=2

Exemple:

$params = array(
    'user_id' => '1', 
    'setting_id' => '2'
);
echo http_build_query($params);

// Output for PHP 5.3.1:
user_id=1&setting_id=2   // NOTICE THAT: '&' character is escaped

// Output for PHP 5.4.0+:
user_id=1&setting_id=2       // NOTICE THAT: '&' character is NOT escaped

Solution pour cibler plusieurs versions

Option n ° 1: Écrire une fonction wrapper:

/** 
 * This will work consistently and will never escape the '&' character
 */
function buildQuery($params) {
    return http_build_query($params, '', '&');
}

Option n ° 2: Abandonnez la fonction http_build_query et écrivez la vôtre.

6
Basil Musa

Vous voudrez peut-être essayer leur API JSON à la place. J'ai essayé d'obtenir un échantillon de travail, mais je n'ai pas de nom d'application et je ne peux donc pas vérifier le résultat. Voici le code:

<?php
$appName = "Your App Name Here";

$post_data = array(
  'jsonns.xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
  'jsonns.xs' => 'http://www.w3.org/2001/XMLSchema',
  'jsonns.tns' => 'http://www.ebay.com/marketplace/search/v1/services',
  'tns.findItemsByKeywordsRequest' => array(
    'keywords' => 'harry potter pheonix'
  )
);

$headers = array(
  "X-EBAY-SOA-REQUEST-DATA-FORMAT: JSON", 
  "X-EBAY-SOA-RESPONSE-DATA-FORMAT: JSON",
  "X-EBAY-SOA-OPERATION-NAME: findItemsByKeywords",
  "X-EBAY-SOA-SECURITY-APPNAME: $appName"
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'http://svcs.ebay.com/services/search/FindingService/v1');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$result = curl_exec($ch);
if($result) {
  $response = json_decode($result);
}

curl_close($ch);
?>

Vous devrez remplir $appName avec le nom de l'application. De plus, le X-EBAY-SOA-OPERATION-NAME devra être défini sur l'appel réel et le JSON modifié si l'appel est différent.

4
onteria_

http_build_query () est INVALID sans codage d'URL. Peut-être avez-vous accidentellement double-encodé? Par exemple, essayez de construire une requête http pour ce tableau:

$params = array('a' => 'a&b=b');

Sans encodage, vous obtiendrez

a=a&b=b

Lorsque correctement codé, vous obtiendrez

a=a%26b%3Db

qui est correct. Si vous ignorez l'encodage, veillez à éviter les attaques par injection d'URL.

4
Marius Balčytis

Vous pouvez utiliser urldecode () ..__ ou utiliser http_build_query avec l'argument $ arg_separator.

    $query_data= $data = array('bar', 'baz'=>'boom');
    $numeric_prefix= 'test_';
    $arg_separator = '&';
    $http_query = http_build_query ( $query_data, $numeric_prefix, $arg_separator );
    var_dump( $http_query );

la sortie de ce qui précède est

     string 'test_0=bar&baz=boom' (length=19)

numeric_prefix: si les index du tableau sont des nombres, cette chaîne est ajoutée en tant que préfixe dans chaque index. Dans ce cas, le 'test_0 = barre'.

arg_separator: est utilisé pour séparer les arguments. Si non est donné php, utilisez le arg_separator.output défini dans le fichier php.ini

Voir php http_build_query

3
mhgo

Cela pourrait aussi fonctionner

$fields = array(
    'a' => 'A', 
    'b' => 'B'
 );

$separator = '';
foreach($fields as $key=>$value) {
    $fields_string .= $separator . $key . '=' . $value; 
    $separator = '&'; 
}
0
Jefkine Kafuna

J'ai essayé de le faire récemment https://Gist.github.com/marcocesarato/4293986fe93139f04d8269aa3fbd47e9 la différence est que cette fonction est un tableau récursif compatible avec PHP4 Vous pouvez gérer ici le code urlencode

<?php
/**
 * Build URL query params
 * as http_build_query build a query url the difference is 
 * that this function is array recursive and compatible with PHP4
 *
 * @author Marco Cesarato <[email protected]>
 * @param $query
 * @param string $parent
 * @return string
 *
 * @example
 * $p = array('abbreviations' => array('google' => 'ggle', 'facebook' => array('abb_key' => 'fbook', 'fcbk')), 'key' => 'value');
 * echo url_build_query($p);
 */
function url_build_query($query, $parent = null){
    $query_array = array();
    foreach($query as $key => $value){
        $_key = empty($parent) ?  urlencode($key) : $parent . '[' . urlencode($key) . ']';
        if(is_array($value)) {
            $query_array[] = url_build_query($value, $_key);
        } else {
            $query_array[] = $_key . '=' . urlencode($value);
        }
    }
    return implode('&', $query_array);
}
0
user4015351

J'essayais de créer une chaîne GET pour l'attacher à la fin d'une URL comme ceci -

$get_params = array(
    'include' => array(
        'enrollments',
        'current_grading_period_scores'
    ),
    'enrollment_type' => array(
        'student',
    ),

);
$get_params = http_build_query($get_params);
$get_params = urldecode($get_params);
$url = $domain.$slug;
$url = $url.'?'.$get_params;
echo $url;

qui imprime

include[0]=enrollments&include[1]=current_grading_period_scores&enrollment_type[0]=student

Mais mon api n'aimait pas les chiffres entre crochets, alors j'ai trouvé une expression régulière qui supprime les chiffres - 

preg_replace('/[[0-9]+]/', '[]', $get_params);

Le code final et le résultat - 

$get_params = array(
    'include' => array(
        'enrollments',
        'current_grading_period_scores'
    ),
    'enrollment_type' => array(
        'student',
    ),

);
$get_params = http_build_query($get_params);
$get_params = urldecode($get_params);
$get_params = preg_replace('/[[0-9]+]/', '[]', $get_params);
$url = $domain.$slug;
$url = $url.'?'.$get_params;
echo $url;

Prints out -

include[]=enrollments&include[]=current_grading_period_scores&enrollment_type[]=student

Si quelqu'un connaît une meilleure expression rationnelle, faites-le-moi savoir, je suis un peu un noob avec ça.

0
kiko carisse

ma réponse à la réponse d'Alex mais est plus rapide

$params = array('a' => 'A', 'b' => 'B');
$query = '';

foreach ($params as $param => $value) {
   $query .= $param.'='.$value .'&';
}

echo substr($query, 0, -1);
0
david