Curl не працює. CURL не працює з Apache. Функції зворотного дзвінка

Маємо: php 5.2.3, Windows XP, Apache 1.3.33
Проблема - не визначається модуль cURL, якщо PHP запускати з-під Apache
У php.ini extension=php_curl.dll розкоментований, extension_dir встановлений правильно,
libeay32.dll та ssleay32.dll скопійовані в c:\windows\system32.
Тим не менш, функція phpinfo() модуль cURL в числі встановлених не показує, і при запуску Апача в лог пишеться наступне:

PHP Startup: Неможливо завантажити dynamic library "c:/php/ext/php_curl.dll" - Не знайдено вказаний модуль.

Якщо запускати php з командного рядка, то скрипти, що містять команди з cURL, відпрацьовують нормально, а якщо запускати з-під Апача, то видають таке:
Fatal error: Call до undefined function: curl_init() - причому незалежно від цього, як поставлений PHP - як CGI чи як модуль.

В інеті неодноразово натикався на опис цієї проблеми - саме для модуля cURL, але способи вирішення, які там пропонувалися, не допомагають. Причому я вже змінив PHP 5.2 на PHP 5.2.3 – все одно не допомогло.

Давид Мзареулян
php.ini у мене один – перевірив пошуком по диску. Те, що використовується один і той же php.ini легко підтверджується також тим фактом, що зміни, що вносяться в нього, впливають як на запуск скриптів з-під Апача, так і з командного рядка.

Данило Іванов[досьє]Краще зробіть файл із викликом

та відкрийте його через браузер.
А потім запустіть у командному рядку php-i | grep ini та перевірте шляхи до php.ini у тому вигляді як їх бачить php, а не за наявністю файлу на диску.

Данило Іванов[досьє]А що видає php-i? За замовчуванням бінарник може шукати конфіг в іншому місці, залежно від параметрів компіляції. Вже не вперше я стикався з тим, що mod_php.dll і php.exe дивляться на різні файли і те, що працює в одному - не працює в іншому.

Василь Свиридов[досьє]
php -i видає таке:

Configuration File (php.ini) Path => C:\WINDOWS
Loaded Configuration File => C:\PHP\php.ini

Перенесення файлу php.ini до каталогу Windows ситуації не змінює.

Данило Іванов[досьє]
Як із рештою модулів? Наприклад, php_mysql??? Підключається? Чи це тільки cURL такий бридкий?

Хм, у мене теж не вантажиться... На зовсім іншій конфігурації (Апач 2.2 плюс РНР 5.1.6 під Зенд-студією). Але не в цьому суть. Експеримент із запуском Апача з командного рядка (точніше із FARа) показав цікаве. Без спроб підключити Курл – все пучком запускається. При спробі підключити Курл видає помилку... php5ts.dll.

Здрастуйте!
У мене виникла аналогічна проблема, довго шукав рішення, поставив більше нову версіюРНР у результаті знайшов цей форум. Рішення тут не було, тож пробував далі сам.

Я собі ставив зенд студію, і перед тим стояла більше рання версіяРНР. Можливо, хтось із них поставив свої бібліотеки, і вони там залишалися – застарілі.

Дякуємо за поради, особливо останній від "Nehxby". Я поліз у C:\windows\system32 і виявив, що бібліотеки libeay32.dll та ssleay32.dll не збігаються за розмірами, з оригінальними. Я встановлював мемкешед, можливо, після цього. Так, якщо ви чот додавали, в систем32 гоу:)

виникла така сама проблема, скористався командою php-i | grep ini
показала, що не вистачає бібліотеки zlib1.dll
у папці з апачем вона була, записав копію до папки з ПХП
повторив команду, показала не вистачає бібліотеки zlib.dll записав у папку з апачем і все запрацювало.
та ще всі бібліотеки теж були php5ts.dll у тому числі, так що враховуйте наявність усіх бібліотек необхідних.

Вирішив дописати. Оскільки теж зіштовхнувся із цією проблемою. На цей форум натрапив через посилання на іншому сайті. Загалом усі запропоновані варіанти не що інше як милиці. суть рішення у Windows. треба прописати змінну PATH. вказавши де у вас перебувати PHP. і алілуя curl помилок не видає. як і інші бібліотеки...

