PHP Curl Class: упрощеные HTTP-запросы
PHP Curl Class упрощает отправку HTTP-запросов и интеграцию с веб-API.
https://github.com/php-curl-class/php-curl-class
- Установка
- Требования
- Быстрый старт и примеры
- Доступные методы
- Безопасность
- Поиск проблем
- Запуск тестов
Установка
Чтобы установить класс PHP Curl, просто:
$ composer require php-curl-class/php-curl-class
Для последней версии фиксации:
$ composer require php-curl-class/php-curl-class @dev
Требования
PHP Curl Class работает с PHP 5.3, 5.4, 5.5, 5.6, 7.0, 7.1, 7.2 и HHVM.
Быстрый старт и примеры
Дополнительные примеры доступны в /примерах.
require __DIR__ . '/vendor/autoload.php'; use \Curl\Curl; $curl = new Curl(); $curl->get('https://www.example.com/'); if ($curl->error) { echo 'Error: ' . $curl->errorCode . ': ' . $curl->errorMessage . "\n"; } else { echo 'Response:' . "\n"; var_dump($curl->response); }
// https://www.example.com/search?q=keyword $curl = new Curl(); $curl->get('https://www.example.com/search', array( 'q' => 'keyword', ));
$curl = new Curl(); $curl->post('https://www.example.com/login/', array( 'username' => 'myusername', 'password' => 'mypassword', ));
$curl = new Curl(); $curl->setBasicAuthentication('username', 'password'); $curl->setUserAgent('MyUserAgent/0.0.1 (+https://www.example.com/bot.html)'); $curl->setReferrer('https://www.example.com/url?url=https%3A%2F%2Fwww.example.com%2F'); $curl->setHeader('X-Requested-With', 'XMLHttpRequest'); $curl->setCookie('key', 'value'); $curl->get('https://www.example.com/'); if ($curl->error) { echo 'Error: ' . $curl->errorCode . ': ' . $curl->errorMessage . "\n"; } else { echo 'Response:' . "\n"; var_dump($curl->response); } var_dump($curl->requestHeaders); var_dump($curl->responseHeaders);
$curl = new Curl(); $curl->setOpt(CURLOPT_FOLLOWLOCATION, true); $curl->get('https://shortn.example.com/bHbVsP');
$curl = new Curl(); $curl->put('https://api.example.com/user/', array( 'first_name' => 'Zach', 'last_name' => 'Borboa', ));
$curl = new Curl(); $curl->patch('https://api.example.com/profile/', array( 'image' => '@path/to/file.jpg', ));
$curl = new Curl(); $curl->patch('https://api.example.com/profile/', array( 'image' => new CURLFile('path/to/file.jpg'), ));
$curl = new Curl(); $curl->delete('https://api.example.com/user/', array( 'id' => '1234', ));
// Включить все поддерживаемые типы кодировки и загрузите файл. $curl = new Curl(); $curl->setOpt(CURLOPT_ENCODING , ''); $curl->download('https://www.example.com/file.bin', '/tmp/myfile.bin');
// Нечувствительный к регистру доступ к заголовкам. $curl = new Curl(); $curl->download('https://www.example.com/image.png', '/tmp/myimage.png'); echo $curl->responseHeaders['Content-Type'] . "\n"; // image/png echo $curl->responseHeaders['CoNTeNT-TyPE'] . "\n"; // image/png
// Очистить. $curl->close();
// Пример доступа к объекту curl. curl_set_opt($curl->curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1'); curl_close($curl->curl);
require __DIR__ . '/vendor/autoload.php'; use \Curl\MultiCurl; // Запросы параллельно с функциями обратного вызова. $multi_curl = new MultiCurl(); $multi_curl->success(function($instance) { echo 'вызов "' . $instance->url . '"был удачный.' . "\n"; echo 'ответ:' . "\n"; var_dump($instance->response); }); $multi_curl->error(function($instance) { echo 'call to "' . $instance->url . '" was unsuccessful.' . "\n"; echo 'код ошибки: ' . $instance->errorCode . "\n"; echo 'сообщение об ошибке: ' . $instance->errorMessage . "\n"; }); $multi_curl->complete(function($instance) { echo 'вызов завершен' . "\n"; }); $multi_curl->addGet('https://www.google.com/search', array( 'q' => 'hello world', )); $multi_curl->addGet('https://duckduckgo.com/', array( 'q' => 'hello world', )); $multi_curl->addGet('https://www.bing.com/search', array( 'q' => 'hello world', )); $multi_curl->start(); // Blocks until all items in the queue have been processed.
Дополнительные примеры доступны в разделе /образцы.
Имеющиеся методы
Curl::__construct($base_url = null) Curl::__destruct() Curl::__get($name) Curl::attemptRetry() Curl::beforeSend($callback) Curl::buildPostData($data) Curl::call() Curl::close() Curl::complete($callback) Curl::delete($url, $query_parameters = array(), $data = array()) Curl::download($url, $mixed_filename) Curl::error($callback) Curl::exec($ch = null) Curl::execDone() Curl::get($url, $data = array()) Curl::getAttempts() Curl::getBeforeSendCallback() Curl::getCompleteCallback() Curl::getCookie($key) Curl::getCurl() Curl::getCurlErrorCode() Curl::getCurlErrorMessage() Curl::getDownloadCompleteCallback() Curl::getDownloadFileName() Curl::getErrorCallback() Curl::getErrorCode() Curl::getErrorMessage() Curl::getFileHandle() Curl::getHttpErrorMessage() Curl::getHttpStatusCode() Curl::getId() Curl::getInfo($opt = null) Curl::getJsonDecoder() Curl::getOpt($option) Curl::getRawResponse() Curl::getRawResponseHeaders() Curl::getRemainingRetries() Curl::getRequestHeaders() Curl::getResponse() Curl::getResponseCookie($key) Curl::getResponseCookies() Curl::getResponseHeaders() Curl::getRetries() Curl::getRetryDecider() Curl::getSuccessCallback() Curl::getUrl() Curl::getXmlDecoder() Curl::head($url, $data = array()) Curl::isChildOfMultiCurl() Curl::isCurlError() Curl::isError() Curl::isHttpError() Curl::options($url, $data = array()) Curl::patch($url, $data = array()) Curl::post($url, $data = '', $follow_303_with_post = false) Curl::progress($callback) Curl::put($url, $data = array()) Curl::removeHeader($key) Curl::reset() Curl::search($url, $data = array()) Curl::setBasicAuthentication($username, $password = '') Curl::setConnectTimeout($seconds) Curl::setCookie($key, $value) Curl::setCookieFile($cookie_file) Curl::setCookieJar($cookie_jar) Curl::setCookieString($string) Curl::setCookies($cookies) Curl::setDefaultDecoder($mixed = 'json') Curl::setDefaultJsonDecoder() Curl::setDefaultTimeout() Curl::setDefaultUserAgent() Curl::setDefaultXmlDecoder() Curl::setDigestAuthentication($username, $password = '') Curl::setHeader($key, $value) Curl::setHeaders($headers) Curl::setJsonDecoder($mixed) Curl::setMaxFilesize($bytes) Curl::setOpt($option, $value) Curl::setOpts($options) Curl::setPort($port) Curl::setProxy($proxy, $port = null, $username = null, $password = null) Curl::setProxyAuth($auth) Curl::setProxyTunnel($tunnel = true) Curl::setProxyType($type) Curl::setReferer($referer) Curl::setReferrer($referrer) Curl::setRetry($mixed) Curl::setTimeout($seconds) Curl::setUrl($url, $mixed_data = '') Curl::setUserAgent($user_agent) Curl::setXmlDecoder($mixed) Curl::success($callback) Curl::unsetHeader($key) Curl::unsetProxy() Curl::verbose($on = true, $output = STDERR) MultiCurl::__construct($base_url = null) MultiCurl::__destruct() MultiCurl::addCurl(Curl $curl) MultiCurl::addDelete($url, $query_parameters = array(), $data = array()) MultiCurl::addDownload($url, $mixed_filename) MultiCurl::addGet($url, $data = array()) MultiCurl::addHead($url, $data = array()) MultiCurl::addOptions($url, $data = array()) MultiCurl::addPatch($url, $data = array()) MultiCurl::addPost($url, $data = '', $follow_303_with_post = false) MultiCurl::addPut($url, $data = array()) MultiCurl::addSearch($url, $data = array()) MultiCurl::beforeSend($callback) MultiCurl::close() MultiCurl::complete($callback) MultiCurl::error($callback) MultiCurl::getOpt($option) MultiCurl::removeHeader($key) MultiCurl::setBasicAuthentication($username, $password = '') MultiCurl::setConcurrency($concurrency) MultiCurl::setConnectTimeout($seconds) MultiCurl::setCookie($key, $value) MultiCurl::setCookieFile($cookie_file) MultiCurl::setCookieJar($cookie_jar) MultiCurl::setCookieString($string) MultiCurl::setCookies($cookies) MultiCurl::setDigestAuthentication($username, $password = '') MultiCurl::setHeader($key, $value) MultiCurl::setHeaders($headers) MultiCurl::setJsonDecoder($mixed) MultiCurl::setOpt($option, $value) MultiCurl::setOpts($options) MultiCurl::setPort($port) MultiCurl::setReferer($referer) MultiCurl::setReferrer($referrer) MultiCurl::setRetry($mixed) MultiCurl::setTimeout($seconds) MultiCurl::setUrl($url) MultiCurl::setUserAgent($user_agent) MultiCurl::setXmlDecoder($mixed) MultiCurl::start() MultiCurl::success($callback) MultiCurl::unsetHeader($key) MultiCurl::verbose($on = true, $output = STDERR)
Соображения безопасности.
Url может указывать на системные файлы.
- Слепо не принимать ссылки от пользователей, поскольку они могут указывать на системные файлы. Curl поддерживает множество протоколов, включая FILE. Ниже показано содержимое файла file:///etc/passwd
# Атакующий. $ curl https://www.example.com/display_webpage.php?url=file%3A%2F%2F%2Fetc%2Fpasswd
// display_webpage.php $url = $_GET['url']; // DANGER! $curl = new Curl(); $curl->get($url); echo $curl->response;
Более безопасный:
function is_allowed_url($url, $allowed_url_schemes = array('http', 'https')) { $valid_url = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED) !== false; if ($valid_url) { $scheme = parse_url($url, PHP_URL_SCHEME); return in_array($scheme, $allowed_url_schemes, true); } $valid_ip = filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false; return $valid_ip; } $url = $_GET['url']; if (!is_allowed_url($url)) { die('Unsafe url detected.'); }
URL-адрес может указывать на внутренние URL-адреса.
- Url-адрес может указывать на внутренние URL-адреса, в том числе за брандмауэром (например http://192.168.0.1 / или ftp://192.168.0.1/). Используйте белый список, чтобы разрешить определенные URL, а не черный список.
Данные запроса могут относиться к системным файлам.
- Данные запроса с префиксом @ могут иметь специальную интерпретацию и считываться из системных файлов.
# Атакующий. $ curl https://www.example.com/upload_photo.php --data "photo=@/etc/passwd"
// upload_photo.php $curl = new Curl(); $curl->post('http://www.anotherwebsite.com/', array( 'photo' => $_POST['photo'], // DANGER! ));
Небезопасный ответ с включенным перенаправлением.
- Запросы с включенным перенаправлением могут возвращать ответы из неожиданных источников. Загрузка https://www.example.com/image.png может редирект и скачать https://www.evil.com/virus.exe
$curl = new Curl(); $curl->setOpt(CURLOPT_FOLLOWLOCATION, true); // DANGER! $curl->download('https://www.example.com/image.png', 'my_image.png');
$curl = new Curl(); $curl->setOpt(CURLOPT_FOLLOWLOCATION, true); // DANGER! $curl->get('https://www.example.com/image.png');
Держите SSL защита включеной.
- Не отключайте защиту SSL.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // DANGER! curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // DANGER!
Предотвращение внедрения внешней сущности XML.
- Задайте следующие параметры при использовании парсера PHP XML по умолчанию, чтобы предотвратить внедрение внешних XML-объектов.
libxml_disable_entity_loader(true);
Выполнить тесты.
Для запуска тестов:
$ git clone https://github.com/php-curl-class/php-curl-class.git $ cd php-curl-class/ $ composer update $ ./tests/run.sh
Чтобы проверить все версии PHP в контейнерах:
$ git clone https://github.com/php-curl-class/php-curl-class.git $ cd php-curl-class/ $ ./tests/test_all.sh