HTTP Sabre (Da Mao Wang), klien HTTP PHP berkinerja tinggi dari Swoole人性化组件库
, didasarkan pada coroutine asli Swoole, mendukung berbagai gaya operasi, dan menyediakan solusi berkinerja tinggi di bagian bawah, memungkinkan pengembang untuk fokus pada fungsionalitas pengembangan, dari Bebas tradisional dari pemblokiran sinkron dan konfigurasi Curl yang rumit.
Dokumen Bahasa Inggris
Cara terbaik untuk menginstal adalah melalui manajer paket Composer:
composer require swlib/saber
Lapisan bawah Swoole mengimplementasikan penjadwalan coroutine, dan lapisan bisnis tidak perlu menyadarinya . Pengembang dapat menggunakan penulisan kode sinkron untuk mencapai efek IO asinkron dan kinerja sangat tinggi tanpa menyadarinya, menghindari logika kode diskrit dan jebakan berlebihan yang disebabkan oleh callback asinkron tradisional. Callback lapisan menyebabkan kode tidak dapat dikelola.
Ini perlu digunakan dalam onRequet
, onReceive
, onConnect
dan fungsi callback event lainnya, atau dibungkus dengan kata kunci go ( swoole.use_shortname
diaktifkan secara default).
go ( function () {
echo SaberGM:: get ( ' http://httpbin.org/get ' );
})
Pengemasan data otomatis: Data yang masuk akan secara otomatis diubah ke dalam format tipe yang ditentukan oleh tipe konten
Standarnya adalah
x-www-form-urlencoded
, dan format lain sepertijson
juga didukung.
SaberGM
:= Saber Global Manager
. Jika menurut Anda nama kelasnya agak panjang, Anda dapat menggunakan class_alias
untuk memberikan alias Anda sendiri. Disarankan untuk menggunakan metode pembuatan instance di layanan dan menggunakan SaberGM
sebagai pintasan.
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 ' ]);
Layanan proksi API yang berlaku
$ 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 ' ]);
Sesi akan secara otomatis menyimpan informasi cookie, dan penerapannya selesai di tingkat browser.
$ 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 ;
Catatan: Solusi pengoptimalan pengalihan serentak digunakan di sini. Beberapa pengalihan selalu dilakukan secara bersamaan dan tidak akan berubah menjadi satu permintaan dalam antrean.
$ 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 ' ]
]);
Saat ini mendukung penguraian data secara cepat dalam empat format: json
, xml
, html
, dan 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 );
Mendukung proxy HTTP dan 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 ;
Penjadwalan coroutine otomatis yang mendasarinya dapat mendukung pengiriman file berukuran sangat besar secara asinkron dan melanjutkan pengunggahan pada titik henti sementara.
Unggah tiga file sekaligus (tiga parameter gaya
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
]
]
);
Setelah Download menerima data, ia akan menulisnya langsung ke disk secara asinkron alih-alih menyambungkan HttpBody ke dalam memori. Oleh karena itu, pengunduhan hanya menggunakan sejumlah kecil memori untuk menyelesaikan pengunduhan file yang sangat besar . Ini juga mendukung pengunduhan lanjutan breakpoint mengatur parameter offset untuk melakukan pengunduhan breakpoint.
Pengunduhan wallpaper Sabre secara asinkron
$ download_dir = ' /tmp/saber.jpg ' ;
$ response = SaberGM:: download (
' https://ws1.sinaimg.cn/large/006DQdzWly1fsr8jt2botj31hc0wxqfs.jpg ' ,
$ download_dir
);
if ( $ response -> success ) {
exec ( ' open ' . $ download_dir );
}
Dalam proyek perayap, merupakan persyaratan yang sangat umum untuk mencoba ulang permintaan yang gagal secara otomatis, seperti masuk lagi setelah sesi berakhir.
Saber
memiliki fungsi bawaan ini, dan拦截器
dapat digunakan untuk meningkatkannya.
Jika retry_time
tidak disetel tetapi interseptor retry
disetel, retry_time
akan disetel ke 1. Jika metode panggilan balik dari interseptor retry
kembali mengembalikan false
, apa pun retry_time
-nya, percobaan ulang akan dihentikan ketika false
dikembalikan.
$ 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 ;
Terkadang sumber daya HTTP tidak selalu berubah. Kita dapat mempelajari bagaimana browser menyimpan sumber daya yang tidak berubah untuk mempercepat efisiensi permintaan. Saber
secara otomatis menyelesaikan ini tanpa harus mempertahankan logika caching (CURD atau pembacaan dan penulisan file) dengan sendirinya toh tidak akan memblokir server. Saber
tidak menggunakan mekanisme middleware karena sangat terkait dengan Swoole, namun caching bisa menggunakan内存/文件/数据库
dan cara lainnya, jadi walaupun belum diimplementasikan akan disertakan dalam Saber
peta jalan berikutnya.
$ 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 ();
Anda dapat langsung mencetak string data yang dikembalikan melalui metode __toString pada bingkai data websocketFrame.
$ websocket = SaberGM:: websocket ( ' ws://127.0.0.1:9999 ' );
while ( true ) {
echo $ websocket -> recv ( 1 ) . "n" ;
$ websocket -> push ( " hello " );
co:: sleep ( 1 );
}
Mesin pengujiannya adalah MacBook Pro dengan konfigurasi terendah, dan server permintaannya adalah server gema lokal.
Menyelesaikan 6666 permintaan dalam 0,9 detik , dengan tingkat keberhasilan 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
Dalam proyek sebenarnya, daftar URL sering digunakan untuk mengonfigurasi permintaan, sehingga metode daftar disediakan untuk kenyamanan:
echo SaberGM:: list ([
' uri ' => [
' https://www.qq.com/ ' ,
' https://www.baidu.com/ ' ,
' https://www.swoole.com/ ' ,
' http://httpbin.org/ '
]
]);
Dalam proyek perayap sebenarnya, kita sering kali harus membatasi jumlah permintaan tunggal secara bersamaan untuk mencegah pemblokiran oleh firewall server, dan parameter max_co
dapat dengan mudah menyelesaikan masalah ini. max_co
akan memasukkan permintaan ke dalam antrian dalam batch sesuai dengan batas atas dan jalankan mereka.
// 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" ;
Saat digunakan di server yang menyimpan memori, pastikan untuk mengaktifkan opsi kumpulan koneksi secara manual :
$ swoole = Saber:: create ([
' base_uri ' => ' https://www.swoole.com/ ' ,
' use_pool ' => true
]);
Ketika digunakan melalui instance ini, fitur kumpulan koneksi akan diaktifkan, yaitu klien koneksi yang mendasari dengan situs web www.swoole.com
akan menggunakan kumpulan koneksi global untuk mengakses, menghindari overhead pembuatan/koneksi setiap kali digunakan .
Jika parameternya true
, kapasitas kumpulan koneksi situs web tidak terbatas . Secara umum, tidak ada masalah, dan kumpulan koneksi dengan kapasitas tidak terbatas memiliki kinerja yang lebih baik.
Namun jika Anda menggunakannya sebagai layanan proxy perayap dan menemui sejumlah besar permintaan , jumlah klien di kumpulan koneksi akan meningkat tak terkendali dan cepat, bahkan melebihi jumlah koneksi maksimum yang diizinkan oleh situs web sumber yang Anda minta saat ini , Anda perlu use_pool
disetel ke nilai ideal (int). Saat ini, lapisan bawah akan menggunakan Saluran sebagai kumpulan koneksi. Ketika jumlah klien yang dibuat oleh kumpulan koneksi melebihi jumlah dan tidak cukup, coroutine yang perlu mengakses klien akan ditangguhkan. Dan tunggu coroutine yang menggunakan klien untuk mengembalikan klien. Hampir tidak ada konsumsi kinerja dalam menunggu dan beralih coroutine, dan ini adalah solusi yang sangat canggih .
Perlu dicatat bahwa kumpulan koneksi terikat ke服务器IP+端口
, artinya, jika Anda memiliki beberapa instance yang menghadapi服务器IP+端口
yang sama, kumpulan koneksi yang digunakan di antara keduanya juga sama.
Jadi ketika Anda berulang kali membuat instance服务器IP+端口
, use_pool
yang ditentukan oleh instance yang baru dibuat diizinkan untuk menimpa nilai sebelumnya, yaitu, lapisan bawah kumpulan koneksi secara otomatis mengubah kapasitasnya lapisan bawah akan membuat ulang kumpulan koneksi baru dan mentransfer pelanggan. Ketika kapasitas berkurang, kelebihan klien di kumpulan koneksi juga akan dimusnahkan.
Selain mengingat untuk mengkonfigurasi kumpulan koneksi, metode penanganan pengecualian juga harus sejalan dengan kebiasaan pemrograman Anda. Penanganan pengecualian default Saber
adalah抛出异常
yang paling umum dan ketat, tetapi Saber
juga mendukung penggunaan错误码
secara diam-diam错误码
dan状态位
, mungkin lebih sesuai dengan selera banyak orang.
SaberGM:: exceptionReport ( 0 ); // 关闭抛出异常报告, 在业务代码之前注册即可全局生效
$ saber -> exceptionReport ( 0 ); //也可以单独设置某个实例
Dengan cara yang sama, konfigurasi yang Anda inginkan dapat dikonfigurasi sebelumnya sebelum kode bisnis, seperti onWorkerStart
atau bahkan sebelum swoole_server
dimulai.
SaberGM:: default ([
' exception_report ' => 0
' use_pool ' => true
]);
Mengonfigurasi opsi yang Anda inginkan seperti ini dapat memberi Anda pengalaman yang lebih baik!
go ( function (){
// your code with pool ...
saber_pool_release (); // and this script will exit
});
Jika Anda menggunakan kumpulan koneksi dalam skrip satu kali, karena klien coroutine ada di kumpulan, jumlah referensi adalah 1 dan tidak dapat dilepaskan, yang akan menyebabkan swoole selalu berada di loop peristiwa dan skrip tidak dapat keluar dari Anda perlu memanggil saber_pool_release
secara manual Atau saber_exit
atau swoole_event_exit
untuk keluar secara normal, atau Anda dapat menggunakan exit untuk memaksa keluar dari skrip saat ini (jangan gunakan exit di server).
|
.simbol memisahkan beberapa nilai opsional
kunci | jenis | perkenalan | contoh | komentar |
---|---|---|---|---|
protokol_versi | rangkaian | Versi protokol HTTP | 1.1 | HTTP2 masih dalam perencanaan |
base_uri | rangkaian | jalur dasar | http://httpbin.org | Akan digabungkan dengan uri menurut rfc3986 |
uri | rangkaian | pengidentifikasi sumber daya | http://httpbin.org/get |. /get get | Jalur absolut dan relatif dapat digunakan |
uri_query | string|array | meminta informasi | ['foo' => 'bar'] | Non-string secara otomatis dikonversi |
metode | rangkaian | Metode permintaan | get | post delete head | patch put | Lapisan bawah secara otomatis diubah menjadi huruf besar |
header | susunan | tajuk permintaan | ['DNT' => '1'] |. ['accept' => ['text/html'], ['application/xml']] | Nama bidang tidak peka terhadap huruf besar-kecil, tetapi aturan huruf besar-kecil selama pengaturan akan dipertahankan. Setiap nilai bidang yang mendasarinya akan secara otomatis dibagi ke dalam array sesuai dengan PSR-7 |
kue | array | string | ['foo '=> 'bar'] |. 'foo=bar; foz=baz' | Lapisan bawah secara otomatis diubah menjadi objek Cookies, dan domainnya diatur ke URI saat ini, dengan atribut lengkap di tingkat browser. | |
agen pengguna | rangkaian | agen pengguna | curl-1.0 | Standarnya adalah chrome pada platform macOS |
referensi | rangkaian | Alamat sumber | https://www.google.com | Standarnya kosong |
mengarahkan ulang | ke dalam | Jumlah maksimum pengalihan | 5 | Standarnya adalah 3, dan jika 0, tidak ada pengalihan. |
tetap_hidup | bodoh | Apakah akan tetap terhubung | true |. false | Standarnya adalah benar, koneksi akan digunakan kembali secara otomatis selama pengalihan |
tipe_konten | rangkaian | Jenis pengkodean konten dikirim | text/plain | SwlibHttpContentType::JSON | Standarnya adalah application/x-www-form-urlencoded |
data | array | string | data terkirim | 'foo=bar&dog=cat' | ['foo' => 'bar'] | Data akan secara otomatis dikodekan berdasarkan content_type |
sebelum | callable | array | Pencegat pra-permintaan | function(Request $request){} | Silakan merujuk ke bagian Interceptor untuk detailnya. |
setelah | callable | array | Pencegat pasca-respons | function(Response $response){} | Silakan merujuk ke bagian Interceptor untuk detailnya. |
sebelum_redirect | callable | array | Pencegat pasca-pengalihan | function(Request $request, Response $response){} | Silakan merujuk ke bagian Interceptor untuk detailnya. |
batas waktu | mengambang | batas waktu | 0,5 | Defaultnya adalah 5 detik, mendukung batas waktu milidetik |
bind_address | rangkaian | Ikat alamat | 192.168.1.1 atau eth0 | Tidak disetel secara default |
ikat_port | ke dalam | Ikat pelabuhan | 80 | Tidak disetel secara default |
proksi | rangkaian | akting | http://127.0.0.1:1087 |. socks5://127.0.0.1:1087 | Mendukung http dan kaus kaki5 |
sl | ke dalam | Apakah akan mengaktifkan koneksi SSL | 0=关闭 1=开启 2=自动 | Otomatis bawaan |
cafile | rangkaian | file ca | __DIR__ . '/cacert.pem' | Dilengkapi dengan bawaan |
ssl_verify_peer | bodoh | Verifikasi sertifikat sisi server | false | true | Mati secara default |
ssl_allow_self_signed | bodoh | Izinkan sertifikat yang ditandatangani sendiri | true |. false | Diizinkan secara default |
ssl_cert_file | rangkaian | sertifikat sertifikat | __DIR__ . '/ssl.cert' | Tidak disetel secara default |
ssl_key_file | rangkaian | kunci kunci pribadi | __DIR__ . '/ssl.key' | Tidak disetel secara default |
ikonv | susunan | Tentukan konversi pengkodean | ['gbk', 'utf-8'] | Ada tiga parameter total: from,to,use_mb , yang secara otomatis dikenali secara default. |
pengecualian_laporan | ke dalam | Tingkat pelaporan pengecualian | HttpExceptionMask::E_ALL | Laporkan semua pengecualian secara default |
pengecualian_pegangan | dapat dipanggil|array | Fungsi penanganan khusus pengecualian | function(Exception $e){} | Kesalahan dapat diabaikan ketika fungsi mengembalikan nilai true |
mencoba kembali | dapat dipanggil | Pencegat coba ulang otomatis | function(Request $request, Response $response){} | Setelah terjadi kesalahan dan sebelum mencoba kembali |
coba lagi_waktu | ke dalam | Jumlah percobaan ulang otomatis | Jangan mencoba lagi secara default | |
use_pool | bodoh|int | kumpulan koneksi | true | false |
kunci_kolam | dapat dipanggil|array | Kunci kumpulan koneksi | function(Request $request):string { return $key; } | Standarnya adalah host:port dari alamat yang diminta |
Untuk kemudahan penggunaan dan toleransi kesalahan, nilai kunci item konfigurasi memiliki mekanisme alias. Disarankan untuk menggunakan nama asli sebanyak mungkin:
kunci | alias |
---|---|
metode | 0 |
uri | 1 | url |
data | 2 |. body |
base_uri | base_url |
setelah | panggilan balik |
tipe_konten | content-type | contentType |
kue | kue |
header | tajuk |
mengarahkan ulang | mengikuti |
agen pengguna | ua | user-agent |
pengecualian_laporan | error_report | report |
sebelum_coba lagi | mencoba kembali |
referensi | ref | referrer |
Pencegat adalah fitur Sabre yang sangat kuat , yang memungkinkan Anda menangani berbagai hal dengan sangat mudah, seperti mencetak log pengembang:
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
Bahkan异常自定义处理函数
dan会话
penanganan pengecualian khusus diimplementasikan melalui interseptor.
Mungkin ada beberapa pencegat, yang akan dieksekusi dalam urutan registrasi, dan Anda dapat memberi nama pencegat tersebut . Anda hanya perlu membungkusnya dengan array dan menentukan nilai kuncinya nilai nol.
[
' after ' => [
' interceptor_new ' => function (){},
' interceptor_old ' => null
]
]
Interceptor dapat didaftarkan dengan empat cara (4 fungsi panggilan balik PHP):
callable: function (){}
string: ' function_name '
string: ' ClassName::method_name '
array: [ $ object , ' method_name ' ]
Penerapan Cookie selesai di tingkat browser . Ini secara khusus mengacu pada penerapan browser Chrome dan mengikuti aturan yang relevan.
Cookie adalah kumpulan cookie, dan setiap cookie memiliki properti berikut:
name
, value
, expires
, path
, session
, secure
, httponly
, hostonly
Dan kelas Cookies mendukung konversi berbagai format, seperti
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']
Tunggu hingga format ditransfer ke kelas Cookie, atau kelas Cookie diserialkan ke dalam format ini.
Cookie juga mendukung verifikasi nama domain dan batas waktu tanpa kehilangan informasi apa pun. Misalnya, jika domainnya adalah github.com
, cookie tidak akan muncul di help.github.com
kecuali domain tersebut bukan hanya host (karakter pengganti .github.com
).
Jika itu adalah cookie sesi (tidak memiliki waktu kedaluwarsa dan kedaluwarsa ketika browser ditutup), atribut expired akan disetel ke waktu saat ini, dan Anda dapat menyetel waktu tertentu melalui interseptor .
Dengan membaca atribut mentah Cookies, maka dapat dengan mudah disimpan ke database , yang sangat cocok untuk aplikasi crawler login.
Untuk lebih jelasnya, silakan lihat dokumentasi dan contoh perpustakaan Swlib/Http.
Sabre mengikuti aturan memisahkan bisnis dari kesalahan . Ketika ada bagian dari permintaan yang gagal, pengecualian akan diberikan secara default .
Yang hebatnya adalah penanganan pengecualian Sabre juga beragam dan selengkap penanganan pengecualian asli PHP.
Namespace pengecualian terletak di SwlibHttpException
Pengecualian | Pendahuluan | pemandangan |
---|---|---|
PermintaanPengecualian | Permintaan gagal | Kesalahan konfigurasi permintaan |
HubungkanPengecualian | Koneksi gagal | Jika tidak ada koneksi jaringan, permintaan DNS gagal, batas waktu habis, dll., nilai errno sama dengan Linux errno. Anda dapat menggunakan swoole_strerror untuk mengubah kode kesalahan menjadi pesan kesalahan. |
TooManyRedirectsException | Jumlah pengalihan terlampaui | Jumlah pengalihan melebihi batas yang ditetapkan, dan pengecualian yang diberikan akan mencetak informasi pelacakan pengalihan. |
Pengecualian Klien | Pengecualian klien | Server mengembalikan kode kesalahan 4xx |
Pengecualian Server | Pengecualian server | Server mengembalikan kode kesalahan 5xx |
Pengecualian Respons Buruk | Gagal menerima respons tidak diketahui | Server tidak merespons atau mengembalikan kode kesalahan yang tidak dikenal. |
Selain metode pengecualian umum, semua kelas pengecualian HTTP juga memiliki metode berikut:
Metode | Pendahuluan |
---|---|
dapatkan Permintaan | Dapatkan contoh permintaan |
memilikiRespon | Apakah akan mendapat tanggapan |
dapatkan Respons | Dapatkan contoh respons |
dapatkanResponseBodySummary | Dapatkan konten ringkasan dari isi respons |
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
Pada saat yang sama, Sabre juga mendukung penanganan pengecualian dengan cara yang lembut, untuk mencegah pengguna menjadi panik di lingkungan jaringan yang tidak stabil dan harus membungkus kode dengan try di setiap langkah:
Tetapkan tingkat errorReport, yang efektif secara global dan tidak akan berpengaruh pada instance yang dibuat .
// 启用所有异常但忽略重定向次数过多异常
SaberGM:: exceptionReport (
HttpExceptionMask:: E_ALL ^ HttpExceptionMask:: E_REDIRECT
);
Nilai-nilai berikut (numerik atau simbolik) digunakan untuk membuat bitmask yang menentukan pesan kesalahan yang akan dilaporkan. Anda dapat menggunakan operator bitwise untuk menggabungkan nilai-nilai ini atau untuk menutupi jenis kesalahan tertentu. Bendera dan topeng
Masker | Nilai | Pendahuluan |
---|---|---|
E_TIDAK ADA | 0 | abaikan semua pengecualian |
E_PERMINTAAN | 1 | Sesuai dengan RequestException |
E_CONNECT | 2 | Sesuai dengan RequestException |
E_REDIRECT | 4 | Sesuai dengan RequestException |
E_BAD_RESPONSE | 8 | Sesuai dengan BadRException |
E_KLIEN | 16 | Sesuai dengan ClientException |
E_SERVER | 32 | Sesuai dengan ServerException |
E_SEMUA | 63 | Semua pengecualian |
Fungsi ini dapat menangani kesalahan yang dihasilkan dalam permintaan HTTP dengan cara Anda sendiri, dan Anda dapat menentukan pengecualian yang ingin Anda tangkap/abaikan dengan lebih bebas.
Catatan: Kecuali jika fungsi mengembalikan TRUE (atau nilai sebenarnya lainnya), pengecualian akan terus dilempar alih-alih ditangkap oleh fungsi khusus.
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 !
Unggah Berkas | soket web | Parser Otomatis | Coba Ulang Otomatis | Unduh File Besar | Cache | Kolam Klien | AcakUA |
---|---|---|---|---|---|---|---|
4 (Prioritas tinggi) | 3 | 2 | 1 | .5 | .5 | .5 | .175 |
Karena manfaat utama HTTP/2 adalah memungkinkan multiplexing banyak permintaan dalam satu koneksi, sehingga [hampir] menghilangkan batasan jumlah permintaan simultan - dan tidak ada batasan seperti itu ketika berbicara dengan backend Anda sendiri menjadi lebih buruk ketika menggunakan HTTP/2 ke backend, karena koneksi TCP tunggal digunakan dan bukan beberapa koneksi, jadi Http2 tidak akan menjadi prioritas (#ref)
Tambahkan file sumber proyek ini ke Include Path
IDE.
(Jika diinstal menggunakan composer, Anda dapat menyertakan seluruh folder vendor, dan PHPStorm akan otomatis menyertakannya)
Penulisan komentar yang baik membuat Sabre mendukung perintah otomatis IDE dengan sempurna. Cukup tulis simbol panah setelah objek untuk melihat semua nama metode objek. Banyak metode mengikuti spesifikasi PSR atau diimplementasikan dengan mengacu pada Proyek Guzzle (terima kasih).
Untuk petunjuk IDE pada kelas terkait Swoole yang mendasarinya, Anda perlu memperkenalkan swoole-ide-helper eaglewu (komposer akan diinstal secara default di lingkungan pengembang). Namun, proyek ini dikelola secara manual dan belum selesai -ide-pembantu atau:
Pembantu ide resmi Swoole.
Selamat datang untuk menyampaikan isu dan PR.
Karena coroutine (__call, __callStatic) tidak dapat digunakan dalam metode ajaib, metode dalam kode sumber ditentukan secara manual.
Untuk kemudahan penggunaan, alias telah disediakan untuk semua metode permintaan yang didukung.
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()