cURL - це спеціальний інструмент, який призначений для того, щоб передавати файли та дані синтаксисом URL. Дана технологіяпідтримує безліч протоколів, таких як HTTP, FTP, TELNET та багато інших. Спочатку cURL було розроблено для того, щоб бути інструментом командного рядка. На щастя, бібліотека cURL підтримується мовою програмування PHP. У цій статті ми розглянемо деякі розширені функції cURL, а також торкнемося практичного застосування отриманих знань засобами PHP.

Чому cURL?

Насправді існує чимало альтернативних способіввибірки змісту веб-сторінки. У багатьох випадках, головним чином через лінощі, я використав прості PHP функціїзамість cURL:

$content = file_get_contents("http://www.nettuts.com"); // або $lines=file("http://www.nettuts.com"); // або readfile("http://www.nettuts.com");

Однак ці функції не мають практично ніякої гнучкості і містять величезну кількість недоліків у тому, що стосується обробки помилок і т.д. Крім того, існують певні завдання, які ви просто не можете вирішити завдяки цим стандартним функціям: взаємодія з cookie, автентифікація, надсилання форми, завантаження файлів тощо.

cURL - це потужна бібліотека, яка підтримує безліч різних протоколів, опцій та забезпечує детальну інформаціюпро URL запити.

Базова структура

  • Ініціалізація
  • Призначення параметрів
  • Виконання та вибірка результату
  • Звільнення пам'яті

// 1. ініціалізація $ch = curl_init(); // 2. вказуємо параметри, включаючи url curl_setopt ($ ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. отримуємо HTML як результат $output = curl_exec($ch); // 4. закриваємо з'єднання curl_close ($ ch);

Крок #2 (тобто, виклик curl_setopt()) обговорюватимемо у цій статті набагато більше, ніж інші етапи, т.к. на цій стадії відбувається все найцікавіше та корисне, що вам необхідно знати. У cURL існує величезна кількість різних опцій, які повинні бути вказані, щоб мати можливість налаштувати URL-запит найретельніше. Ми не розглядатимемо весь список повністю, а зупинимося тільки на тому, що я вважаю за потрібне і корисне для цього уроку. Решту ви зможете вивчити самі, якщо ця тема вас зацікавить.

Перевірка Помилки

Крім того, ви також можете використовувати умовні операторидля перевірки виконання операції на успіх:

// ... $output = curl_exec ($ ch); if ($output === FALSE) ( echo "cURL Error: " . curl_error($ch); ) // ...

Тут прошу відзначити собі дуже важливий момент: ми маємо використовувати “=== false” для порівняння, замість “== false”. Для тих, хто не в курсі, це допоможе нам відрізняти порожній результат від булевого значення false, яке буде вказувати на помилку.

Отримання інформації

Ще одним додатковим кроком є ​​отримання даних про запит cURL, після того, як він був виконаний.

// ... curl_exec ($ ch); $info = curl_getinfo($ch); echo "Took". $info["total_time"] . "seconds for url". $info["url"]; // …

Повертається масив містить таку інформацію:

  • "url"
  • "content_type"
  • "http_code"
  • "header_size"
  • "request_size"
  • "filetime"
  • "ssl_verify_result"
  • "redirect_count"
  • "total_time"
  • "namelookup_time"
  • "connect_time"
  • "pretransfer_time"
  • "size_upload"
  • "size_download"
  • "speed_download"
  • "speed_upload"
  • "download_content_length"
  • "upload_content_length"
  • "starttransfer_time"
  • "redirect_time"

Виявлення перенаправлення залежно від браузера

У цьому першому прикладі ми напишемо код, який зможе виявити перенаправлення URL, що базуються на різних налаштуваннях браузера. Наприклад, деякі веб-сайти перенаправляють браузери стільникового телефону, або будь-якого іншого пристрою.

Ми збираємося використовувати опцію CURLOPT_HTTPHEADER для того, щоб визначити наші вихідні заголовки HTTP, включаючи назву браузера користувача та доступні мови. Зрештою, ми зможемо визначити, які сайти перенаправляють нас до різних URL-адрес.

