HTTP Sabre (Da Mao Wang)، عميل HTTP عالي الأداء PHP Swoole人性化组件库
، يعتمد على coroutine الأصلي لـ Swoole، ويدعم أنماطًا متعددة من العمليات، ويوفر حلولًا عالية الأداء في الأسفل، مما يسمح للمطورين بالتركيز على الوظائف. التنمية، من التقليدية خالية من الحظر المتزامن والتكوين المرهق لـ Curl.
وثيقة باللغة الإنجليزية
أفضل طريقة للتثبيت هي من خلال مدير حزم Composer:
composer require swlib/saber
تطبق الطبقة السفلية من Swoole جدولة coroutine، ولا تحتاج طبقة الأعمال إلى الوعي . يمكن للمطورين استخدام كتابة التعليمات البرمجية المتزامنة لتحقيق تأثير الإدخال/الإخراج غير المتزامن والأداء العالي دون إدراك ذلك، وتجنب منطق التعليمات البرمجية المنفصلة. تتسبب عمليات الاسترجاعات غير المتزامنة التقليدية في تعويض اللون بشكل مفرط في عدم إمكانية صيانة التعليمات البرمجية.
يجب استخدامه في 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 ' ]);
ستقوم الجلسة تلقائيًا بحفظ معلومات ملفات تعريف الارتباط، ويكتمل تنفيذها على مستوى المتصفح.
$ 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 ;
يمكن أن تدعم جدولة coroutine التلقائية الأساسية الإرسال غير المتزامن للملفات الكبيرة جدًا ونقل استئناف نقطة التوقف.
تحميل ثلاثة ملفات في نفس الوقت (
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
]
]
);
بعد أن يتلقى التنزيل البيانات، سيتم كتابتها مباشرة على القرص بشكل غير متزامن بدلاً من ربط HttpBody في الذاكرة، لذلك يستخدم التنزيل فقط كمية صغيرة من الذاكرة لإكمال تنزيل الملفات الكبيرة جدًا ، كما أنه يدعم استئناف التنزيل بنقطة التوقف ضبط معلمة الإزاحة لإجراء تنزيلات نقطة التوقف.
تنزيل غير متزامن لخلفيات 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 لتكوين الطلبات، لذلك يتم توفير طريقة القائمة للراحة:
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). في هذا الوقت، ستستخدم الطبقة السفلية القناة كتجمع اتصال التي تحتاج إلى الوصول إلى العميل سيتم تعليقها. وانتظر حتى يقوم الكوروتين الذي يستخدم العميل بإرجاع العميل، ولا يوجد تقريبًا أي استهلاك للأداء في انتظار وتبديل الكوروتين، وهو حل متقدم للغاية .
تجدر الإشارة إلى أن تجمع الاتصال مرتبط服务器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
});
إذا كنت تستخدم تجمع اتصال في برنامج نصي لمرة واحدة، نظرًا لوجود عميل coroutine في التجمع، فإن عدد المرجع هو 1 ولا يمكن تحريره، مما سيؤدي إلى تواجد swoole دائمًا في حلقة الحدث ولا يمكن للبرنامج النصي الخروج منك تحتاج إلى الاتصال يدويًا saber_pool_release
أو saber_exit
أو swoole_event_exit
للخروج بشكل طبيعي، أو يمكنك استخدام الخروج لفرض الخروج من البرنامج النصي الحالي (لا تستخدم الخروج في الخادم).
|
يفصل الرمز بين القيم الاختيارية المتعددة
مفتاح | يكتب | مقدمة | مثال | ملاحظة |
---|---|---|---|---|
Protocol_version | خيط | إصدار بروتوكول HTTP | 1.1 | HTTP2 لا يزال قيد التخطيط |
base_uri | خيط | المسار الأساسي | http://httpbin.org | سيتم دمجه مع uri وفقًا لـ rfc3986 |
أوري | خيط | معرف الموارد | http://httpbin.org/get get /get | يمكن استخدام كل من المسارات المطلقة والنسبية |
uri_query | سلسلة|صفيف | طلب المعلومات | ['foo' => 'bar'] | يتم تحويل غير السلاسل تلقائيًا |
طريقة | خيط | طريقة الطلب | get post delete head patch put | يتم تحويل الطبقة السفلية تلقائيًا إلى أحرف كبيرة |
رؤوس | صفيف | رأس الطلب | ['DNT' => '1'] | ['accept' => ['text/html'], ['application/xml']] | أسماء الحقول ليست حساسة لحالة الأحرف، ولكن سيتم الاحتفاظ بقواعد الحالة الأصلية أثناء الإعداد وسيتم تقسيم كل قيمة حقل أساسية تلقائيًا إلى صفائف وفقًا لـ PSR-7 |
ملفات تعريف الارتباط | array string | ['foo '=> 'bar'] |. 'foo=bar; foz=baz' | يتم تحويل الطبقة السفلية تلقائيًا إلى كائن ملفات تعريف الارتباط، ويتم تعيين مجالها على URI الحالي، مع سمات كاملة على مستوى المتصفح. | |
com.useragent | خيط | وكيل المستخدم | curl-1.0 | الإعداد الافتراضي هو chrome على نظام macos الأساسي |
مرجع | خيط | عنوان المصدر | https://www.google.com | الافتراضي فارغ |
إعادة توجيه | كثافة العمليات | الحد الأقصى لعدد عمليات إعادة التوجيه | 5 | القيمة الافتراضية هي 3، وعندما تكون 0، لا توجد إعادة توجيه. |
keep_alive | منطقي | سواء للبقاء على اتصال | true false | الافتراضي هو صحيح، سيتم إعادة استخدام الاتصال تلقائيًا أثناء إعادة التوجيه |
content_type | خيط | تم إرسال نوع ترميز المحتوى | text/plain | SwlibHttpContentType::JSON | الافتراضي هو application/x-www-form-urlencoded |
بيانات | array string | البيانات المرسلة | 'foo=bar&dog=cat' ['foo' => 'bar'] . | سيتم ترميز البيانات تلقائيًا استنادًا إلى content_type |
قبل | array callable | | اعتراض الطلب المسبق | function(Request $request){} | يرجى الرجوع إلى قسم المعترض للحصول على التفاصيل. |
بعد | array callable | | اعتراضية ما بعد الاستجابة | function(Response $response){} | يرجى الرجوع إلى قسم المعترض للحصول على التفاصيل. |
before_redirect | array callable | | اعتراضية ما بعد إعادة التوجيه | function(Request $request, Response $response){} | يرجى الرجوع إلى قسم المعترض للحصول على التفاصيل. |
نفذ الوقت | يطفو | نفذ الوقت | 0.5 | الافتراضي هو 5 ثوان، ويدعم المهلة بالمللي ثانية |
bind_address | خيط | ربط العنوان | 192.168.1.1 أو eth0 | لم يتم تعيينه بشكل افتراضي |
bind_port | كثافة العمليات | ربط المنفذ | 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' | لم يتم تعيينه بشكل افتراضي |
iconv | صفيف | تحديد تحويل الترميز | ['gbk', 'utf-8'] | هناك ثلاث معاملات في المجمل: from,to,use_mb ، والتي يتم التعرف عليها تلقائيًا بشكل افتراضي. |
Exception_report | كثافة العمليات | مستوى الإبلاغ عن الاستثناء | HttpExceptionMask::E_ALL | الإبلاغ عن كافة الاستثناءات بشكل افتراضي |
Exception_handle | قابل للاستدعاء|صفيف | وظيفة معالجة الاستثناءات المخصصة | function(Exception $e){} | يمكن تجاهل الأخطاء عندما ترجع الدالة صحيحًا |
أعد المحاولة | قابل للاستدعاء | إعادة المحاولة التلقائية | function(Request $request, Response $response){} | بعد حدوث خطأ وقبل إعادة المحاولة |
retry_time | كثافة العمليات | إعادة المحاولة التلقائية | لا تقم بإعادة المحاولة بشكل افتراضي | |
use_pool | منطقي | كثافة العمليات | تجمع الاتصال | true | false |
Pool_key | قابل للاستدعاء|صفيف | مفتاح تجمع الاتصال | function(Request $request):string { return $key; } | الافتراضي هو host:port العنوان المطلوب |
لسهولة الاستخدام والتسامح مع الأخطاء، تحتوي القيم الأساسية لعناصر التكوين على آلية اسم مستعار، ويوصى باستخدام الاسم الأصلي قدر الإمكان:
مفتاح | الاسم المستعار |
---|---|
طريقة | 0 |
أوري | 1 url |
بيانات | 2 body |
base_uri | base_url |
بعد | أتصل مرة أخرى |
content_type | content-type | contentType |
ملفات تعريف الارتباط | ملفات تعريف الارتباط |
رؤوس | header |
إعادة توجيه | يتبع |
com.useragent | ua | user-agent |
Exception_report | error_report 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 ' ]
اكتمل تنفيذ ملف تعريف الارتباط على مستوى المتصفح ، وهو يشير على وجه التحديد إلى تنفيذ متصفح Chrome ويتبع القواعد ذات الصلة.
ملفات تعريف الارتباط هي مجموعة من ملفات تعريف الارتباط، ولكل ملف تعريف ارتباط الخصائص التالية:
name
value
expires
path
session
secure
httponly
hostonly
وتدعم فئة ملفات تعريف الارتباط تحويل تنسيقات متعددة، مثل
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']
انتظر حتى يتم نقل التنسيق إلى فئة ملفات تعريف الارتباط، أو يتم إجراء تسلسل لفئة ملفات تعريف الارتباط في هذه التنسيقات.
تدعم ملفات تعريف الارتباط أيضًا التحقق من اسم النطاق والحد الزمني دون فقدان أي معلومات، على سبيل المثال، إذا كان المجال هو github.com
، فلن يظهر ملف تعريف الارتباط في help.github.com
إلا إذا لم يكن المجال مضيفًا فقط ( .github.com
بدل).
إذا كان ملف تعريف ارتباط جلسة (ليس له وقت انتهاء الصلاحية وينتهي عند إغلاق المتصفح)، فسيتم تعيين سمة انتهاء الصلاحية على الوقت الحالي، ويمكنك تعيين وقت محدد من خلال المعترض .
من خلال قراءة السمة الأولية لملفات تعريف الارتباط، يمكن بسهولة الاحتفاظ بها في قاعدة البيانات ، وهي مناسبة جدًا لتطبيقات زاحف تسجيل الدخول.
لمزيد من التفاصيل، يرجى الرجوع إلى وثائق وأمثلة مكتبة Swlib/Http.
يتبع Sabre قاعدة فصل الأعمال عن الأخطاء . عند فشل أي جزء من الطلب، سيتم طرح استثناء بشكل افتراضي .
الأمر القوي هو أن معالجة الاستثناءات في Sabre متنوعة أيضًا وكاملة مثل معالجة الاستثناءات الأصلية في PHP.
توجد مساحة اسم الاستثناء في SwlibHttpException
استثناء | مقدمة | مشهد |
---|---|---|
طلب استثناء | فشل الطلب | خطأ في تكوين الطلب |
ConnectException | فشل الاتصال | إذا لم يكن هناك اتصال بالشبكة، أو فشل استعلام DNS، أو انتهت المهلة، وما إلى ذلك، فإن قيمة errno تساوي Linux errno. يمكنك استخدام swoole_strerror لتحويل رموز الخطأ إلى رسائل خطأ. |
TooManyRedirectsException | تم تجاوز عدد عمليات إعادة التوجيه | يتجاوز عدد عمليات إعادة التوجيه الحد المحدد، وسيؤدي الاستثناء الذي تم طرحه إلى طباعة معلومات تتبع إعادة التوجيه. |
ClientException | استثناء العميل | قام الخادم بإرجاع رمز خطأ 4xx |
استثناء الخادم | استثناء الخادم | قام الخادم بإرجاع رمز خطأ 5xx |
BadResponseException | فشل الحصول على استجابة غير معروف | لم يستجب الخادم أو قام بإرجاع رمز خطأ غير معروف. |
بالإضافة إلى أساليب الاستثناء العامة، تحتوي جميع فئات استثناءات HTTP أيضًا على الطرق التالية:
طريقة | مقدمة |
---|---|
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
في الوقت نفسه، يدعم Sabre أيضًا التعامل مع الاستثناءات بطريقة لطيفة، وذلك لمنع المستخدمين من الوقوع في حالة من الذعر في بيئات الشبكة غير المستقرة والاضطرار إلى تغليف التعليمات البرمجية مع المحاولة في كل خطوة:
قم بتعيين مستوى errorReport، وهو فعال عالميًا ولن يسري مفعوله على المثيلات التي تم إنشاؤها .
// 启用所有异常但忽略重定向次数过多异常
SaberGM:: exceptionReport (
HttpExceptionMask:: E_ALL ^ HttpExceptionMask:: E_REDIRECT
);
يتم استخدام القيم التالية (رقمية أو رمزية) لإنشاء قناع بت يحدد رسالة الخطأ التي سيتم الإبلاغ عنها. يمكنك استخدام معاملات البت لدمج هذه القيم أو لإخفاء أنواع معينة من الأخطاء. أعلام وأقنعة
قناع | قيمة | مقدمة |
---|---|---|
E_NONE | 0 | تجاهل كافة الاستثناءات |
طلب E_REQUEST | 1 | يتوافق مع RequestException |
E_CONNECT | 2 | يتوافق مع RequestException |
E_REDIRECT | 4 | يتوافق مع RequestException |
E_BAD_RESPONSE | 8 | يتوافق مع BadRException |
E_CLIENT | 16 | يتوافق مع ClientException |
الخادم الإلكتروني | 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 !
تحميل الملف | WebSockets | محلل تلقائي | إعادة المحاولة التلقائية | تحميل الملف الكبير | مخبأ | ClientPool | RandomUA |
---|---|---|---|---|---|---|---|
4 (أولوية عالية) | 3 | 2 | 1 | .5 | .5 | .5 | .175 |
نظرًا لأن الفائدة الرئيسية لـ HTTP/2 هي أنه يسمح بتعدد إرسال العديد من الطلبات ضمن اتصال واحد، وبالتالي يتم إزالة الحد الأقصى لعدد الطلبات المتزامنة [تقريبًا] - ولا يوجد مثل هذا الحد عند التحدث إلى الواجهات الخلفية الخاصة بك، علاوة على ذلك، قد تكون الأمور كذلك يصبح أسوأ عند استخدام HTTP/2 للواجهات الخلفية، نظرًا لاستخدام اتصال TCP واحد بدلاً من اتصالات متعددة، لذلك لن يكون Http2 أولوية (#ref)
قم بإضافة الملفات المصدر لهذا المشروع إلى Include Path
الخاص بـ IDE.
(إذا تم التثبيت باستخدام الملحن، فيمكنك تضمين مجلد البائع بأكمله، وسيقوم PHPStorm بتضمينه تلقائيًا)
كتابة التعليقات الجيدة تجعل Sabre يدعم بشكل مثالي المطالبات التلقائية لـ IDE، ما عليك سوى كتابة رمز السهم بعد الكائن لعرض أسماء جميع أساليب الكائنات، ومن السهل جدًا فهمها مشروع غزالة (شكرا).
بالنسبة لمطالبات IDE للفئات الأساسية المرتبطة بـ Swoole، تحتاج إلى تقديم مساعد eaglewu's swoole-ide (سيتم تثبيت الملحن افتراضيًا في بيئة التطوير، ومع ذلك، تتم صيانة هذا المشروع يدويًا ولم يكتمل. يمكنك أيضًا استخدام swoft -ide-مساعد أو:
مساعد Swoole الرسمي.
مرحبا بكم في تقديم القضايا والعلاقات العامة.
نظرًا لأنه لا يمكن استخدام coroutines (__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()