Я пишу php-приложение, которое отправляет через curl-данные, чтобы подписаться на список электронной почты iContact. Однако я продолжаю получать неверную ошибку адреса электронной почты. Я думаю, это может быть связано с тем, что я избегаю символа @, поэтому он выглядит как% 40 вместо @. Кроме того, согласно документации php для curl_setopt с CURLOPT_POSTFIELDS:
Полные данные для отправки в HTTP-режиме «POST». Чтобы опубликовать файл, добавьте имя файла с помощью @ и используйте полный путь.
Итак, есть ли все равно, чтобы передать символ @ в качестве пост-данных через curl в php, не запуская сначала через urlencode?
http_build_query()
используйте http_build_query()
в вашем массиве данных, прежде чем передать его curl_setopt()
, что приведет к отправке формы в виде application/x-www-form-encoded
вместо multipart/form-data
(и, следовательно, @ не интерпретировать).
Также почему вы действительно волнуете @ в адресе электронной почты? Это имеет значение только в том случае, если @ – первый символ, а не где-то посередине.
После поиска PHP curl manual, я обнаружил, что нет информации, чтобы избежать первого «@», если поле post является строкой вместо файла, если сообщение с кодировкой multipart / form-data.
Способ, которым я работал над этой проблемой, – это префикс пробела в начале текста. Хотя наш бэкэнд-API будет удалять пробелы, чтобы он мог удалить пустой и восстановить исходный текст. Я не знаю, что погода Twitter API будет обрезать пробелы при вводе пользователя.
Если это так, это обходное решение также работает для вас.
Если кто-то нашел способ избежать первого «@» при использовании PHP curl с кодировкой multipart / form-data, сообщите нам об этом.
Я столкнулся с той же проблемой, хотя и с завитом, а не с завихрением PHP.
При использовании опции поля «rot» в поле « -F
» ведущий символ @ не будет отправляться в POST, но вместо этого будет инструктировать curl для отправки имени файла, которое сразу же удастся заменить символ как часть POST.
К счастью, curl предлагает еще одну опцию ' --form-string
', которая ведет себя так же, как ' -F
', за исключением того, что опция «form-string» не анализируется.
Например, если вы хотите использовать curl для поля POST1 со значением «@value» и file1 с файлом «testfile.txt», вы можете сделать это следующим образом:
curl "http://www.url.com" --form-string "field1=@value" -F "file1=@testfile.txt"
Это истинное решение, которое поддерживает обе строки, содержащие @
и файлы .
CURLFile
вместо @
. CURLOPT_SAFE_UPLOAD
. CURLFile
вместо @
. Content-Type
самостоятельно. Следующий фрагмент поможет вам: D
<?php /** * For safe multipart POST request for PHP5.3 ~ PHP 5.4. * * @param resource $ch cURL resource * @param array $assoc "name => value" * @param array $files "name => path" * @return bool */ function curl_custom_postfields($ch, array $assoc = array(), array $files = array()) { // invalid characters for "name" and "filename" static $disallow = array("\0", "\"", "\r", "\n"); // initialize body $body = array(); // build normal parameters foreach ($assoc as $k => $v) { $k = str_replace($disallow, "_", $k); $body[] = implode("\r\n", array( "Content-Disposition: form-data; name=\"{$k}\"", "", filter_var($v), )); } // build file parameters foreach ($files as $k => $v) { switch (true) { case false === $v = realpath(filter_var($v)): case !is_file($v): case !is_readable($v): continue; // or return false, throw new InvalidArgumentException } $data = file_get_contents($v); $v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v)); list($k, $v) = str_replace($disallow, "_", array($k, $v)); $body[] = implode("\r\n", array( "Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"", "Content-Type: application/octet-stream", "", $data, )); } // generate safe boundary do { $boundary = "---------------------" . md5(mt_rand() . microtime()); } while (preg_grep("/{$boundary}/", $body)); // add boundary for each parameters array_walk($body, function (&$part) use ($boundary) { $part = "--{$boundary}\r\n{$part}"; }); // add final boundary $body[] = "--{$boundary}--"; $body[] = ""; // set options return curl_setopt_array($ch, array( CURLOPT_POST => true, CURLOPT_POSTFIELDS => implode("\r\n", $body), CURLOPT_HTTPHEADER => array( "Expect: 100-continue", "Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type ), )); } ?>
@ Ответ PatricDaryll верен, но мне нужно было сделать несколько исследований, чтобы понять, где использовать эту функцию http_build_query .
Чтобы уточнить и обобщить, вместо того, чтобы делать:
curl_setopt($ch, CURLOPT_POSTFIELDS, $array);
Вы будете использовать:
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array));
Простой, но сбивающий с толку … завиток достаточно умен, чтобы понять, дали ли вы ему строку или массив.
Чтобы избежать появления знака @ в данных, отличных от файла, вам необходимо сделать следующее. Подготовьте текстовую строку символом NULL
$postfields = array( 'upload_file' => '@file_to_upload.png', 'upload_text' => sprintf("\0%s", '@text_to_upload') ); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'http://example.com/upload-test'); curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields); curl_exec($curl); curl_close($curl);