// Тестуємо URL $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // тестуємо браузери $browsers = array("standard" => array ("user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6)) Gecko/20091201 Firefox/3.5 .6 (.NET CLR 3.5.30729)", "language" => "en-us,en;q=0.5"), "iphone" => array ("user_agent" => "Mozilla/5.0 (iPhone; U ; CPU як Mac OS X; => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", "language" => "fr,fr-FR;q=0.5")); foreach ($urls as $url) ( echo "URL: $url\n"; foreach ($browsers as $test_name => $browser) ( $ch = curl_init(); // вказуємо url curl_setopt($ch, CURLOPT_URL, $url); // вказуємо заголовки для браузера curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: ($browser["user_agent"])", "Accept-Language: ($browser["language"])" ));// нам не потрібно зміст сторінки curl_setopt($ch, CURLOPT_NOBODY, 1);// нам необхідно отримати HTTP заголовки curl_setopt($ch, CURLOPT_HEADER, 1);// повертаємо результати замість виведення curl_setopt($ch, CURLOPT_RETURRAN 1); $output = curl_exec($ch); curl_close($ch);// Чи був HTTP редирект? $test_name: redirects to $matches\n"; ) else ( echo "$test_name: no redirection\n"; ) ) echo "\n\n"; )

Спочатку ми вказуємо список URL сайтів, які перевірятимемо. Точніше нам знадобляться адреси даних сайтів. Далі нам необхідно визначити налаштування браузера, щоб протестувати кожен із цих URL. Після цього ми скористаємося циклом, у якому пробіжимося по всіх отриманих результатах.

Прийом, який ми використовуємо в цьому прикладі для того, щоб задати налаштування cURL, дозволить нам отримати не зміст сторінки, а лише заголовки HTTP (збережені в $output). Далі, скориставшись простим regex, ми можемо визначити, чи був рядок “Location:” в отриманих заголовках.

Коли ви запустите даний код, то повинні будете отримати приблизно наступний результат:

Створення запиту POST на певну URL

При формуванні GET запиту дані можуть бути передані на URL через “рядок запиту”. Наприклад, коли ви робите пошук у Google, критерій пошуку розміщуються в адресному рядку нового URL:

Http://www.google.com/search?q=ruseller

Для того, щоб зімітувати даний запитВам не потрібно користуватися засобами cURL. Якщо ліньки вас долає остаточно, скористайтеся функцією “file_get_contents()”, щоб отримати результат.

Але річ у тому, що деякі HTML-форми надсилають запити POST. Дані цих форм транспортуються через тіло HTTP запиту, а не як у попередньому випадку. Наприклад, якщо ви заповнили форму на форумі і натиснули на кнопку пошуку, то швидше за все буде здійснено запит POST:

http://codeigniter.com/forums/do_search/

Ми можемо написати PHP скрипт, який може зімітувати цей вид URL-адреси запиту. Спочатку давайте створимо простий файл для прийняття та відображення POST даних. Назвемо його post_output.php:

Print_r($_POST);

Потім ми створюємо PHP скрипт, щоб виконати cURL запит:

$url = "http://localhost/post_output.php"; $post_data = array ("foo" => "bar", "query" => "Nettuts", "action" => "Submit"); $ ch = curl_init (); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1); // вказуємо, що POST запит curl_setopt($ch, CURLOPT_POST, 1); // додаємо змінні curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output;

При запуску даного скрипта ви повинні отримати такий результат:

Таким чином, POST запит був відправлений скрипту post_output.php, який у свою чергу вивів суперглобальний масив $_POST, зміст якого ми отримали за допомогою cURL.

завантаження файлу

Спочатку давайте створимо файл для того, щоб сформувати його та надіслати файлу upload_output.php:

Print_r($_FILES);

А ось і код скрипту, який виконує вказаний вище функціонал:

