HTTP軍刀(呆毛王), Swoole人性化组件库
之PHP高性能HTTP客戶端, 基於Swoole原生協程, 支援多種風格操作, 底層提供高效能解決方案, 讓開發者專注於功能開發, 從傳統同步阻塞且配置繁瑣的Curl中解放.
English Document
最好的安裝方法是透過Composer 套件管理器:
composer require swlib/saber
Swoole底層實現協程調度,業務層無需感知, 開發者可以無感知的用同步的代碼編寫方式達到異步IO的效果和超高性能,避免了傳統異步回調所帶來的離散的代碼邏輯和陷入多層回調中導致程式碼無法維護.
需要在onRequet
, onReceive
, onConnect
等事件回呼函數中使用, 或是使用go關鍵字包裹( swoole.use_shortname
預設為開啟).
go ( function () {
echo SaberGM:: get ( ' http://httpbin.org/get ' );
})
資料自動打包: 傳入的data會自動轉換成content-type所指定的型別格式
預設為
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 ' ]);
Session會自動儲存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僅使用小量記憶體, 就可以完成超大檔案的下載. 且支援斷點續傳, 透過設定offset參數來進行斷點下載.
非同步下載Saber壁紙
$ 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 ();
可以透過websocketFrame資料幀的__toString方法直接列印回傳資料字串
$ websocket = SaberGM:: websocket ( ' ws://127.0.0.1:9999 ' );
while ( true ) {
echo $ websocket -> recv ( 1 ) . "n" ;
$ websocket -> push ( " hello " );
co:: sleep ( 1 );
}
測試機器為最低配MacBookPro, 請求伺服器為本機echo伺服器
0.9秒完成6666個請求, 成功率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
來正常退出, 也可以使用exit強制退出目前腳本(不要在server中使用exit).
|
符號分割多種可選值
key | type | introduction | example | remark |
---|---|---|---|---|
protocol_version | string | HTTP協定版本 | 1.1 | HTTP2還在規劃中 |
base_uri | string | 基礎路徑 | http://httpbin.org | 將會與uri依rfc3986合併 |
uri | string | 資源標識符 | http://httpbin.org/get | /get | get | 可以使用絕對路徑和相對路徑 |
uri_query | string|array | 請求訊息 | ['foo' => 'bar'] | 非字串會自動轉換 |
method | string | 請求方法 | get | post | head | patch | put | delete | 底層自動轉換為大寫 |
headers | array | 請求報頭 | ['DNT' => '1'] | ['accept' => ['text/html'], ['application/xml']] | 字段名不區分大小寫, 但會保留設定時的原始大小寫規則, 底層每個字段值會根據PSR-7自動分割為數組 |
cookies | array | string | ['foo '=> 'bar'] | 'foo=bar; foz=baz' | 底層自動轉換為Cookies物件, 並設定其domain為目前的uri, 具有瀏覽器等級的完備屬性. | |
useragent | string | 使用者代理 | curl-1.0 | 預設為macos平台的chrome |
referer | string | 來源地址 | https://www.google.com | 預設為空 |
redirect | int | 最大重定向次數 | 5 | 預設為3, 為0時不重定向. |
keep_alive | bool | 是否保持連接 | true | false | 預設為true, 重定向時會自動重複使用連接 |
content_type | string | 傳送的內容編碼類型 | text/plain | SwlibHttpContentType::JSON | 預設為application/x-www-form-urlencoded |
data | array | string | 發送的數據 | 'foo=bar&dog=cat' | ['foo' => 'bar'] | 會根據content_type自動編碼數據 |
before | callable | array | 請求前攔截器 | function(Request $request){} | 具體參考攔截器一節 |
after | callable | array | 回應後攔截器 | function(Response $response){} | 具體參考攔截器一節 |
before_redirect | callable | array | 重定向後攔截器 | function(Request $request, Response $response){} | 具體參考攔截器一節 |
timeout | float | 超時時間 | 0.5 | 預設5s, 支援毫秒級超時 |
bind_address | string | 綁定位址 | 192.168.1.1 或eth0 | 預設不設定 |
bind_port | int | 綁定連接埠 | 80 | 預設不設定 |
proxy | string | 代理商 | http://127.0.0.1:1087 | socks5://127.0.0.1:1087 | 支持http和socks5 |
ssl | int | 是否開啟ssl連線 | 0=关闭 1=开启 2=自动 | 預設自動 |
cafile | string | ca文件 | __DIR__ . '/cacert.pem' | 預設自帶 |
ssl_verify_peer | bool | 驗證伺服器端證書 | false | true | 預設關閉 |
ssl_allow_self_signed | bool | 允許自簽名證書 | true | false | 預設允許 |
ssl_cert_file | string | cert 憑證 | __DIR__ . '/ssl.cert' | 預設不設定 |
ssl_key_file | string | key 私鑰 | __DIR__ . '/ssl.key' | 預設不設定 |
iconv | array | 指定編碼轉換 | ['gbk', 'utf-8'] | 共三個參數為from,to,use_mb , 預設自動識別 |
exception_report | int | 異常報告級別 | HttpExceptionMask::E_ALL | 預設匯報所有異常 |
exception_handle | callable|array | 異常自訂處理函數 | function(Exception $e){} | 函數傳回true時可忽略錯誤 |
retry | callable | 自動重試攔截器 | function(Request $request, Response $response){} | 位於發生錯誤後及重試前 |
retry_time | int | 自動重試次數 | 預設不重試 | |
use_pool | bool|int | 連接池 | true | false |
pool_key | callable|array | 連接池的key | function(Request $request):string { return $key; } | 預設為請求位址的host:port |
為了使用方便與容錯, 配置項目的鍵值具有別名機制, 建議盡量使用本名:
key | alias |
---|---|
method | 0 |
uri | 1 | url |
data | 2 | body |
base_uri | base_url |
after | callback |
content_type | content-type | contentType |
cookies | cookie |
headers | header |
redirect | follow |
useragent | ua | user-agent |
exception_report | error_report | report |
before_retry | retry |
referer | ref | referrer |
攔截器是Saber的一個非常強大的特性, 它可以讓你非常方便地處理各種事情, 比如打印dev日誌:
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
甚至連异常自定义处理函数
,会话
都是透過攔截器來實現的.
攔截器可以有多個, 會依照註冊順序執行, 並且你可以為攔截器命名, 只需要使用數組包裹並指定key值, 如果你要刪除這個攔截器, 給它覆蓋一個null值即可.
[
' after ' => [
' interceptor_new ' => function (){},
' interceptor_old ' => null
]
]
攔截器可以使用四種方式註冊(4種PHP回呼函數):
callable: function (){}
string: ' function_name '
string: ' ClassName::method_name '
array: [ $ object , ' method_name ' ]
Cookie的實作是瀏覽器等級完備的, 它具體參考了Chrome瀏覽器的實作, 並遵循其相關規則.
Cookies是一堆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也支援網域名稱和時限校驗, 不會遺失任何資訊, 如domain是github.com
cookie, 不會出現在help.github.com
, 除非domain不是hostonly的( .github.com
通配).
如果是session-cookie(沒有過期時間,瀏覽器關閉則過期的), expires屬性會設定為當前時間, 你可以透過攔截器來對其設定特定的時間.
透過讀取Cookies的raw屬性, 可以輕鬆地將其持久化到資料庫中, 非常適合登入類爬蟲應用程式.
更多詳情請參考Swlib/Http庫文件和範例.
Saber遵循將業務與錯誤分離的守則, 當請求任意環節失敗時,預設都會拋出異常.
強大的是, Saber的異常處理也是多樣化的, 且和PHP的原生的異常處理一樣完善.
異常的命名空間位於SwlibHttpException
Exception | Intro | scene |
---|---|---|
RequestException | 請求失敗 | 請求配置錯誤 |
ConnectException | 連線失敗 | 如無網路連線, DNS查詢失敗, 逾時等, errno的值等於Linux errno。可使用swoole_strerror將錯誤碼轉為錯誤訊息。 |
TooManyRedirectsException | 重定向次數超限 | 重定向的次數超過了設定的限制, 拋出的異常將會列印重定向追蹤訊息 |
ClientException | 客戶端異常 | 伺服器回傳了4xx錯誤碼 |
ServerException | 伺服器異常 | 伺服器回傳了5xx錯誤碼 |
BadResponseException | 未知的獲取響應失敗 | 伺服器無回應或傳回了無法辨識的錯誤碼 |
除一般異常方法外, 所有HTTP異常類別還擁有以下方法:
Method | Intro |
---|---|
getRequest | 取得請求實例 |
hasResponse | 是否獲得回應 |
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
同時, Saber亦支持以溫和的方式來對待異常, 以免用戶陷入在不穩定的網絡環境下, 必須在每一步都使用try包裹代碼的恐慌中:
設定errorReport等級, 它是全域生效的, 對已建立的實例不會生效.
// 启用所有异常但忽略重定向次数过多异常
SaberGM:: exceptionReport (
HttpExceptionMask:: E_ALL ^ HttpExceptionMask:: E_REDIRECT
);
下面的值(數值或符號)用於建立一個二進位位元掩碼,來製定要報告的錯誤訊息。可以使用位元運算子來組合這些值或屏蔽某些類型的錯誤。標誌位元與遮罩
Mask | Value | Intro |
---|---|---|
E_NONE | 0 | 忽略所有異常 |
E_REQUEST | 1 | 對應RequestException |
E_CONNECT | 2 | 對應RequestException |
E_REDIRECT | 4 | 對應RequestException |
E_BAD_RESPONSE | 8 | 對應BadRException |
E_CLIENT | 16 | 對應ClientException |
E_SERVER | 32 | 對應ServerException |
E_ALL | 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 !
File Upload | WebSocket | AutoParser | AutoRetry | BigFile Download | Cache | ClientPool | Random UA |
---|---|---|---|---|---|---|---|
4 (High-priority) | 3 | 2 | 1 | .5 | .5 | .5 | .175 |
As the main HTTP/2 benefit is that it allows multiplexing many requests within a single connection, thus [almost] removing the limit on number of simultaneous requests - and there is no such limit, when talking to become worse when using HTTP/2 to backends, due to single TCP connection being used instead of multiple ones, so Http2 Will not be a priority. (#ref)
將本專案來源檔案加入到IDE的Include Path
.
(使用composer安裝,則可以包含整個vendor資料夾, PHPStorm會自動包含)
良好的註釋書寫使得Saber完美支持IDE自動提示, 只要在對象後書寫箭頭符號即可查看所有對象方法名稱, 名稱都十分通俗易懂, 大量方法都遵循PSR規範或是參考Guzzle項目(感謝)而實現.
對於底層Swoole相關類別的IDE提示則需要引入eaglewu的swoole-ide-helper(composer在dev環境下會預設安裝), 但是該項目為手動維護, 不太完整, 也可以使用swoft-ide-helper或:
Swoole官方的ide-helper.
歡迎提交issue和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()