CURLOPT_POSTFIELDS сломал мой моск!

bugargen

Местный житель
Регистрация
24 Апр 2008
Сообщения
234
Реакции
20
Почему этот код не работает:
PHP:
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, http_build_query ( array
        (
            '__VIEWSTATE' => '/wEPDwUKMTcyNjAyOTg3Mg9kFgICAQ9kFgRmDw8WAh4EVGV4dAUIRGVjZW1iZXJkZAIEDzwrAAsAZGRNeirC79BNdveVTXLn6ksGFliaAw==',
            '__EVENTVALIDATION' => '/wEWBQLE8OOoCgKagaDZAgKuyd61DAK+sdPcCALCi9reAyU2ln31VgW5dbKcpzILrNVZXPDU',
            'ddlShowEstimate' => "Don't show estimates",
            'txtKeyword' => 'kakoito keyword',
            'btnSubmit' => 'Submit'
        ) ) );
Хотя, если полученную через http_build_query строку вставить непосредственно, т.е.:
PHP:
curl_setopt ( $ch, CURLOPT_POSTFIELDS, '__VIEWSTATE=%2FwEPDwUKMTcyNjAyOTg3Mg9kFgICAQ9kFgRmDw8WAh4EVGV4dAUIRGVjZW1iZXJkZAIEDzwrAAsAZGRNeirC79BNdveVTXLn6ksGFliaAw%3D%3D&__EVENTVALIDATION=%2FwEWBQLE8OOoCgKagaDZAgKuyd61DAK%2BsdPcCALCi9reAyU2ln31VgW5dbKcpzILrNVZXPDU&ddlShowEstimate=Don%27t+show+estimates&txtKeyword=kakoito+keyword&btnSubmit=Submit' );
то всё работает.

PS: Если из первого примера убрать использование http_build_query, то тоже всё работает, но ОООЧЕНЬ медленно.
 
Если именно в таком порядке строки = то хз.
Попробуй вынести http_build_query
PHP:
curl_setopt ( $ch, CURLOPT_POST);
$FF = http_build_query ( array
        (
            '__VIEWSTATE' => '/wEPDwUKMTcyNjAyOTg3Mg9kFgICAQ9kFgRmDw8WAh4EVGV4dAUIRGVjZW1iZXJkZAIEDzwrAAsAZGRNeirC79BNdveVTXLn6ksGFliaAw==',
            '__EVENTVALIDATION' => '/wEWBQLE8OOoCgKagaDZAgKuyd61DAK+sdPcCALCi9reAyU2ln31VgW5dbKcpzILrNVZXPDU',
            'ddlShowEstimate' => "Don't show estimates",
            'txtKeyword' => 'kakoito keyword',
            'btnSubmit' => 'Submit'
        ) );
 curl_setopt ( $ch, CURLOPT_POSTFIELDS, $FF );
 
Если именно в таком порядке строки = то хз.
Попробуй вынести http_build_query
Пробовал - не работает.

Т.е. смотрите, что получается..
Если получить результат http_build_query непосредственно в CURLOPT_POSTFIELDS или в переменную, то это не работает. А если этот результат вывести на экран, скопировать эту строку и, опять же, вставить в CURLOPT_POSTFIELDS или в переменную - то всё работает! НУ НЕ БРЕД???
Ведь одна и таже строка генерируется, хоть в переменную, хоть на экран. Разве не так?
 
Не советую использовать http_build_query(), ибо были замечены косяки при обработки этой функцией, пришлось отказаться от использования. Точно что за косяк был вспомнить не могу, но что то связанное с символом &, толи не проставился или наоборот был проставлен, в общем если вдруг вспомню отпишусь в теме что да как.

Сам использую следующую функцию, нареканий пока не было:

PHP:
	function genQueryGet($d = false, $s = '&') {
		if(is_array($d)){
			$r = '';
			foreach ($d as $k => $v) {
				$r = $r.$k.'='.$v.$s;
			}
			$r = substr($r, 0, -1);
			return $r;
		}else{
			return false;
		}
	}

Так же проверти кодировку отправляемых данных в этом иногда также кроиться причина не работоспособности и многих косяков.
 
trool
И функцию я такую создавал и использовал уже, ничерта не работает :) Дело в чём-то другом.
 
Возможно, что косяк с УРЛенкодингом, попробуй заменить -
PHP:
'__VIEWSTATE' => '/wEPDwUKMTcyNjAyOTg3Mg9kFgICAQ9kFgRmDw8WAh4EVGV4dAUIRGVjZW1iZXJkZAIEDzwrAAsAZGRNeirC79BNdveVTXLn6ksGFliaAw==',
            '__EVENTVALIDATION' => '/wEWBQLE8OOoCgKagaDZAgKuyd61DAK+sdPcCALCi9reAyU2ln31VgW5dbKcpzILrNVZXPDU',

на -

PHP:
'__VIEWSTATE' => '%2FwEPDwUKMTcyNjAyOTg3Mg9kFgICAQ9kFgRmDw8WAh4EVGV4dAUIRGVjZW1iZXJkZAIEDzwrAAsAZGRNeirC79BNdveVTXLn6ksGFliaAw%3D%3D',
            '__EVENTVALIDATION' => '%2FwEWBQLE8OOoCgKagaDZAgKuyd61DAK%2BsdPcCALCi9reAyU2ln31VgW5dbKcpzILrNVZXPDU',

ну и так далее...
 
отдельные символы http_build_query переводит в html формат:

PHP:
$post = html_entity_decode(http_build_query(array(
            '__VIEWSTATE' => '/wEPDwUKMTcyNjAyOTg3Mg9kFgICAQ9kFgRmDw8WAh4EVGV4dAUIRGVjZW1iZXJkZAIEDzwrAAsAZGRNeirC79BNdveVTXLn6ksGFliaAw==',
            '__EVENTVALIDATION' => '/wEWBQLE8OOoCgKagaDZAgKuyd61DAK+sdPcCALCi9reAyU2ln31VgW5dbKcpzILrNVZXPDU',
            'ddlShowEstimate' => "Don't show estimates",
            'txtKeyword' => 'kakoito keyword',
            'btnSubmit' => 'Submit'
        )));

curl_setopt($ch, CURLOPT_POSTFIELDS,$post);

но оптимальный вариант - прямое указание массива
PHP:
curl_setopt ($ch,CURLOPT_POSTFIELDS,$array);
 
steel_HILL
Так html_build_query итак сам прекрасно декодирует эти значения к такому виду. Это легко проверить, если вывести сформированную строку запроса на экран. Но почему-то эта строка замечательно и правильно выглядит на экране, но в POSTFIELD передаётся неверно. Хотя если её скопировать с экрана, вставить в кавычках (т.е. - как и любую другую строку) в POSTFIELD, то всё замечательно срабатывает.

Я уж устал это объяснять :)

ЗЫ: Все данные, кроме кнопки сабмит и ещё одного поля - динамичны, т.е. - изменяются постоянно.

Добавлено через 16 минут
pitkina
Этот вариант работает ровно столько же медленно, сколько и прямое указание массива.

Я бы и успокоился на прямом указании массива (что с самого начала и сделал:(
PHP:
curl_setopt ( $ch, CURLOPT_POSTFIELDS, array
        (
            '__VIEWSTATE' => '/wEPDwUKMTcyNjAyOTg3Mg9kFgICAQ9kFgRmDw8WAh4EVGV4dAUIRGVjZW1iZXJkZAIEDzwrAAsAZGRNeirC79BNdveVTXLn6ksGFliaAw==',
            '__EVENTVALIDATION' => '/wEWBQLE8OOoCgKagaDZAgKuyd61DAK+sdPcCALCi9reAyU2ln31VgW5dbKcpzILrNVZXPDU',
            'ddlShowEstimate' => "Don't show estimates",
            'txtKeyword' => 'kakoito keyword',
            'btnSubmit' => 'Submit'
        ) );
но ведь медленно, сволочь, работает! Это незаметно, когда цикл в один проход, а когда этот запрос выполняется 5, 10, 100 раз - тормоза колоссальные, нежели бы я просто методом GET отправил: Для просмотра ссылки Войди или Зарегистрируйся. И ладно бы это было из-за самого, КАК ТАКОВОГО, метода POST, так ведь когда я делаю тоже самое, но сам, через форму сайта в браузере - запрос и ответ выполняются молниеносно. Как так? Браузер же тоже данные кодирует перед отправкой, но тормозов таких нет.
 
так ведь когда я делаю тоже самое, но сам, через форму сайта в браузере - запрос и ответ выполняются молниеносно. Как так? Браузер же тоже данные кодирует перед отправкой, но тормозов таких нет.

Ну как бы, сравнивать скомпилированый браузер с PHP-интерпретатором не совсем корректно...
Для просмотра ссылки Войди или Зарегистрируйся
Хотя сомневаюсь, что он летать будет, ведь при мульти-поточной работе в первую очередь все зависит от твоего провайдера...
 
Ну как бы, сравнивать скомпилированый браузер с PHP-интерпретатором не совсем корректно...
Да я бы и забил на это дело уже давно и юзал бы на 100% работающий вариант без всяких http_build_query:
PHP:
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, array
        (
            '__VIEWSTATE' => '/wEPDwUKMTcyNjAyOTg3Mg9kFgICAQ9kFgRmDw8WAh4EVGV4dAUIRGVjZW1iZXJkZAIEDzwrAAsAZGRNeirC79BNdveVTXLn6ksGFliaAw==',
            '__EVENTVALIDATION' => '/wEWBQLE8OOoCgKagaDZAgKuyd61DAK+sdPcCALCi9reAyU2ln31VgW5dbKcpzILrNVZXPDU',
            'ddlShowEstimate' => "Don't show estimates",
            'txtKeyword' => 'kakoito keyword',
            'btnSubmit' => 'Submit'
        ) );
если бы не следующий момент...

Сравним два варианта, на примере отправки капчи..

PHP:
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, array
        (
            'recaptcha_challenge_field' => 'тра-ля-ля',
            'recaptcha_response_field' => 'тру-лю-лю',
            'submit' => "I'm a human"
        ) );
и

PHP:
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, http_build_query ( array
        (
            'recaptcha_challenge_field' => 'тра-ля-ля',
            'recaptcha_response_field' => 'тру-лю-лю',
            'submit' => "I'm a human"
        ) ) );
Теперь взглянем на starttransfer_time из curl_getinfo:
- в первом варианте это 2.015;
- во втором варианте это 0.125.

Разница очевидна. http_buil_query жжёт по скорости просто нипадецки, т.е. свой хлеб ест не зря. Но, сцуко, в моём случае - он отказывается правильно отрабатывать. Всё дело в этих грёбанных полях грёбанного ASPX (__VIEWSTATE и __EVENTVALIDATION) походу.

Из всего вышесказанного делаем выводы:
1. http_build_query очень сильно ускоряет обработку данных в CURLOPT_POSTFIELDS.
2. Если позволить CURLOPT_POSTFIELDS самому собирать и кодировать массив (т.е. отказаться от http_build_query) - то процесс этот сильно замедляется.
3. При попытке применения к данным функции urlencode - результат столь же плачевный, что и во втором пункте (это если кто схитрить захочет).
 
Назад
Сверху