HTTP Sabre (Da Mao Wang), un cliente HTTP PHP de alto rendimiento de Swoole人性化组件库
, se basa en la rutina nativa de Swoole, admite múltiples estilos de operaciones y proporciona soluciones de alto rendimiento en la parte inferior, lo que permite a los desarrolladores centrarse en funciones. desarrollo, desde tradicional Libre del bloqueo sincrónico y la configuración engorrosa de Curl.
Documento en inglés
La mejor forma de instalarlo es a través del administrador de paquetes de Composer:
composer require swlib/saber
La capa inferior de Swoole implementa la programación de rutinas, y la capa empresarial no necesita ser consciente . Los desarrolladores pueden usar la escritura de código sincrónico para lograr el efecto de IO asíncrono y un rendimiento ultra alto sin darse cuenta, evitando la lógica del código discreto. La captura excesiva causada por las devoluciones de llamadas asincrónicas tradicionales hace que el código no se pueda mantener.
Debe usarse en onRequet
, onReceive
, onConnect
y otras funciones de devolución de llamada de eventos, o incluirse con la palabra clave go ( swoole.use_shortname
está habilitado de forma predeterminada).
go ( function () {
echo SaberGM:: get ( ' http://httpbin.org/get ' );
})
Empaquetado automático de datos: los datos entrantes se convertirán automáticamente al formato de tipo especificado por tipo de contenido.
El valor predeterminado es
x-www-form-urlencoded
y también se admiten otros formatos comojson
.
SaberGM
: = Saber Global Manager
. Si cree que el nombre de la clase es un poco largo, puede usar class_alias
para elegir un alias usted mismo. Se recomienda utilizar el método de generación de instancias en el servicio y utilizar SaberGM
como acceso directo.
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 ' ]);
Servicio de proxy API aplicable
$ 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 ' ]);
La sesión guardará automáticamente la información de las cookies y su implementación se completará a nivel del navegador.
$ 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 ;
Nota: Aquí se utiliza una solución de optimización de redirecciones simultáneas. Las redirecciones múltiples siempre son simultáneas y no degenerarán en una sola solicitud en la cola.
$ 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 ' ]
]);
Actualmente admite el análisis rápido de datos en cuatro formatos: json
, xml
, html
y 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 );
Admite servidores proxy HTTP y 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 ;
La programación automática de rutinas subyacente puede admitir el envío asincrónico de archivos muy grandes y la transmisión de reanudación de puntos de interrupción.
Cargue tres archivos al mismo tiempo (tres estilos de parámetros
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
]
]
);
Después de que Download reciba los datos, los escribirá directamente en el disco de forma asincrónica en lugar de empalmar el HttpBody en la memoria. Por lo tanto, la descarga solo usa una pequeña cantidad de memoria para completar la descarga de archivos muy grandes . También admite la descarga reanudada por punto de interrupción. configurar el parámetro de compensación para realizar descargas de puntos de interrupción.
Descarga asincrónica de fondos de pantalla de 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 );
}
En proyectos de rastreadores, es un requisito muy común reintentar automáticamente una solicitud fallida, como iniciar sesión nuevamente después de que expire una sesión.
Saber
tiene esta funcionalidad incorporada y se pueden usar拦截器
para mejorarla.
Si no se establece retry_time
pero se establece un interceptor retry
, retry_time
se establecerá en 1. Si el método de devolución de llamada del interceptor retry
devuelve false
, no importa cuál sea retry_time
, el reintento finalizará cuando se devuelva 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 ;
A veces, los recursos HTTP no siempre cambian. Podemos aprender cómo los navegadores almacenan en caché los recursos que no cambian para acelerar la eficiencia de las solicitudes. Saber
completa esto automáticamente sin tener que mantener la lógica de almacenamiento en caché (CURD o lectura y escritura de archivos) por sí solo. De todos modos, no bloqueará el servidor. Saber
no usa un mecanismo de middleware porque está fuertemente relacionado con Swoole, pero el almacenamiento en caché puede usar内存/文件/数据库
y otros métodos, por lo que, aunque aún no se ha implementado, estará incluido en Saber
La hoja de ruta posterior.
$ 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 ();
Puede imprimir directamente la cadena de datos devuelta a través del método __toString del marco de datos websocketFrame.
$ websocket = SaberGM:: websocket ( ' ws://127.0.0.1:9999 ' );
while ( true ) {
echo $ websocket -> recv ( 1 ) . "n" ;
$ websocket -> push ( " hello " );
co:: sleep ( 1 );
}
La máquina de prueba es una MacBook Pro con la configuración más baja y el servidor de solicitudes es un servidor de eco local.
Completó 6666 solicitudes en 0,9 segundos , con una tasa de éxito del 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
En proyectos reales, las listas de URL se utilizan a menudo para configurar solicitudes, por lo que se proporciona el método de lista para mayor comodidad:
echo SaberGM:: list ([
' uri ' => [
' https://www.qq.com/ ' ,
' https://www.baidu.com/ ' ,
' https://www.swoole.com/ ' ,
' http://httpbin.org/ '
]
]);
En proyectos de rastreadores reales, a menudo tenemos que limitar la cantidad de solicitudes simultáneas individuales para evitar que el firewall del servidor las bloquee, y un parámetro max_co
puede resolver fácilmente este problema. max_co
enviará las solicitudes a la cola en lotes de acuerdo con el límite superior. y ejecutarlos. Recibir paquete.
// 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" ;
Cuando se utiliza en un servidor residente en memoria, asegúrese de habilitar manualmente la opción del grupo de conexiones :
$ swoole = Saber:: create ([
' base_uri ' => ' https://www.swoole.com/ ' ,
' use_pool ' => true
]);
Cuando se usa a través de esta instancia, se habilitará la función del grupo de conexiones, es decir, el cliente de conexión subyacente con el sitio web www.swoole.com
utilizará un grupo de conexiones global para acceder, evitando la sobrecarga de crear/conectar cada vez que se usa. .
Cuando el parámetro es true
, la capacidad del grupo de conexiones del sitio web es ilimitada . Generalmente no hay problema y el grupo de conexiones con capacidad ilimitada tiene mejor rendimiento.
Pero si lo usa como un servicio de proxy de rastreador y encuentra una gran cantidad de solicitudes , la cantidad de clientes en el grupo de conexiones aumentará de manera incontrolable y rápida, incluso excediendo la cantidad máxima de conexiones permitidas por el sitio web de origen que solicitó en este momento. , debe configurar use_pool
en un valor ideal (int). En este momento, la capa inferior usará Channel como grupo de conexiones. Cuando la cantidad de clientes creados por el grupo de conexiones excede el número y no es suficiente, la corrutina. que necesite acceder al cliente será suspendido. Y espere a que la rutina que está utilizando el cliente devuelva el cliente. Casi no hay consumo de rendimiento en la espera y el cambio de rutina, y es una solución muy avanzada .
Cabe señalar que el grupo de conexiones está vinculado al服务器IP+端口
, es decir, si tiene varias instancias frente al mismo服务器IP+端口
, el grupo de conexiones utilizado entre ellas también es el mismo.
Entonces, cuando crea repetidamente una instancia de服务器IP+端口
, use_pool
especificado por la instancia recién creada puede sobrescribir el valor anterior, es decir, la capa inferior del grupo de conexiones cambia automáticamente su capacidad. La capa inferior volverá a crear un nuevo grupo de conexiones y transferirá clientes. Cuando se reduzca la capacidad, el exceso de clientes en el grupo de conexiones también se destruirá.
Además de recordar configurar un grupo de conexiones, el método de manejo de excepciones también debe estar en línea con sus hábitos de programación. El manejo de excepciones predeterminado de Saber
es el método抛出异常
más común y riguroso, pero Saber
también admite el uso silencioso de错误码
y状态位
, puede estar más acorde con los gustos de muchas personas.
SaberGM:: exceptionReport ( 0 ); // 关闭抛出异常报告, 在业务代码之前注册即可全局生效
$ saber -> exceptionReport ( 0 ); //也可以单独设置某个实例
De la misma manera, la configuración que desee se puede preconfigurar antes del código comercial, como onWorkerStart
o incluso antes de que se inicie swoole_server
.
SaberGM:: default ([
' exception_report ' => 0
' use_pool ' => true
]);
¡Configurar las opciones deseadas como esta puede brindarle una mejor experiencia!
go ( function (){
// your code with pool ...
saber_pool_release (); // and this script will exit
});
Si utiliza un grupo de conexiones en un script de un solo uso, dado que el cliente de rutina existe en el grupo, el recuento de referencias es 1 y no se puede liberar, lo que hará que swoole siempre esté en el bucle de eventos y el script no pueda salir. debe llamar manualmente saber_pool_release
O saber_exit
o swoole_event_exit
para salir normalmente, o puede usar exit para forzar la salida del script actual (no use exit en el servidor).
|
símbolo separa múltiples valores opcionales
llave | tipo | introducción | ejemplo | observación |
---|---|---|---|---|
versión_protocolo | cadena | Versión del protocolo HTTP | 1.1 | HTTP2 todavía está en planificación |
base_uri | cadena | camino base | http://httpbin.org | Se fusionará con uri según rfc3986 |
uri | cadena | identificador de recursos | http://httpbin.org/get | /get get | Se pueden utilizar rutas absolutas y relativas. |
consulta_uri | cadena|matriz | solicitar informacion | ['foo' => 'bar'] | Las no cadenas se convierten automáticamente |
método | cadena | Método de solicitud | get | post | head delete patch put | La capa inferior se convierte automáticamente a mayúsculas. |
encabezados | formación | encabezado de solicitud | ['DNT' => '1'] | ['accept' => ['text/html'], ['application/xml']] | Los nombres de los campos no distinguen entre mayúsculas y minúsculas, pero se conservarán las reglas de mayúsculas y minúsculas originales durante la configuración. Cada valor de campo subyacente se dividirá automáticamente en matrices de acuerdo con PSR-7. |
galletas | array | string | ['foo '=> 'bar'] | 'foo=bar; foz=baz' | La capa inferior se convierte automáticamente en un objeto Cookies y su dominio se establece en el URI actual, con atributos completos en el nivel del navegador. | |
agente de usuario | cadena | agente de usuario | curl-1.0 | El valor predeterminado es Chrome en la plataforma macOS. |
árbitro | cadena | Dirección de origen | https://www.google.com | El valor predeterminado está vacío |
redirigir | entero | Número máximo de redirecciones | 5 | El valor predeterminado es 3 y cuando es 0, no hay redirección. |
mantener_alive | booleano | Ya sea para mantenerse conectado | true | false | El valor predeterminado es verdadero, la conexión se reutilizará automáticamente durante la redirección |
tipo de contenido | cadena | Tipo de codificación de contenido enviado | text/plain | SwlibHttpContentType::JSON | El valor predeterminado es aplicación/x-www-form-urlencoded |
datos | array | string | datos enviados | 'foo=bar&dog=cat' | ['foo' => 'bar'] | Los datos se codificarán automáticamente según el tipo de contenido. |
antes | callable | array | Interceptor de solicitud previa | function(Request $request){} | Consulte la sección Interceptor para obtener más detalles. |
después | callable | array | Interceptor posterior a la respuesta | function(Response $response){} | Consulte la sección Interceptor para obtener más detalles. |
antes_redirect | callable | array | Interceptor posterior a la redirección | function(Request $request, Response $response){} | Consulte la sección Interceptor para obtener más detalles. |
se acabó el tiempo | flotar | se acabó el tiempo | 0,5 | El valor predeterminado es 5 segundos, admite tiempo de espera de milisegundos |
dirección_vinculada | cadena | dirección de enlace | 192.168.1.1 o eth0 | No configurado por defecto |
puerto_vinculado | entero | Puerto de enlace | 80 | No configurado por defecto |
apoderado | cadena | interino | http://127.0.0.1:1087 | socks5://127.0.0.1:1087 | Soporte http y calcetines5 |
SSL | entero | Si se debe habilitar la conexión SSL | 0=关闭 1=开启 2=自动 | Automático predeterminado |
cafile | cadena | archivo ca | __DIR__ . '/cacert.pem' | Viene por defecto |
ssl_verify_peer | booleano | Verificar el certificado del lado del servidor | false | true | Desactivado de forma predeterminada |
ssl_allow_self_signed | booleano | Permitir certificados autofirmados | true | false | Permitido por defecto |
archivo_cert_ssl | cadena | certificado de certificado | __DIR__ . '/ssl.cert' | No configurado por defecto |
archivo_clave_ssl | cadena | clave clave privada | __DIR__ . '/ssl.key' | No configurado por defecto |
iconov | formación | Especificar la conversión de codificación | ['gbk', 'utf-8'] | Hay tres parámetros en total: from,to,use_mb , que se reconocen automáticamente de forma predeterminada. |
informe_excepción | entero | Nivel de informe de excepción | Máscara de excepción Http::E_ALL | Informar todas las excepciones de forma predeterminada |
mango_excepción | invocable|matriz | Función de manejo personalizado de excepciones | function(Exception $e){} | Los errores se pueden ignorar cuando la función devuelve verdadero |
rever | invocable | Interceptor de reintento automático | function(Request $request, Response $response){} | Después de que se produzca un error y antes de volver a intentarlo |
tiempo_reintento | entero | Reintentos automáticos | No volver a intentarlo de forma predeterminada | |
use_pool | booleano|int | grupo de conexiones | true | false |
clave_piscina | invocable|matriz | Clave del grupo de conexiones | function(Request $request):string { return $key; } | El valor predeterminado es host:port de la dirección solicitada. |
Para facilitar su uso y tolerar fallas, los valores clave de los elementos de configuración tienen un mecanismo de alias. Se recomienda utilizar el nombre original tanto como sea posible:
llave | alias |
---|---|
método | 0 |
uri | 1 url |
datos | 2 | body |
base_uri | URL_base |
después | llamar de vuelta |
tipo de contenido | content-type | contentType |
galletas | galletas |
encabezados | encabezamiento |
redirigir | seguir |
agente de usuario | ua | user-agent |
informe_excepción | error_report report |
antes_reintentar | rever |
árbitro | ref referrer |
El interceptor es una característica muy poderosa de Sabre, que le permite manejar varias cosas de manera muy conveniente, como imprimir registros de desarrollo:
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
Incluso las funciones y会话
异常自定义处理函数
se implementan a través de interceptores.
Puede haber varios interceptores, que se ejecutarán en el orden de registro, y puede nombrar el interceptor . Solo necesita envolverlo con una matriz y especificar el valor de la clave. Si desea eliminar este interceptor, simplemente sobrescríbalo. un valor nulo.
[
' after ' => [
' interceptor_new ' => function (){},
' interceptor_old ' => null
]
]
Los interceptores se pueden registrar de cuatro formas (4 funciones de devolución de llamada de PHP):
callable: function (){}
string: ' function_name '
string: ' ClassName::method_name '
array: [ $ object , ' method_name ' ]
La implementación de Cookie está completa a nivel del navegador . Se refiere específicamente a la implementación del navegador Chrome y sigue sus reglas relevantes.
Las cookies son una colección de cookies y cada cookie tiene las siguientes propiedades:
name
, value
, expires
, path
, session
, secure
, httponly
, hostonly
Y la clase Cookies admite la conversión de múltiples formatos, como
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']
Espere a que el formato se transfiera a la clase Cookie o que la clase Cookie se serialice en estos formatos.
Las cookies también admiten la verificación del nombre de dominio y del límite de tiempo sin perder información. Por ejemplo, si el dominio es github.com
, la cookie no aparecerá en help.github.com
a menos que el dominio no sea solo host (comodín .github.com
).
Si es una cookie de sesión (no tiene tiempo de vencimiento y caduca cuando se cierra el navegador), el atributo de vencimiento se establecerá en la hora actual y puede establecer una hora específica a través del interceptor .
Al leer el atributo sin formato de las cookies, se puede conservar fácilmente en la base de datos , lo cual es muy adecuado para aplicaciones de rastreo de inicio de sesión.
Para obtener más detalles, consulte la documentación y los ejemplos de la biblioteca Swlib/Http.
Sabre sigue la regla de separar los negocios de los errores . Cuando falla alguna parte de la solicitud, se generará una excepción de forma predeterminada .
Lo poderoso es que el manejo de excepciones de Sabre también es diverso y tan completo como el manejo de excepciones nativo de PHP.
El espacio de nombres de excepción se encuentra en SwlibHttpException
Excepción | Introducción | escena |
---|---|---|
Solicitud de excepción | Solicitud fallida | Error de configuración de solicitud |
ConexiónExcepción | La conexión falló | Si no hay conexión de red, la consulta DNS falla, se agota el tiempo de espera, etc., el valor de errno es igual al errno de Linux. Puede utilizar swoole_strerror para convertir códigos de error en mensajes de error. |
Excepción de demasiadas redirecciones | Se superó el número de redirecciones | La cantidad de redirecciones excede el límite establecido y la excepción lanzada imprimirá información de seguimiento de redirecciones. |
Excepción de cliente | excepción del cliente | El servidor devolvió un código de error 4xx |
Excepción del servidor | Excepción del servidor | El servidor devolvió un código de error 5xx |
Excepción de mala respuesta | Error al obtener respuesta desconocida | El servidor no respondió o devolvió un código de error no reconocido. |
Además de los métodos de excepción generales, todas las clases de excepción HTTP también tienen los siguientes métodos:
Método | Introducción |
---|---|
obtenerSolicitud | Obtener instancia de solicitud |
tiene respuesta | Ya sea para obtener una respuesta |
obtener respuesta | Obtener instancia de respuesta |
obtenerRespuestaCuerpoResumen | Obtenga el contenido resumido del cuerpo de la respuesta. |
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
Al mismo tiempo, Sabre también admite el manejo de excepciones de una manera suave, para evitar que los usuarios entren en pánico en entornos de red inestables y tengan que ajustar el código con intentos en cada paso:
Establezca el nivel de errorReport, que es efectivo globalmente y no tendrá efecto en las instancias creadas .
// 启用所有异常但忽略重定向次数过多异常
SaberGM:: exceptionReport (
HttpExceptionMask:: E_ALL ^ HttpExceptionMask:: E_REDIRECT
);
Los siguientes valores (numéricos o simbólicos) se utilizan para crear una máscara de bits que especifica el mensaje de error que se informará. Puede utilizar operadores bit a bit para combinar estos valores o enmascarar ciertos tipos de errores. Banderas y máscaras
Mascarilla | Valor | Introducción |
---|---|---|
E_NINGUNO | 0 | ignorar todas las excepciones |
E_REQUEST | 1 | Corresponde a RequestException |
E_CONECTAR | 2 | Corresponde a RequestException |
E_REDIRECT | 4 | Corresponde a RequestException |
E_BAD_RESPONSE | 8 | Corresponde a BadRException |
E_CLIENTE | 16 | Corresponde a ClientException |
E_SERVIDOR | 32 | Corresponde a ServerException |
E_ALL | 63 | Todas las excepciones |
Esta función puede manejar los errores generados en las solicitudes HTTP a su manera y puede definir las excepciones que desea detectar/ignorar más libremente.
Nota: A menos que la función devuelva VERDADERO (u otro valor verdadero), la excepción se seguirá lanzando en lugar de ser detectada por la función personalizada.
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 !
Carga de archivos | WebSockets | Analizador automático | Reintento automático | Descarga de archivos grandes | Cache | Grupo de clientes | AleatorioUA |
---|---|---|---|---|---|---|---|
4 (alta prioridad) | 3 | 2 | 1 | .5 | .5 | .5 | .175 |
El principal beneficio de HTTP/2 es que permite multiplexar muchas solicitudes dentro de una sola conexión, eliminando así [casi] el límite en el número de solicitudes simultáneas, y no existe tal límite cuando se habla con sus propios backends. empeora cuando se usa HTTP/2 en backends, debido a que se utiliza una única conexión TCP en lugar de varias, por lo que Http2 no será una prioridad (#ref).
Agregue los archivos fuente de este proyecto a la Include Path
del IDE.
(Si se instala usando Composer, puede incluir toda la carpeta del proveedor y PHPStorm la incluirá automáticamente)
La buena redacción de comentarios hace que Sabre admita perfectamente las indicaciones automáticas de IDE. Simplemente escriba el símbolo de flecha después del objeto para ver todos los nombres de los métodos del objeto. Una gran cantidad de métodos siguen la especificación PSR o se implementan haciendo referencia a ella. Proyecto Guzzle (gracias).
Para las indicaciones de IDE sobre clases subyacentes relacionadas con Swoole, debe introducir el asistente swoole-ide-helper de eaglewu (el compositor se instalará de forma predeterminada en el entorno de desarrollo). Sin embargo, este proyecto se mantiene manualmente y no está completo. -ide-ayudante o:
El ide-ayudante oficial de Swoole.
Bienvenido a enviar problemas y relaciones públicas.
Dado que las corrutinas (__call, __callStatic) no se pueden usar en métodos mágicos, los métodos en el código fuente se definen manualmente.
Para facilitar su uso, se han proporcionado alias para todos los métodos de solicitud admitidos.
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()