$url = "http://localhost/upload_output.php"; $post_data = array ("foo" => "bar", // файл, який необхідно завантажити "upload" => "@C:/wamp/www/test.zip"); $ ch = curl_init (); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output;

Коли ви хочете завантажити файл, все, що вам потрібно зробити, так це передати його як звичайну post-зміну, попередньо помістивши перед нею символ @. При запуску написаного скрипту ви отримаєте наступний результат:

Множинний cURL

Однією з найсильніших сторін CURL є можливість створення "множинних" CURL обробників. Це дозволяє вам відкривати з'єднання до множини URL одночасно і асинхронно.

У класичному варіанті cURL запиту виконання скрипта припиняється, і відбувається очікування завершення операції URL-адреси запиту, після чого робота скрипта може продовжитися. Якщо ви маєте намір взаємодіяти з безліччю URL, це призведе до досить-таки значних витрат часу, оскільки в класичному варіанті ви можете працювати тільки з одним URL за один раз. Проте, ми можемо виправити цю ситуацію, скориставшись спеціальними обробниками.

Давайте розглянемо приклад коду, який я взяв із php.net:

// створюємо кілька ресурсів cURL $ch1 = curl_init(); $ ch2 = curl_init (); // вказуємо URL та інші параметри curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); curl_setopt($ch2, CURLOPT_HEADER, 0); //створюємо множинний cURL обробник $mh = curl_multi_init(); //додаємо кілька обробників curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $active = null; //виконання do ( $mrc ​​= curl_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc ​​== CURLM_OK) ( if (curl_multi_select($mh) != -1) ( do ( $mrc ​​= curl_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); ) ) //закриття curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Ідея полягає в тому, що ви можете використовувати множинні cURL обробники. Використовуючи простий цикл, можна відстежити, які запити ще не виконалися.

У цьому прикладі є два основні цикли. Перший цикл do-while викликає функцію curl_multi_exec(). Ця функція не блокується. Вона виконується з швидкістю, з якою може, і повертає стан запиту. Поки повернене значення є константою 'CURLM_CALL_MULTI_PERFORM', це означає, що робота ще не завершена (наприклад, зараз відбувається відправка http заголовківв URL); Саме тому ми продовжуємо перевіряти це значення, що повертається, поки не отримаємо інший результат.

У наступному циклі ми перевіряємо умову, доки змінна $active = "true". Це другий параметр для функції curl_multi_exec(). Значення даної змінної дорівнюватиме "true", доки якесь із існуючих змін є активним. Далі ми викликаємо функцію curl_multi_select(). Її виконання "блокується", доки існує хоч одне активне з'єднання, доки не буде отримано відповідь. Коли це станеться, ми повертаємося до основного циклу, щоб продовжити виконання запитів.

А тепер давайте застосуємо отримані знання на прикладі, який буде реально корисним для великої кількості людей.

Перевіряємо посилання на WordPress

Уявіть собі блог із величезною кількістю постів та повідомлень, у кожному з яких є посилання на зовнішні інтернет ресурси. Деякі з цих посилань з різних причин могли б бути «мертвими». Можливо, сторінку було видалено або сайт зовсім не працює.

Ми збираємося створити скрипт, який проаналізує всі посилання і знайде веб-сайти і сторінки 404, що не завантажуються, після чого надасть нам докладний звіт.

Відразу скажу, що це не приклад створення плагіна для WordPress. Це всього лише хороший полігон для наших випробувань.

Давайте нарешті почнемо. Спочатку ми повинні зробити вибірку всіх посилань із бази даних:

// Конфігурація $db_host = "localhost"; $ db_user = "root"; $db_pass = ""; $ db_name = "wordpress"; $excluded_domains = array("localhost", "www.mydomain.com"); $max_connections = 10; // ініціалізація змінних $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $active = null; // підключаємося до MySQL if (!mysql_connect($db_host, $db_user, $db_pass)) ( die("Could not connect: " not select db: " . mysql_error()); ) // вибираємо всі опубліковані пости, де є посилання $q = "SELECT post_content FROM wp_posts WHERE post_content LIKE "%href=%" AND post_status = "publish" AND post_type = "post ""; $r = mysql_query($q) або die(mysql_error()); while ($d = mysql_fetch_assoc($r)) ( // робимо вибірку посилань за допомогою регулярних виразів if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $matches)) ( foreach ($matches as $url) ( $tmp = parse_url($url) if (in_array($tmp["host"], $excluded_domains)) ( continue; ) $url_list = $url; ) ) ) // прибираємо дублікати $url_list = array_values(array_unique($url_list)); if (!$url_list) ( die("No URL to check"); )

Спочатку ми формуємо конфігураційні дані для взаємодії з базою даних, далі пишемо список доменів, які братимуть участь у перевірці ($excluded_domains). Також ми визначаємо число, яке характеризує кількість максимальних одночасних з'єднань, які ми будемо використовувати у нашому скрипті ($max_connections). Потім ми приєднуємося до бази даних, вибираємо пости, які містять посилання, та накопичуємо їх у масив ($url_list).

Наступний код трохи складний, так що розберіться в ньому від початку до кінця:

// 1. множинний обробник $ mh = curl_multi_init (); // 2. додаємо безліч URL for ($i = 0; $i< $max_connections; $i++) { add_url_to_multi_handle($mh, $url_list); } // 3. инициализация выполнения do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 4. основной цикл while ($active && $mrc == CURLM_OK) { // 5. если всё прошло успешно if (curl_multi_select($mh) != -1) { // 6. делаем дело do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 7. если есть инфа? if ($mhinfo = curl_multi_info_read($mh)) { // это значит, что запрос завершился // 8. извлекаем инфу $chinfo = curl_getinfo($mhinfo["handle"]); // 9. мёртвая ссылка? if (!$chinfo["http_code"]) { $dead_urls = $chinfo["url"]; // 10. 404? } else if ($chinfo["http_code"] == 404) { $not_found_urls = $chinfo["url"]; // 11. рабочая } else { $working_urls = $chinfo["url"]; } // 12. чистим за собой curl_multi_remove_handle($mh, $mhinfo["handle"]); // в случае зацикливания, закомментируйте данный вызов curl_close($mhinfo["handle"]); // 13. добавляем новый url и продолжаем работу if (add_url_to_multi_handle($mh, $url_list)) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } } } // 14. завершение curl_multi_close($mh); echo "==Dead URLs==\n"; echo implode("\n",$dead_urls) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n",$not_found_urls) . "\n\n"; echo "==Working URLs==\n"; echo implode("\n",$working_urls); function add_url_to_multi_handle($mh, $url_list) { static $index = 0; // если у нас есть ещё url, которые нужно достать if ($url_list[$index]) { // новый curl обработчик $ch = curl_init(); // указываем url curl_setopt($ch, CURLOPT_URL, $url_list[$index]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_multi_add_handle($mh, $ch); // переходим на следующий url $index++; return true; } else { // добавление новых URL завершено return false; } }

Тут я спробую викласти все по поличках. Числа у списку відповідають числам у коментарі.

  1. 1. Створюємо множинний обробник;
  2. 2. Функцію add_url_to_multi_handle() ми напишемо трохи згодом. Щоразу, коли вона буде викликатися, почнеться обробка нового URL. Спочатку ми додаємо 10 ($max_connections) URL;
  3. 3. Щоб розпочати роботу, ми повинні запустити функцію curl_multi_exec(). Доки вона повертатиме CURLM_CALL_MULTI_PERFORM, нам ще є, що робити. Це нам потрібно головним чином для того, щоб створити з'єднання;
  4. 4. Далі слідує основний цикл, який буде виконуватися доти, доки ми маємо хоч одне активне з'єднання;
  5. 5. curl_multi_select() зависає в очікуванні, доки пошук URL не завершиться;
  6. 6. І знову ми повинні змусити cURL виконати деяку роботу, а саме, зробити вибірку даних відповіді, що повертається;
  7. 7. Тут відбувається перевірка інформації. В результаті виконання запиту буде повернено масив;
  8. 8. У поверненому масиві присутній cURL обробник. Його ми і будемо використовувати для того, щоб вибрати інформацію про окремий запит cURL;
  9. 9. Якщо посилання було мертвим, або час виконання скрипту вийшов, то нам не слід шукати жодного http коду;
  10. 10. Якщо посилання повернуло нам сторінку 404, то http код міститиме значення 404;
  11. 11. Інакше перед нами знаходиться робоче посилання. (Ви можете додати додаткові перевірки на код помилки 500 тощо);
  12. 12. Далі ми видаляємо cURL обробник, тому що більше його не потребуємо;
  13. 13. Тепер ми можемо додати інший url і запустити все те, що говорили до цього;
  14. 14. На цьому етапі скрипт завершує свою роботу. Ми можемо видалити все, що нам не потрібно, і сформувати звіт;
  15. 15. Зрештою, напишемо функцію, яка додаватиме url в обробник. Статична змінна $index збільшуватиметься щоразу, коли дана функціябуде викликано.

Я використав цей скрипт на своєму блозі (з деякими непрацюючими посиланнями, які додав спеціально для того, щоб протестувати його роботу) і отримав наступний результат:

У моєму випадку, скрипту потрібно трохи менше 2 секунд, щоб пробігтися по 40 URL. Збільшення продуктивності є суттєвим при роботі з ще більшою кількістю URL-адрес. Якщо ви відкриваєте десять з'єднань одночасно, то скрипт може виконатися у десять разів швидше.

Пару слів про інші корисні опції cURL

HTTP Аутентифікація

Якщо на URL адресі є HTTP автентифікація, то ви легко можете скористатися наступним скриптом:

$url = "http://www.somesite.com/members/"; $ ch = curl_init (); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1); // вказуємо ім'я та пароль curl_setopt($ch, CURLOPT_USERPWD, "myusername: mypassword"); // якщо перенаправлення дозволено curl_setopt ($ ch, CURLOPT_FOLLOWLOCATION, 1); // то збережемо наші дані в cURL curl_setopt ($ ch, CURLOPT_UNRESTRICTED_AUTH, 1); $output = curl_exec($ch); curl_close($ch);

