HTTP Sabre (Da Mao Wang), высокопроизводительный HTTP-клиент PHP из Swoole人性化组件库
, основан на собственной сопрограмме Swoole, поддерживает несколько стилей операций и предоставляет высокопроизводительные решения внизу, позволяя разработчикам сосредоточиться на функциональности. разработка, от традиционных Свободных от синхронной блокировки и громоздкой настройки Curl.
Английский документ
Лучший способ установки — через менеджер пакетов Composer:
composer require swlib/saber
Нижний уровень Swoole реализует планирование сопрограмм, о чем не нужно знать бизнес-уровне . Разработчики могут использовать синхронную запись кода для достижения эффекта асинхронного ввода-вывода и сверхвысокой производительности, не подозревая об этом, избегая логики дискретного кода и т. д. чрезмерное перехват, вызванное традиционными асинхронными обратными вызовами, делает код недоступным.
Его необходимо использовать в onRequet
, onReceive
, onConnect
и других функциях обратного вызова событий или обернуть ключевым словом go ( swoole.use_shortname
включен по умолчанию).
go ( function () {
echo SaberGM:: get ( ' http://httpbin.org/get ' );
})
Автоматическая упаковка данных: входящие данные будут автоматически преобразованы в формат типа, указанный типом контента.
По умолчанию используется
x-www-form-urlencoded
. Также поддерживаются другие форматы, такие какjson
.
SaberGM
:= Saber Global Manager
. Если вы считаете, что имя класса слишком длинное, вы можете использовать class_alias
, чтобы выбрать псевдоним самостоятельно. Рекомендуется использовать метод генерации экземпляров в сервисе и использовать SaberGM
в качестве ярлыка.
SaberGM:: get ( ' http://httpbin.org/get ' );
SaberGM:: delete ( ' http://httpbin.org/delete ' );
SaberGM:: post ( ' http://httpbin.org/post ' , [ ' foo ' => ' bar ' ]);
SaberGM:: put ( ' http://httpbin.org/put ' , [ ' foo ' => ' bar ' ]);
SaberGM:: patch ( ' http://httpbin.org/patch ' , [ ' foo ' => ' bar ' ]);
Применимый прокси-сервис API
$ saber = Saber:: create ([
' base_uri ' => ' http://httpbin.org ' ,
' headers ' => [
' Accept-Language ' => ' en,zh-CN;q=0.9,zh;q=0.8 ' ,
' Content-Type ' => ContentType:: JSON ,
' DNT ' => ' 1 ' ,
' User-Agent ' => null
]
]);
echo $ saber -> get ( ' /get ' );
echo $ saber -> delete ( ' /delete ' );
echo $ saber -> post ( ' /post ' , [ ' foo ' => ' bar ' ]);
echo $ saber -> patch ( ' /patch ' , [ ' foo ' => ' bar ' ]);
echo $ saber -> put ( ' /put ' , [ ' foo ' => ' bar ' ]);
Сессия автоматически сохранит информацию о файлах cookie, и ее реализация будет завершена на уровне браузера.
$ session = Saber:: session ([
' base_uri ' => ' http://httpbin.org ' ,
' redirect ' => 0
]);
$ session -> get ( ' /cookies/set?foo=bar&k=v&apple=banana ' );
$ session -> get ( ' /cookies/delete?k ' );
echo $ session -> get ( ' /cookies ' )-> body ;
Примечание. Здесь используется решение по оптимизации одновременного перенаправления. Несколько перенаправлений всегда выполняются одновременно и не превращаются в один запрос в очереди.
$ responses = SaberGM:: requests ([
[ ' uri ' => ' http://github.com/ ' ],
[ ' uri ' => ' http://github.com/ ' ],
[ ' uri ' => ' https://github.com/ ' ]
]);
echo " multi-requests [ { $ responses -> success_num } ok, { $ responses -> error_num } error ]: n" . " consuming-time: { $ responses -> time } s n" ;
// multi - requests [ 3 ok , 0 error ] :
// consuming - time : 0 . 79090881347656s
// 别名机制可以省略参数书写参数名
$ saber = Saber:: create ([ ' base_uri ' => ' http://httpbin.org ' ]);
echo $ saber -> requests ([
[ ' get ' , ' /get ' ],
[ ' post ' , ' /post ' ],
[ ' patch ' , ' /patch ' ],
[ ' put ' , ' /put ' ],
[ ' delete ' , ' /delete ' ]
]);
На данный момент поддерживается быстрый анализ данных в четырех форматах: json
, xml
, html
и url-query
[ $ json , $ xml , $ html ] = SaberGM:: list ([
' uri ' => [
' http://httpbin.org/get ' ,
' http://www.w3school.com.cn/example/xmle/note.xml ' ,
' http://httpbin.org/html '
]
]);
var_dump ( $ json -> getParsedJsonArray ());
var_dump ( $ json -> getParsedJsonObject ());
var_dump ( $ xml -> getParsedXmlArray ());
var_dump ( $ xml -> getParsedXmlObject ( true ));
var_dump ( $ html -> getParsedDomObject ()-> getElementsByTagName ( ' h1 ' )-> item ( 0 )-> textContent );
Поддерживает прокси HTTP и SOCKS5.
$ uri = ' http://myip.ipip.net/ ' ;
echo SaberGM:: get ( $ uri , [ ' proxy ' => ' http://127.0.0.1:1087 ' ])-> body ;
echo SaberGM:: get ( $ uri , [ ' proxy ' => ' socks5://127.0.0.1:1086 ' ])-> body ;
Базовое автоматическое планирование сопрограмм может поддерживать асинхронную отправку очень больших файлов и возобновление передачи с точки останова.
Загрузите три файла одновременно (три стиля параметров:
string
|array
|object
)
$ file1 = __DIR__ . ' /black.png ' ;
$ file2 = [
' path ' => __DIR__ . ' /black.png ' ,
' name ' => ' white.png ' ,
' type ' => ContentType:: MAP [ ' png ' ],
' offset ' => null , // re - upload from break
' size ' => null //upload a part of the file
];
$ file3 = new SwUploadFile (
__DIR__ . ' /black.png ' ,
' white.png ' ,
ContentType:: MAP [ ' png ' ]
);
echo SaberGM:: post ( ' http://httpbin.org/post ' , null , [
' files ' => [
' image1 ' => $ file1 ,
' image2 ' => $ file2 ,
' image3 ' => $ file3
]
]
);
После того, как Download получит данные, он асинхронно запишет их непосредственно на диск вместо объединения HttpBody в памяти. Таким образом, Download использует только небольшой объем памяти для завершения загрузки очень больших файлов . Он также поддерживает возобновление загрузки с точки останова. установка параметра смещения для загрузки точек останова.
Асинхронная загрузка обоев Sabre
$ download_dir = ' /tmp/saber.jpg ' ;
$ response = SaberGM:: download (
' https://ws1.sinaimg.cn/large/006DQdzWly1fsr8jt2botj31hc0wxqfs.jpg ' ,
$ download_dir
);
if ( $ response -> success ) {
exec ( ' open ' . $ download_dir );
}
В проектах сканеров очень распространено требование автоматического повтора неудачного запроса, например повторного входа в систему после истечения сеанса.
Эта функция встроена в Saber
, и для ее расширения можно использовать拦截器
.
Если retry_time
не установлено, но установлен перехватчик retry
, retry_time
будет установлено в 1. Если метод обратного вызова перехватчика retry
возвращает false
, независимо от значения retry_time
, повторная попытка будет прекращена, когда будет возвращено false
.
$ uri = ' http://eu.httpbin.org/basic-auth/foo/bar ' ;
$ res = SaberGM:: get (
$ uri , [
' exception_report ' => 0 ,
' retry_time ' => 3 ,
' retry ' => function ( Saber Request $ request ) {
echo " retry... n" ;
$ request -> withBasicAuth ( ' foo ' , ' bar ' ); //发现失败后添加验证信息
if ( ' i don not want to retry again ' ) {
return false ; // shutdown
}
}
]
);
echo $ res ;
Иногда HTTP-ресурсы не всегда изменяются. Мы можем узнать, как браузеры кэшируют ресурсы, которые не изменяются, чтобы повысить эффективность запросов. Saber
автоматически выполняет это без необходимости поддерживать логику кэширования (CURD или чтение и запись файлов) самостоятельно. в любом случае он не будет блокировать сервер. Saber
не использует механизм промежуточного программного обеспечения, поскольку он тесно связан с Swoole, но для кэширования можно использовать内存/文件/数据库
и другие методы, поэтому, хотя он еще не реализован, он будет включен в Saber
последующая дорожная карта.
$ bufferStream = new BufferStream ();
$ bufferStream -> write ( json_encode ([ ' foo ' => ' bar ' ]));
$ response = SaberGM:: psr ()
-> withMethod ( ' POST ' )
-> withUri ( new Uri ( ' http://httpbin.org/post?foo=bar ' ))
-> withQueryParams ([ ' foo ' => ' option is higher-level than uri ' ])
-> withHeader ( ' content-type ' , ContentType:: JSON )
-> withBody ( $ bufferStream )
-> exec ()-> recv ();
echo $ response -> getBody ();
Вы можете напрямую распечатать возвращенную строку данных с помощью метода __toString фрейма данных websocketFrame.
$ websocket = SaberGM:: websocket ( ' ws://127.0.0.1:9999 ' );
while ( true ) {
echo $ websocket -> recv ( 1 ) . "n" ;
$ websocket -> push ( " hello " );
co:: sleep ( 1 );
}
Тестовая машина — MacBook Pro самой низкой конфигурации, а сервер запросов — локальный эхо-сервер.
Выполнено 6666 запросов за 0,9 секунды с вероятностью успеха 100%.
co:: set ([ ' max_coroutine ' => 8191 ]);
go ( function () {
$ requests = [];
for ( $ i = 6666 ; $ i --;) {
$ requests [] = [ ' uri ' => ' http://127.0.0.1 ' ];
}
$ res = SaberGM:: requests ( $ requests );
echo " use { $ res -> time } s n" ;
echo " success: $ res -> success_num , error: $ res -> error_num " ;
});
// on MacOS
// use 0 . 91531705856323s
// success : 6666 , error : 0
В реальных проектах для настройки запросов часто используются списки URL-адресов, поэтому для удобства предусмотрен метод list:
echo SaberGM:: list ([
' uri ' => [
' https://www.qq.com/ ' ,
' https://www.baidu.com/ ' ,
' https://www.swoole.com/ ' ,
' http://httpbin.org/ '
]
]);
В реальных проектах сканеров нам часто приходится ограничивать количество отдельных одновременных запросов, чтобы их не блокировал брандмауэр сервера, и параметр max_co
может легко решить эту проблему. max_co
будет помещать запросы в очередь пакетами в соответствии с верхним пределом. и выполните их.
// max_co is the max number of concurrency request once , it ' s very useful to prevent server - waf limit .
$ requests = array_fill ( 0 , 10 , [ ' uri ' => ' https://www.qq.com/ ' ]);
echo SaberGM:: requests ( $ requests , [ ' max_co ' => 5 ])-> time . "n" ;
echo SaberGM:: requests ( $ requests , [ ' max_co ' => 1 ])-> time . "n" ;
При использовании на резидентном сервере обязательно включите опцию пула соединений вручную :
$ swoole = Saber:: create ([
' base_uri ' => ' https://www.swoole.com/ ' ,
' use_pool ' => true
]);
При использовании этого экземпляра функция пула соединений будет включена, то есть базовый клиент соединения с веб-сайтом www.swoole.com
будет использовать глобальный пул соединений для доступа, избегая накладных расходов на создание/подключение каждый раз, когда он используется. .
Если параметр имеет значение true
, емкость пула соединений веб-сайта не ограничена . Как правило, проблем не возникает, и пул соединений с неограниченной емкостью имеет более высокую производительность.
Но если вы используете его в качестве прокси-службы сканера и сталкиваетесь с большим количеством запросов , количество клиентов в пуле подключений будет бесконтрольно и быстро увеличиваться, даже превышая максимальное количество подключений, разрешенное исходным веб-сайтом, который вы запрашивали в настоящее время. вам необходимо, чтобы для use_pool
было установлено идеальное значение (int). В это время нижний уровень будет использовать Channel в качестве пула соединений. Когда количество клиентов, созданных пулом соединений, превышает количество и недостаточно, сопрограмма. которому необходим доступ к клиенту, будет приостановлено. И дождитесь, пока сопрограмма, использующая клиент, вернет клиента. При ожидании и переключении сопрограммы почти нет потребления производительности, и это очень продвинутое решение.
Следует отметить, что пул соединений привязан к服务器IP+端口
, то есть, если у вас есть несколько экземпляров, обращенных к одному и тому же服务器IP+端口
, пул соединений, используемый между ними, также будет одинаковым.
Поэтому, когда вы повторно создаете экземпляр服务器IP+端口
, use_pool
указанный вновь созданным экземпляром, может перезаписать предыдущее значение, то есть нижний уровень пула соединений автоматически меняет свою емкость. Когда емкость увеличивается, нижний уровень заново создаст новый пул соединений и перенесет клиентов. При уменьшении емкости лишние клиенты в пуле соединений также будут уничтожены.
Помимо необходимости настройки пула соединений, метод обработки исключений также должен соответствовать вашим привычкам программирования. Обработка исключений Saber
по умолчанию является наиболее распространенной и строгой,抛出异常
, но Saber
также поддерживает автоматическое использование错误码
и状态位
, могут больше соответствовать вкусам многих людей.
SaberGM:: exceptionReport ( 0 ); // 关闭抛出异常报告, 在业务代码之前注册即可全局生效
$ saber -> exceptionReport ( 0 ); //也可以单独设置某个实例
Аналогично, нужную конфигурацию можно предварительно настроить до бизнес-кода, например onWorkerStart
, или даже до запуска swoole_server
.
SaberGM:: default ([
' exception_report ' => 0
' use_pool ' => true
]);
Подобная настройка желаемых параметров может дать вам лучший опыт!
go ( function (){
// your code with pool ...
saber_pool_release (); // and this script will exit
});
Если вы используете пул соединений в одноразовом сценарии, поскольку клиент сопрограммы существует в пуле, счетчик ссылок равен 1 и не может быть освобожден, что приведет к тому, что swoole всегда будет в цикле событий, и сценарий не сможет выйти. необходимо вручную вызвать saber_pool_release
Или saber_exit
или swoole_event_exit
для нормального выхода, или вы можете использовать выход для принудительного выхода из текущего сценария (не используйте выход на сервере).
|
разделяет несколько необязательных значений
ключ | тип | введение | пример | замечание |
---|---|---|---|---|
протокол_версия | нить | Версия протокола HTTP | 1.1 | HTTP2 все еще находится в стадии планирования |
base_uri | нить | базовый путь | http://httpbin.org | Будет объединен с uri согласно rfc3986. |
ури | нить | идентификатор ресурса | http://httpbin.org/get | /get get | Можно использовать как абсолютные, так и относительные пути. |
uri_query | строка|массив | запросить информацию | ['foo' => 'bar'] | Нестроковые преобразуются автоматически |
метод | нить | Метод запроса | get | post | head patch put delete | Нижний слой автоматически преобразуется в верхний регистр. |
заголовки | множество | заголовок запроса | ['DNT' => '1'] | ['accept' => ['text/html'], ['application/xml']] | Имена полей не чувствительны к регистру, но при настройке будут сохранены исходные правила регистра. Каждое значение основного поля будет автоматически разделено на массивы в соответствии с PSR-7. |
печенье | array | string | ['foo '=> 'bar'] 'foo=bar; foz=baz' | Нижний уровень автоматически преобразуется в объект Cookies, а его домену присваивается текущий URI с полными атрибутами на уровне браузера. | |
пользовательский агент | нить | пользовательский агент | curl-1.0 | По умолчанию на платформе Macos используется Chrome. |
реферер | нить | Исходный адрес | https://www.google.com | По умолчанию пусто |
перенаправить | интервал | Максимальное количество перенаправлений | 5 | Значение по умолчанию — 3, а когда оно равно 0, перенаправление отсутствует. |
держать_живым | логическое значение | Стоит ли оставаться на связи | true | false | По умолчанию установлено значение true, соединение будет автоматически повторно использоваться во время перенаправления. |
тип_контента | нить | Тип кодировки контента отправлен | text/plain | SwlibHttpContentType::JSON | По умолчанию используется application/x-www-form-urlencoded. |
данные | array | string | данные отправлены | 'foo=bar&dog=cat' | ['foo' => 'bar'] | Данные будут автоматически закодированы на основе content_type. |
до | callable | array | Перехватчик предварительного запроса | function(Request $request){} | Подробную информацию можно найти в разделе «Перехватчик». |
после | callable | array | Перехватчик после ответа | function(Response $response){} | Подробную информацию можно найти в разделе «Перехватчик». |
before_redirect | callable | array | Перехватчик пост-редиректа | function(Request $request, Response $response){} | Подробную информацию можно найти в разделе «Перехватчик». |
тайм-аут | плавать | тайм-аут | 0,5 | По умолчанию — 5 с, поддерживается тайм-аут в миллисекундах. |
привязка_адрес | нить | Привязать адрес | 192.168.1.1 или eth0 | Не установлено по умолчанию |
привязка_порта | интервал | Привязать порт | 80 | Не установлено по умолчанию |
прокси | нить | актерское мастерство | http://127.0.0.1:1087 | socks5://127.0.0.1:1087 | Поддержка HTTP и Socks5 |
SSL | интервал | Включить ли SSL-соединение | 0=关闭 1=开启 2=自动 | По умолчанию автоматический |
кафе | нить | ca-файл | __DIR__ . '/cacert.pem' | Поставляется по умолчанию |
ssl_verify_peer | логическое значение | Проверка сертификата на стороне сервера | false | true | Выключено по умолчанию |
ssl_allow_self_signed | логическое значение | Разрешить самозаверяющие сертификаты | true | false | Разрешено по умолчанию |
ssl_cert_file | нить | сертификат сертификата | __DIR__ . '/ssl.cert' | Не установлено по умолчанию |
ssl_key_file | нить | ключ закрытый ключ | __DIR__ . '/ssl.key' | Не установлено по умолчанию |
значок v | множество | Укажите преобразование кодировки | ['gbk', 'utf-8'] | Всего имеется три параметра: from,to,use_mb , которые по умолчанию распознаются автоматически. |
исключение_отчет | интервал | Уровень отчетности об исключениях | HttpExceptionMask::E_ALL | Сообщать обо всех исключениях по умолчанию |
дескриптор_исключения | вызываемый|массив | Пользовательская функция обработки исключений | function(Exception $e){} | Ошибки можно игнорировать, если функция возвращает true |
повторить попытку | отзывной | Автоматический перехватчик повторных попыток | function(Request $request, Response $response){} | После возникновения ошибки и перед повторной попыткой |
время повтора | интервал | Автоматические повторные попытки | Не повторять попытку по умолчанию | |
использовать_пул | bool|int | пул соединений | true | false |
ключ_пула | вызываемый|массив | Ключ пула подключений | function(Request $request):string { return $key; } | По умолчанию используется host:port запрошенного адреса. |
Для удобства использования и отказоустойчивости ключевые значения элементов конфигурации имеют механизм псевдонимов. Рекомендуется по возможности использовать оригинальное имя:
ключ | псевдоним |
---|---|
метод | 0 |
ури | 1 | url |
данные | 2 | body |
base_uri | base_url |
после | перезвонить |
тип_контента | content-type | тип contentType |
печенье | печенье |
заголовки | заголовок |
перенаправить | следовать |
пользовательский агент | ua | user-agent |
исключение_отчет | report error_report | |
before_retry | повторить попытку |
реферер | ref | referrer |
Перехватчик — это очень мощная функция Sabre, которая позволяет очень удобно выполнять различные операции, например, печатать логи разработки:
SaberGM:: get ( ' http://twosee.cn/ ' , [
' before ' => function ( Saber Request $ request ) {
$ uri = $ request -> getUri ();
echo " log: request $ uri now... n" ;
},
' after ' => function ( Saber Response $ response ) {
if ( $ response -> success ) {
echo " log: success! n" ;
} else {
echo " log: failed n" ;
}
echo " use { $ response -> time } s " ;
}
]);
// log : request http : // twosee . cn / now...
// log : success !
// use 0 . 52036285400391s
Даже специальные функции и会话
异常自定义处理函数
реализуются посредством перехватчиков.
Может быть несколько перехватчиков, которые будут выполняться в порядке регистрации, и вы можете назвать перехватчик . Вам нужно только обернуть его массивом и указать значение ключа. Если вы хотите удалить этот перехватчик, просто перезапишите его. нулевое значение.
[
' after ' => [
' interceptor_new ' => function (){},
' interceptor_old ' => null
]
]
Перехватчики можно зарегистрировать четырьмя способами (4 функции обратного вызова PHP):
callable: function (){}
string: ' function_name '
string: ' ClassName::method_name '
array: [ $ object , ' method_name ' ]
Реализация файлов cookie является полной на уровне браузера . Это конкретно относится к реализации браузера Chrome и соответствует его соответствующим правилам.
Файлы cookie представляют собой набор файлов cookie, каждый из которых имеет следующие свойства:
name
, value
, expires
, path
, session
, secure
, httponly
, hostonly
А класс Cookies поддерживает преобразование нескольких форматов, таких как
foo=bar; foz=baz; apple=banana
Set-Cookie: logged_in=no; domain=.github.com; path=/; expires=Tue, 06 Apr 2038 00:00:00 -0000; secure; HttpOnly
['foo'=>'bar', 'foz'=>'baz']
Подождите, пока формат будет передан в класс Cookie или класс Cookie будет сериализован в эти форматы.
Файлы cookie также поддерживают проверку имени домена и ограничения по времени без потери какой-либо информации. Например, если домен — github.com
, файл cookie не будет отображаться в help.github.com
если только домен не является хостом (подстановочный знак .github.com
).
Если это сеансовый файл cookie (он не имеет срока действия и истекает при закрытии браузера), атрибут expires будет установлен на текущее время, и вы можете установить конкретное время через перехватчик .
Прочитав необработанный атрибут файлов cookie, его можно легко сохранить в базе данных , что очень удобно для приложений, сканирующих вход в систему.
Для получения более подробной информации обратитесь к документации и примерам библиотеки Swlib/Http.
Sabre следует правилу отделения бизнеса от ошибок . При сбое какой-либо части запроса по умолчанию выдается исключение .
Что особенно важно, так это то, что обработка исключений в Sabre также разнообразна и столь же полна, как и встроенная обработка исключений PHP.
Пространство имен исключений находится в SwlibHttpException
Исключение | Введение | сцена |
---|---|---|
Исключение запроса | Запрос не выполнен | Ошибка конфигурации запроса |
ConnectException | Соединение не удалось | Если нет сетевого подключения, произошел сбой DNS-запроса, истекло время ожидания и т. д., значение errno равно Linux errno. Вы можете использовать swoole_strerror для преобразования кодов ошибок в сообщения об ошибках. |
Исключение TooManyRedirectsException | Превышено количество перенаправлений | Количество перенаправлений превышает установленный предел, и выданное исключение будет печатать информацию об отслеживании перенаправлений. |
Клиентское исключение | Исключение клиента | Сервер вернул код ошибки 4xx. |
Серверное исключение | Исключение сервера | Сервер вернул код ошибки 5xx. |
Исключение BadResponseException | Неизвестно, не удалось получить ответ | Сервер не ответил или вернул нераспознанный код ошибки. |
В дополнение к общим методам исключений все классы исключений HTTP также имеют следующие методы:
Метод | Введение |
---|---|
getRequest | Получить экземпляр запроса |
имеетОтвет | Получить ли ответ |
getResponse | Получить экземпляр ответа |
getResponseBodySummary | Получить сводное содержимое тела ответа |
try {
echo SaberGM:: get ( ' http://httpbin.org/redirect/10 ' );
} catch ( TooManyRedirectsException $ e ) {
var_dump ( $ e -> getCode ());
var_dump ( $ e -> getMessage ());
var_dump ( $ e -> hasResponse ());
echo $ e -> getRedirectsTrace ();
}
// int ( 302)
// string ( 28) "Too many redirects occurred ! "
// bool ( true )
#0 http : // httpbin . org / redirect/10
#1 http : // httpbin . org / relative - redirect/9
#2 http : // httpbin . org / relative - redirect/8
В то же время Sabre также поддерживает щадящую обработку исключений, чтобы пользователи не впадали в панику в нестабильных сетевых средах и не нуждались в переносе кода с try на каждом этапе:
Установите уровень errorReport, который действует глобально и не будет действовать на созданные экземпляры .
// 启用所有异常但忽略重定向次数过多异常
SaberGM:: exceptionReport (
HttpExceptionMask:: E_ALL ^ HttpExceptionMask:: E_REDIRECT
);
Следующие значения (числовые или символические) используются для создания битовой маски, указывающей сообщение об ошибке, о котором необходимо сообщить. Вы можете использовать побитовые операторы для объединения этих значений или для маскировки определенных типов ошибок. Флаги и маски
Маска | Ценить | Введение |
---|---|---|
Е_НЕТ | 0 | игнорировать все исключения |
E_REQUEST | 1 | Соответствует RequestException |
E_CONNECT | 2 | Соответствует RequestException |
E_REDIRECT | 4 | Соответствует RequestException |
E_BAD_RESPONSE | 8 | Соответствует BadRException |
Э_КЛИЕНТ | 16 | Соответствует ClientException |
Э_СЕРВЕР | 32 | Соответствует ServerException |
Е_ВСЕ | 63 | Все исключения |
Эта функция может по-своему обрабатывать ошибки, генерируемые в HTTP-запросах, и вы можете более свободно определять исключения, которые хотите перехватывать/игнорировать.
Примечание. Если функция не вернет TRUE (или другое истинное значение), исключение будет продолжать генерироваться, а не перехватываться пользовательской функцией.
SaberGM:: exceptionHandle ( function ( Exception $ e ) {
echo get_class ( $ e ) . " is caught! " ;
return true ;
});
SaberGM:: get ( ' http://httpbin.org/redirect/10 ' );
//output : Swlib Http E xceptionTooManyRedirectsException is caught !
Загрузка файла | Вебсокеты | АвтоПарсер | Автоматическая повторная попытка | Загрузка большого файла | Кэш | Клиентский пул | СлучайныйUA |
---|---|---|---|---|---|---|---|
4 (высокий приоритет) | 3 | 2 | 1 | .5 | .5 | .5 | .175 |
Основное преимущество HTTP/2 заключается в том, что он позволяет мультиплексировать множество запросов в рамках одного соединения, тем самым [почти] снимая ограничение на количество одновременных запросов - и при общении с вашими собственными серверами такого ограничения не существует. Более того, все может даже быть. становится хуже при использовании HTTP/2 для серверов из-за использования одного TCP-соединения вместо нескольких, поэтому Http2 не будет приоритетом (#ref).
Добавьте исходные файлы этого проекта в Include Path
IDE.
(При установке с помощью композитора вы можете включить всю папку поставщика, и PHPStorm автоматически включит ее)
Хорошее написание комментариев позволяет Sabre прекрасно поддерживать автоматические подсказки IDE. Просто напишите символ стрелки после объекта, чтобы просмотреть имена всех методов объекта. Большое количество методов соответствуют спецификации PSR или реализуются путем ссылки на них. Проект Guzzle (спасибо).
Для запросов IDE для базовых классов, связанных с Swoole, вам необходимо ввести swoole-ide-helper от eaglewu (composer будет установлен по умолчанию в среде разработки). Однако этот проект поддерживается вручную и не является завершенным. Вы также можете использовать swoft. -ide-помощник или:
Официальный помощник Свула.
Добро пожаловать, чтобы представить вопросы и PR.
Поскольку сопрограммы (__call, __callStatic) нельзя использовать в магических методах, методы в исходном коде определяются вручную.
Для простоты использования псевдонимы предоставлены для всех поддерживаемых методов запроса.
public static function psr( array $ options = []): Swlib Saber Request
public static function wait(): Swlib Saber
public static function request( array $ options = [])
public static function get (string $ uri , array $ options = [])
public static function delete (string $ uri , array $ options = [])
public static function head (string $ uri , array $ options = [])
public static function options (string $ uri , array $ options = [])
public static function post (string $ uri , $ data = null , array $ options = [])
public static function put (string $ uri , $ data = null , array $ options = [])
public static function patch (string $ uri , $ data = null , array $ options = [])
public static function download (string $ uri , string $ dir , int $ offset , array $ options = [])
public static function requests (array $ requests , array $ default_options = []): Swlib Saber ResponseMap
public static function list(array $ options , array $ default_options = []): Swlib Saber ResponseMap
public static function websocket (string $ uri )
public static function default (?array $ options = null ): array
public static function exceptionReport (?int $ level = null ): int
public static function exceptionHandle (callable $ handle ): void
public static function create( array $ options = []): self
public static function session( array $ options = []): self
public static function websocket( string $ uri ): WebSocket
public function request( array $ options )
public function get( string $ uri , array $ options = [])
public function delete( string $ uri , array $ options = [])
public function head( string $ uri , array $ options = [])
public function options( string $ uri , array $ options = [])
public function post( string $ uri , $ data = null , array $ options = [])
public function put( string $ uri , $ data = null , array $ options = [])
public function patch( string $ uri , $ data = null , array $ options = [])
public function download( string $ uri , string $ dir , int $ offset , array $ options = [])
public function requests( array $ requests , array $ default_options = []): ResponseMap
public function list( array $ options , array $ default_options = []): ResponseMap
public function upgrade(? string $ path = null ): WebSocket
public function psr( array $ options = []): Request
public function wait(): self
public function exceptionReport(? int $ level = null ): int
public function exceptionHandle( callable $ handle ): void
public static function getAliasMap(): array
public function setOptions( array $ options = [], ? Swlib Saber Request $ request = null ): self
public static function getDefaultOptions(): array
public static function setDefaultOptions( array $ options = [])
public function getExceptionReport(): int
public function setExceptionReport( int $ level ): self
public function isWaiting(): bool
public function getPool()
public function withPool( $ bool_or_max_size ): self
public function tryToRevertClientToPool( bool $ connect_failed = false )
public function getSSL(): int
public function withSSL( int $ mode = 2 ): self
public function getCAFile(): string
public function withCAFile( string $ ca_file = __DIR__ . ' /cacert.pem ' ): self
public function getSSLCertFile(): string
public function withSSLCertFile( string $ cert_file ): self
public function getSSLKeyFile(): string
public function withSSLKeyFile( string $ key_file ): self
public function withSSLVerifyPeer( bool $ verify_peer = false , ? string $ ssl_host_name = '' ): self
public function withSSLAllowSelfSigned( bool $ allow = true ): self
public function getSSLConf()
public function getKeepAlive()
public function withKeepAlive( bool $ enable ): self
public function withBasicAuth(? string $ username = null , ? string $ password = null ): self
public function withXHR( bool $ enable = true )
public function getProxy(): array
public function withProxy( string $ host , int $ port ): self
public function withSocks5( string $ host , int $ port , ? string $ username , ? string $ password ): self
public function withoutProxy(): self
public function getBindAddress(): ? string
public function withBindAddress( string $ address ): self
public function getBindPort(): ? int
public function withBindPort( int $ port ): self
public function getTimeout(): float
public function withTimeout( float $ timeout ): self
public function getRedirect(): int
public function getName()
public function withName( $ name ): self
public function withRedirect( int $ time ): self
public function isInQueue(): bool
public function withInQueue( bool $ enable ): self
public function getRetryTime(): int
public function withRetryTime( int $ time ): self
public function withAutoIconv( bool $ enable ): self
public function withExpectCharset( string $ source = ' auto ' , string $ target = ' utf-8 ' , bool $ use_mb = false ): self
public function withDownloadDir( string $ dir ): self
public function withDownloadOffset( int $ offset ): self
public function resetClient( $ client )
public function exec()
public function recv()
public function getRequestTarget(): string
public function withRequestTarget( $ requestTarget ): self
public function getMethod(): string
public function withMethod( $ method ): self
public function getUri(): Psr Http Message UriInterface
public function withUri(? Psr Http Message UriInterface $ uri , $ preserveHost = false ): self
public function getCookieParams(): array
public function getCookieParam( string $ name ): string
public function withCookieParam( string $ name , ? string $ value ): self
public function withCookieParams( array $ cookies ): self
public function getQueryParam( string $ name ): string
public function getQueryParams(): array
public function withQueryParam( string $ name , ? string $ value ): self
public function withQueryParams( array $ query ): self
public function getParsedBody(? string $ name = null )
public function withParsedBody( $ data ): self
public function getUploadedFile( string $ name ): Psr Http Message UploadedFileInterface
public function getUploadedFiles(): array
public function withUploadedFile( string $ name , ? Psr Http Message UploadedFileInterface $ uploadedFile ): self
public function withoutUploadedFile( string $ name ): self
public function withUploadedFiles( array $ uploadedFiles ): self
public function __toString()
public function getProtocolVersion(): string
public function withProtocolVersion( $ version ): self
public function hasHeader( $ name ): bool
public function getHeader( $ name ): array
public function getHeaderLine( $ name ): string
public function getHeaders( bool $ implode = false , bool $ ucwords = false ): array
public function getHeadersString( bool $ ucwords = true ): string
public function withHeader( $ raw_name , $ value ): self
public function withHeaders( array $ headers ): self
public function withAddedHeaders( array $ headers ): self
public function withAddedHeader( $ raw_name , $ value ): self
public function withoutHeader( $ name ): self
public function getBody(): Psr Http Message StreamInterface
public function withBody(? Psr Http Message StreamInterface $ body ): self
public function getCookies()
public function setCookie( array $ options ): self
public function unsetCookie( string $ name , string $ path = '' , string $ domain = '' ): self
public function withInterceptor( string $ name , array $ interceptor )
public function withAddedInterceptor( string $ name , array $ functions ): self
public function withoutInterceptor( string $ name ): self
public function callInterceptor( string $ name , $ arguments )
public function getSpecialMark( string $ name = ' default ' )
public function withSpecialMark( $ mark , string $ name = ' default ' ): self
public function isSuccess(): bool
public function getUri(): Psr Http Message UriInterface
public function getTime(): float
public function getRedirectHeaders(): array
public function getStatusCode()
public function withStatus( $ code , $ reasonPhrase = '' )
public function getReasonPhrase()
public function __toString()
public function getProtocolVersion(): string
public function withProtocolVersion( $ version ): self
public function hasHeader( $ name ): bool
public function getHeader( $ name ): array
public function getHeaderLine( $ name ): string
public function getHeaders( bool $ implode = false , bool $ ucwords = false ): array
public function getHeadersString( bool $ ucwords = true ): string
public function withHeader( $ raw_name , $ value ): self
public function withHeaders( array $ headers ): self
public function withAddedHeaders( array $ headers ): self
public function withAddedHeader( $ raw_name , $ value ): self
public function withoutHeader( $ name ): self
public function getBody(): Psr Http Message StreamInterface
public function withBody(? Psr Http Message StreamInterface $ body ): self
public function getCookies()
public function setCookie( array $ options ): self
public function unsetCookie( string $ name , string $ path = '' , string $ domain = '' ): self
public function getSpecialMark( string $ name = ' default ' )
public function withSpecialMark( $ mark , string $ name = ' default ' ): self
public function getParsedJsonArray( bool $ reParse = false ): array
public function getParsedJsonObject( bool $ reParse = false ): object
public function getParsedQueryArray( bool $ reParse = false ): array
public function getParsedXmlArray( bool $ reParse = false ): array
public function getParsedXmlObject( bool $ reParse = false ): SimpleXMLElement
public function getParsedDomObject( bool $ reParse = false ): DOMDocument
public function getDataRegexMatch( string $ regex , $ group = null , int $ fill_size )
public function getDataRegexMatches( string $ regex , int $ flag ): array
public function isExistInData( string $ needle , int $ offset )
public function enqueue( $ request )
public function getMaxConcurrency(): int
public function withMaxConcurrency( int $ num = - 1 ): self
public function recv(): Swlib Saber ResponseMap
public function withInterceptor( string $ name , array $ interceptor )
public function withAddedInterceptor( string $ name , array $ functions ): self
public function withoutInterceptor( string $ name ): self
public function callInterceptor( string $ name , $ arguments )
public $ time = 0.0 ;
public $ status_map = [];
public $ success_map = [];
public $ success_num = 0 ;
public $ error_num = 0 ;
public function offsetSet( $ index , $ response )
public function __toString()
public function withMock( bool $ ssl ): self
public function recv( float $ timeout = - 1 )
public function push( string $ data , int $ opcode = 1 , bool $ finish = true ): bool
public function close(): bool
public $ finish = true ;
public $ opcode = null ;
public $ data = null ;
public function getOpcodeDefinition()
public function getOpcode()
public function getData()
public function __toString()