Подтвердить что ты не робот

Http_build_query() без кодировки url

Есть ли способ использовать http_build_query() без кодирования URL в соответствии с некоторым стандартом RFC?

Почему я не хочу, чтобы URL-адрес кодировал все: я обращаюсь к API Ebay. Они честно настаивают на том, что имена параметров не кодируются URL-адресом, поскольку в скобках указаны запятые. Например. DomainName (0) - это параметр, и запрос завершается с ошибкой, если эти парсеры закодированы.

4b9b3361

Ответ 1

Вы можете использовать urldecode() функцию в строке результата, которую вы получаете от http_build_query()

Ответ 2

Нет, кажется, он всегда хочет кодировать (что должно быть, оно предназначено для кодирования URL при создании списка параметров для URL-адреса).

Вы можете сделать свой собственный...

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

$paramsJoined = array();

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

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

CodePad.

Ответ 3

Вместо этого вы можете попробовать использовать JSON API. Я попытался получить рабочий образец, но у меня нет имени приложения, поэтому я не могу проверить результат. Здесь код:

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

Вам нужно заполнить $appName любым именем приложения. Также нужно установить X-EBAY-SOA-OPERATION-NAME на фактический вызов, а JSON изменить, если вызов отличается.

Ответ 4

http_build_query() является INVALID без urlencoding. Может быть, вы случайно его дважды закодируете? Например, попробуйте создать HTTP-запрос для этого массива:

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

Без кодирования вы получите

a=a&b=b

При правильном кодировании вы получите

a=a%26b%3Db

что является правильным. Если вы пропустите кодировку, не забудьте избежать атак с помощью URL-атак.

Ответ 5

PHP 5.3.1 (Багги-поведение) http_build_query ДАЕТ выйти из режима '&' амперсанд, который объединяет параметры. Пример: user_id=1&amp;setting_id=2.

PHP 5.4 + http_build_query НЕ не выполняет '&' амперсанд, который объединяет параметры. Пример: user_id=1&setting_id=2

Пример:

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

// Output for PHP 5.3.1:
user_id=1&amp;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

Решение при таргетинге на несколько версий

Вариант №1: Записать функцию обертки:

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

Вариант №2: Отключить функцию http_build_query и написать свой собственный.

Ответ 6

Вы можете использовать urldecode(). Или используйте http_build_query с аргументом $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 );

вывод выше:

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

numeric_prefix: если индексы массива являются числами, эта строка добавляется как префикс в каждом индексе. В этом случае "test_0 = bar".

arg_separator: используется для разделения аргументов. Если non задан php, используйте arg_separator.output, разлитый в php.ini

См. php http_build_query

Ответ 7

мой ответ на alex, но быстрее

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

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

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

Ответ 8

Это также может работать

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

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