FTP завантаження

У PHP також існує бібліотека для роботи з FTP, але вам нічого не заважає і скористатися засобами cURL:

// відкриваємо файл $file = fopen("/path/to/file", "r"); // в url має бути наступний зміст $url = "ftp://username: [email protected]:21/path/to/new/file"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_UPLO curl_setopt($ch, CURLOPT_INFILE, $fp); curl_setopt($ch, CURLOPT_INFILESIZE, filesize("/path/to/file")); // вказівкам ASCII мод ($ch);curl_close($ch);

Використовуємо Проксі

Ви можете виконати свій URL запит через проксі:

$ ch = curl_init (); curl_setopt($ch, CURLOPT_URL, "http://www.example.com"); curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1); // вказуємо адресу curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // якщо необхідно надати ім'я користувача та пароль curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $output = curl_exec($ch); curl_close ($ ch);

Функції зворотного дзвінка

Також існує можливість вказати функцію, яка спрацьовуватиме ще до завершення роботи cURL запиту. Наприклад, поки вміст відповіді завантажується, ви можете почати використовувати дані, не чекаючи повного завантаження.

$ ch = curl_init (); curl_setopt($ch, CURLOPT_URL,"http://net.tutsplus.com"); curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function"); curl_exec($ch); curl_close ($ ch); function progress_function($ch,$str) ( echo $str; return strlen($str); )

