Комментарии 71
Статья хороша, правда возникает такое ощущение, что код выхвачен как-то случайно. Раз уж выкладывать пример, дак такой, где и модули есть оставшиеся, и тег ?> закрыт. А в целом все позитивно :)
-2
Да, и еще неплохо запрос формировать через http_build_query, но это уже мелочи. Спасибо за статью
-1
НЛО прилетело и опубликовало эту надпись здесь
Если закрывать ?> потом будешь искать кто в хедер данные шлет до тебя )) очень часты запар. Так что лучше не закрывать…
+9
Даже разработчики Zend Framework не рекомендуют закрывать тег ?>
+5
Неоднократно сталкивался с подобными задачами, однако, помимо банального POST'а часто еще нужно отправить и Cookie, или вообще файл. А вообще, имхо, CURL, а уж тем более сокеты гораздо лучше в плане того, что позволяют разобраться лучше в принципах работы HTTP-протокола, ну и естественно имеют значительно больше возможностей.
+7
Это просто еще один удобный инструмент.
+1
Cookie отправить элементарно — просто указывается ещё один заголовок. С файлом проблемы, я хорошего способа не знаю, кроме как сделать всё руками.
0
Совершенно верно.
Плюс еще модифицировать user-agent или referer, поэтому имхо я считаю, правильным то, что универсальное.
«Своим» file_get_contents вы возьмете контент только на 50% сайтов, что недопустимо мало.
Через сокеты 99%, что закончится успехом.
«Это» нельзя даже предлагать как одно из решений.
Работа через file_get_contents с удаленными данными — это Зло.
Да и вообще, почаще заглядывайте на php.net, чтобы не писать такие топики ;)
Имхо я пользуюсь сокетами, это более универсальное решение.
Плюс еще модифицировать user-agent или referer, поэтому имхо я считаю, правильным то, что универсальное.
«Своим» file_get_contents вы возьмете контент только на 50% сайтов, что недопустимо мало.
Через сокеты 99%, что закончится успехом.
«Это» нельзя даже предлагать как одно из решений.
Работа через file_get_contents с удаленными данными — это Зло.
Да и вообще, почаще заглядывайте на php.net, чтобы не писать такие топики ;)
Имхо я пользуюсь сокетами, это более универсальное решение.
+3
НЛО прилетело и опубликовало эту надпись здесь
решение работает только на серверах с fopen = true, и с PHP >= 5. в совокупности таких около 40%
поэтому для универсальных решений используют curl.
поэтому для универсальных решений используют curl.
+2
Есть только одно оправдание разработчику не использующему curl — массовый дешевый коммерческий продукт, который реально инсталлируют тысячи на всевозможных кривущих хостингах. Вы именно такой пишите?
0
имхо всё совсем наоборот. универсальное массовое решение должно как минимум год-два поддерживать версию PHP 4.x. увы, дешевые hosting провайдеры очень медленно переходят на пятёрку.
-1
>>Чтобы получить содержимое веб-страницы все с удовольствием используют file_get_contents()
наглая ложь :) cURL для того и сделан, чтобы было легче жить, все что нужно уже сделано, cookies например.
ps: я не против концепции ооп, но когда вы даете пример примитивной операции — не нужно его заворачивать в свои лишние методы — это напрягает, приходится бегать глазами и вытаскивать строчки. Донесите до читателя смысл 3-4мя строчками вместо класса и пары инклюдов, а он уже сам решит где и как у себя это применить(ведь маловероятно, что он начнет применять ваш класс у себя).
Тяжело читать статьи, когда код большой и совершенно не адаптирован для быстрого восприятия.
RTFM данный вами в тысячу раз понятнее — угадайте почему :)
наглая ложь :) cURL для того и сделан, чтобы было легче жить, все что нужно уже сделано, cookies например.
ps: я не против концепции ооп, но когда вы даете пример примитивной операции — не нужно его заворачивать в свои лишние методы — это напрягает, приходится бегать глазами и вытаскивать строчки. Донесите до читателя смысл 3-4мя строчками вместо класса и пары инклюдов, а он уже сам решит где и как у себя это применить(ведь маловероятно, что он начнет применять ваш класс у себя).
Тяжело читать статьи, когда код большой и совершенно не адаптирован для быстрого восприятия.
RTFM данный вами в тысячу раз понятнее — угадайте почему :)
+10
Как мне показалось, ничуть не проще курла. Тем более когда послдний знаешь :)
+4
быстрее имхо курлом это сделать, а может мне просто курлом привычнее… от этого и быстрее
-1
как-то вы странно тестируете код.
один из столпов модульного тестирование — изоляция. т.е. тесты не должны зависеть ни от чего снаружи. все действия по созданию рабочей среды должны производиться в фикстурах, а по воспроизведению тестовых прецедентов — в тестовых методах.
как-то так
один из столпов модульного тестирование — изоляция. т.е. тесты не должны зависеть ни от чего снаружи. все действия по созданию рабочей среды должны производиться в фикстурах, а по воспроизведению тестовых прецедентов — в тестовых методах.
как-то так
+2
как показала практика file_get_contents жутко тормознутый в сравнении с курлом
+1
Дабы не создавать отдельную тему… Есть замечание насчет file_get_contents…
По мануалу «It will use memory mapping techniques if supported by your OS to enhance performance. »
НО:
php -r '$data = file_get_contents("/media/STORAGE/Downloads/ubuntu-8.10-desktop-i386.iso");'
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 732774400 bytes) in Command line code on line 1
То есть он пытается весь файл загнать в оперативку и ни о каком memory mapping речи и нет…
Система Ubuntu 8.10 i686
Может mmap где-то отдельно включается или я не понимаю его сути? Может кто разъяснить?
По мануалу «It will use memory mapping techniques if supported by your OS to enhance performance. »
НО:
php -r '$data = file_get_contents("/media/STORAGE/Downloads/ubuntu-8.10-desktop-i386.iso");'
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 732774400 bytes) in Command line code on line 1
То есть он пытается весь файл загнать в оперативку и ни о каком memory mapping речи и нет…
Система Ubuntu 8.10 i686
Может mmap где-то отдельно включается или я не понимаю его сути? Может кто разъяснить?
+2
Все логично — вы же в переменную присваиваете, а вы, допустим, ехайте его?
0
чего с ним делать?
Нет, на первый взгляд все работает как обещано.
Файл хоть и помещается в общую виртуальную кучу php, на самом деле содержимое не обязательно в нее считывается. Это можно узнать запустив через strace. Вот я запустил:
…
open("/usr/lib/vmware/isoimages/linux.iso", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0444, st_size=34963456, ...}) = 0
_llseek(3, 0, [0], SEEK_CUR) = 0
fstat64(3, {st_mode=S_IFREG|0444, st_size=34963456, ...}) = 0
mmap2(NULL, 34963456, PROT_READ, MAP_SHARED, 3, 0) = 0xb5197000
mmap2(NULL, 35131392, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb3016000
munmap(0xb5197000, 34963456) = 0
close(3) = 0
…
Нет, на первый взгляд все работает как обещано.
Файл хоть и помещается в общую виртуальную кучу php, на самом деле содержимое не обязательно в нее считывается. Это можно узнать запустив через strace. Вот я запустил:
…
open("/usr/lib/vmware/isoimages/linux.iso", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0444, st_size=34963456, ...}) = 0
_llseek(3, 0, [0], SEEK_CUR) = 0
fstat64(3, {st_mode=S_IFREG|0444, st_size=34963456, ...}) = 0
mmap2(NULL, 34963456, PROT_READ, MAP_SHARED, 3, 0) = 0xb5197000
mmap2(NULL, 35131392, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb3016000
munmap(0xb5197000, 34963456) = 0
close(3) = 0
…
0
Это тоже было моей первой мыслью, но если пробовать без "$data =" — все совершенно тоже самое.
0
Конечно, file_get_contents запихивает все содержимое файла в оперативку. Для этого оно и было придумало — получить одной строкой все содержимое файла или url. Не нравится — самое первое, что приходит в голову: fopen, fread, fwrite, fclose. Они для подобных целей и были сделаны.
0
Вы не указали, что это доступно только начиная с 5.1.х
0
И еще, народ используется file_get_contents() из-за минимализма кода (в четверке использовали $var = implode("", file("/path/to/file")) и прочие конструкции), а если для отправки постом нужна такая оберкта, то, ИМХО, гораздо проще курл использовать… (да и возможностей в нем всяко больше)
-1
А я пользуюсь PEAR:HTTP_Request и очень доволен
Там все очень просто, разобратся можно очень быстро.
Вот пример:
<?php
require 'HTTP/Request.php'
$http = new HTTP_Request('http://habrahabr.ru');
$http->setMethod(HTTP_REQUEST_METHOD_POST);
$http->addPostData('test', 1);
$http->sendRequest();
$http->getResponseBody(); //тело ответа
$http->getResponseCode()
Там все очень просто, разобратся можно очень быстро.
Вот пример:
<?php
require 'HTTP/Request.php'
$http = new HTTP_Request('http://habrahabr.ru');
$http->setMethod(HTTP_REQUEST_METHOD_POST);
$http->addPostData('test', 1);
$http->sendRequest();
$http->getResponseBody(); //тело ответа
$http->getResponseCode()
0
Хабр заглючил — отправилось раньше
<?php
require 'HTTP/Request.php'
$http = new HTTP_Request('http://habrahabr.ru');
$http->setMethod(HTTP_REQUEST_METHOD_POST);
$http->addPostData('test', 1);
$http->sendRequest();
$http->getResponseBody(); //тело ответа
$http->getResponseCode(); //код ответа
$http->getResponseHeader(); //хидеры
$http->getResponseCookies(); //куки
<?php
require 'HTTP/Request.php'
$http = new HTTP_Request('http://habrahabr.ru');
$http->setMethod(HTTP_REQUEST_METHOD_POST);
$http->addPostData('test', 1);
$http->sendRequest();
$http->getResponseBody(); //тело ответа
$http->getResponseCode(); //код ответа
$http->getResponseHeader(); //хидеры
$http->getResponseCookies(); //куки
0
Зачем столько кода, показывать какой ты крутой умеешь писать под рнр5 паблики приваты… когда основная идея лежит в 3м параметре функции… про него и надо было просто написать.
На хабре люди не дураки, свой класс почти каждый в состоянии написать… а разбираться в чужом дело не сильно классное.
На хабре люди не дураки, свой класс почти каждый в состоянии написать… а разбираться в чужом дело не сильно классное.
+3
Сделал интересное открытие для себя этим контекстом. Но практичнее CURL в модуле, дабы подсунуть Referer, Cookies, etc.
0
PHP_EOL в конце заголовка (Content-Type) — дурь какая-то.
+2
Иногда возникает такое чувство, что разработчики PHP придерживаются некой догмы, согласно которой одно и тоже может быть реализовано как минимум 3-мя различными способами. Это конечно здорово, только не всегда понятно зачем это нужно.
Я думаю так, вот был раньше file_get_contents, внутри которого при обращении к url этот саный контекст создавался. И вот в новой версии разработчики решили — а зачем это мы будем генерить свой контекст, если можно сделать так, что б использовался внешний. Сказано сделано — ввели еще один не обязательный параметр. Т.е. наличие данной особенности не потому что она нужна, а потому что она легко реалтизуется. И может кому-нибудь пригодится. И все.
CURL-то конечно удобнее.
Я думаю так, вот был раньше file_get_contents, внутри которого при обращении к url этот саный контекст создавался. И вот в новой версии разработчики решили — а зачем это мы будем генерить свой контекст, если можно сделать так, что б использовался внешний. Сказано сделано — ввели еще один не обязательный параметр. Т.е. наличие данной особенности не потому что она нужна, а потому что она легко реалтизуется. И может кому-нибудь пригодится. И все.
CURL-то конечно удобнее.
+3
CURL в одну строчку контент не получишь, бывают моменты, когда нужно что то сделать быстро.
0
А вот это:
Одна строчка?
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded' . PHP_EOL,
'content' => QUERY,
),
));
// Отправить запрос на себя, чтобы запустить тесты
// и показать результат выполнения тестов
echo file_get_contents(
$file = "http://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}?runTests",
$use_include_path = false,
$context);
Одна строчка?
0
Прям 1000 и 1 способ собрать велосипед… :)
Мне всегда хватало libcurl для всевозможных HTTP запросов, к тому же он знает, что такое таймауты. Единственный только его минус — не умеет хранить куки в памяти, как например тот же libwww в Perl. Или может в данном направлении прогресс уже произошёл?
Мне всегда хватало libcurl для всевозможных HTTP запросов, к тому же он знает, что такое таймауты. Единственный только его минус — не умеет хранить куки в памяти, как например тот же libwww в Perl. Или может в данном направлении прогресс уже произошёл?
0
> к тому же он знает, что такое таймауты
docs.php.net/manual/ru/context.http.php — timeout там присутствует.
> не умеет хранить куки в памяти
это как? чтобы их каждый раз не указывать при запросе? не понял просто.
docs.php.net/manual/ru/context.http.php — timeout там присутствует.
> не умеет хранить куки в памяти
это как? чтобы их каждый раз не указывать при запросе? не понял просто.
0
В оригинале у libcurl поболее всяких таймаутов поддерживает, но не уверен что их все в PHP включили.
curl.haxx.se/libcurl/c/curl_easy_setopt.html
Да нет, с куки не всё так плохо, указывать вручную ничего не надо. :) Но храниться они могут только в текстовом файле, что зачастую в общем-то нафиг нужно.
curl.haxx.se/libcurl/c/curl_easy_setopt.html
Да нет, с куки не всё так плохо, указывать вручную ничего не надо. :) Но храниться они могут только в текстовом файле, что зачастую в общем-то нафиг нужно.
0
Как говорит один мой умный знакомый, можно и отвертку вместо молотка использовать, главное — бить сильно и метко.
+1
НЛО прилетело и опубликовало эту надпись здесь
блин, вот ведь лень до чего доводит! читать надо маны, читать.
спасибо автор.
спасибо автор.
0
Ёлки-палки! Два месяца использую PHP в подобном роде. Всё время рисовал свои грабли через сокеты. Вчера увидел про CURL, решил что буду гуглить его, и вот — зарегестрировался на хабре и прозрел, каким был идиотом.
Мануалы читать надо! :)
Автору гигантский респект за наставление на пусть истинный. Только что -1.2кб кода и +80 к читаемости. :)
Мануалы читать надо! :)
Автору гигантский респект за наставление на пусть истинный. Только что -1.2кб кода и +80 к читаемости. :)
+1
С версии 5.3.0 контекст принимает так же copy();
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Отправить POST через file_get_contents()