Подібна функція ПОВИННА повертати довжину рядка, що є обов'язковою вимогою.

Висновок

Сьогодні ми познайомилися з тим, як можна застосувати бібліотеку cURL у своїх корисливих цілях. Я сподіваюся, що вам сподобалася ця стаття.

Спасибі! Вдалого дня!

Ті, хто використовує cURL після оновлень на 5.6.1, 5.5.17 зіткнулися з тим, що модуль cURL перестав працювати. Проблема з того часу не зникла. Навіть в останній на сьогодні версії PHP 5.6.4 ця проблема збереглася.

Як дізнатися, чи працює у вас CURL?

Створіть php файлі скопіюйте туди:

Відкрийте його із сервера. Якщо на виході щось на зразок:

Array ( => 468736 => 3 => 3997 => 0 => 7.39.0 => x86_64-pc-win32 => OpenSSL/1.0.1j => 1.2.7.3 => Array ( => dict => file => ftp => ftps => gopher => http => https => imap => imaps => ldap => pop3 => pop3s => rtsp => scp => sftp => smtp => smtps => telnet => tftp) )

Значить з cURL все гаразд, якщо натомість помилка PHP, значить проблема існує.

По-перше, звичайно перевірте файл php.ini, знайдіть там рядок

Extension=php_curl.dll

І переконайтеся, що перед нею не стоїть крапка з комою.

Якщо все так, а cURL не працює, можна провести ще один тест, для підтвердження незвичайності ситуації. Створіть ще один php файл із змістом:

Через пошук у браузері знайдіть cURL, якщо збіг всього один, значить модуль cURL не завантажений:

При цьому і Apache та PHP працюють як завжди.

Рішень три:

  1. Спосіб перший (не кошерний). Якщо у вас є PHP 5.6.*, то візьміть версію PHP 5.6.0, звідти візьміть старий файл php_curl.dll і замініть його замість вашого нового з версії, наприклад, PHP 5.6.4. Для тих, у кого PHP 5.5.17 і вище, потрібно взяти цей файл з PHP 5.5.16 і також його замінити. Проблема тут одна – знайти ці старі версії. Можна, звичайно, поколупатися в http://windows.php.net/downloads/snaps/php-5.6, але особисто я там не знайшов того, що мені потрібно. Та й саме рішення якесь не зовсім кошерне.
  2. Спосіб другий (дуже швидкий, але теж не кошерний). З каталогу PHP скопіювати файл libssh2.dll в каталог Apache24bin і перезапустити Apache.
  3. Спосіб третій (кошерний – кошерні люди аплодують стоячи). Потрібно додати вашу PHP директорію до PATH. Як це зробити дуже добре розписано в офіційній документації.

Перевіряємо:

Вуаля, розділ cURL на місці.

Чому так? Звідки взялася ця проблема? Відповіді це питання немає, хоча вже описаний механізм її виникнення.

Проблема пов'язана з тим, що 5.6.1 повинен був випущений з оновленим libcurl 7.38.0. Але це достеменно не відомо, автори PHP кивають на Apache, мовляв, це там якісь баги.

Механізм виникнення проблеми: якщо до системної PATH не включений каталог PHP, то коли служба Apache запускається, вона не здатна знайти новий dll (libssh2.dll), який є залежністю для php_curl.

Відповідні баг репорти:

Fatal error: Call для undefined function curl_multi_init() in …

Взагалі проблеми з cURL на PHP були, здається, якщо не завжди, то дуже часто. У процесі заглиблення своєї проблеми, я натикався на теми, деяким з яких було більше дюжини років.

Крім цього, гуглення дало ще кілька висновків:

В Інтернеті достатньо «інструкцій для дибілів», у яких докладно, з картинками, розповідають, як розкоментувати рядок extension=php_curl.dll у файлі php.ini.

На офіційному сайті PHP, в розділі по установці cURL, є лише дві пропозиції щодо системи Windows:

Для роботи з цим модулем у Windows файли libeay32.dll і ssleay32.dll повинні існувати в системному змінному оточенні PATH. Вам не потрібний файл libcurl.dll із сайту cURL.

Я прочитав їх десяток разів. Переключився на англійська моваі прочитав ще кілька разів англійською. Щоразу все більше переконуючись, що ці дві пропозиції написали тварини, або хтось просто пострибав попою на клавіатурі — я не розумію їхнього сенсу.

Ще є кілька якихось божевільних порад та інструкцій (деякі я навіть встиг випробувати).

На сайті баг репортів ПХП я вже підібрався до розгадки, що потрібно в системну змінну PATH включити каталог з PHP.

Загалом, для тих, у кого проблема з cURL і кому потрібно «в системну змінну PATH увімкнути каталог з PHP», перейдіть до вже названої інструкції http://php.net/manual/ru/faq.installation.php#faq .installation.addtopath . Там все просто, а головне, людською мовою написано, що потрібно зробити.

Жорсткі диски