HTTP Sabre (Da Mao Wang), um cliente HTTP PHP de alto desempenho da Swoole人性化组件库
, é baseado na corrotina nativa do Swoole, suporta vários estilos de operações e fornece soluções de alto desempenho na parte inferior, permitindo que os desenvolvedores se concentrem em funcionalidades desenvolvimento, do tradicional Free do bloqueio síncrono e configuração complicada do Curl.
Documento Inglês
A melhor maneira de instalar é através do gerenciador de pacotes Composer:
composer require swlib/saber
A camada inferior do Swoole implementa o agendamento de rotina, e a camada de negócios não precisa estar ciente disso. Os desenvolvedores podem usar a escrita de código síncrona para obter o efeito de IO assíncrono e desempenho ultra-alto sem estar ciente disso, evitando a lógica de código discreta e. Trapping excessivo causado por retornos de chamada assíncronos tradicionais faz com que o código não seja sustentável.
Ele precisa ser usado em onRequet
, onReceive
, onConnect
e outras funções de retorno de chamada de evento, ou agrupado com a palavra-chave go ( swoole.use_shortname
está habilitado por padrão).
go ( function () {
echo SaberGM:: get ( ' http://httpbin.org/get ' );
})
Empacotamento automático de dados: os dados recebidos serão convertidos automaticamente no formato de tipo especificado pelo tipo de conteúdo
O padrão é
x-www-form-urlencoded
e outros formatos comojson
também são suportados.
SaberGM
:= Saber Global Manager
. Se você acha que o nome da classe é um pouco longo, você pode usar class_alias
para escolher um alias. Recomenda-se usar o método de geração de instâncias no serviço e usar SaberGM
como atalho.
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 ' ]);
Serviço de proxy de API aplicável
$ 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 ' ]);
A sessão salvará automaticamente as informações do cookie e sua implementação será concluída no nível do 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: Uma solução de otimização de redirecionamento simultâneo é usada aqui. Vários redirecionamentos são sempre simultâneos e não degenerarão em uma única solicitação na fila.
$ 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 ' ]
]);
Atualmente oferece suporte à análise rápida de dados em quatro formatos: json
, xml
, html
e 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 );
Suporta proxies HTTP e 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 ;
O agendamento automático de corrotina subjacente pode suportar o envio assíncrono de arquivos muito grandes e a transmissão de retomada de ponto de interrupção.
Carregue três arquivos ao mesmo tempo (três estilos de parâmetro
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
]
]
);
Depois que o Download recebe os dados, ele os grava diretamente no disco de forma assíncrona , em vez de unir o HttpBody na memória. Portanto, o download usa apenas uma pequena quantidade de memória para concluir o download de arquivos muito grandes . definindo o parâmetro offset para realizar downloads de ponto de interrupção.
Download assíncrono de papéis de parede do 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 );
}
Em projetos de crawler, é um requisito muito comum tentar novamente automaticamente uma solicitação com falha, como fazer login novamente após a expiração de uma sessão.
Saber
possui essa funcionalidade integrada e拦截器
podem ser usados para aprimorá-la.
Se retry_time
não estiver definido, mas um interceptador retry
estiver definido, retry_time
será definido como 1. Se o método de retorno de chamada do interceptor retry
retornar false
, não importa qual seja retry_time
, a nova tentativa será encerrada quando false
for retornado.
$ 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 ;
Às vezes, os recursos HTTP nem sempre mudam. Podemos aprender como os navegadores armazenam em cache os recursos que não mudam para acelerar a eficiência da solicitação. Saber
agendamento de corrotinas garante isso sozinho. de qualquer maneira, ele não bloqueará o servidor. Saber
não usa um mecanismo de middleware porque está fortemente relacionado ao Swoole, mas o cache pode usar内存/文件/数据库
e outros métodos, portanto, embora ainda não tenha sido implementado, será incluído no Saber
roteiro subsequente.
$ 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 ();
Você pode imprimir diretamente a string de dados retornada por meio do método __toString do quadro de dados websocketFrame.
$ websocket = SaberGM:: websocket ( ' ws://127.0.0.1:9999 ' );
while ( true ) {
echo $ websocket -> recv ( 1 ) . "n" ;
$ websocket -> push ( " hello " );
co:: sleep ( 1 );
}
A máquina de teste é um MacBook Pro com a configuração mais baixa e o servidor de solicitação é um servidor de eco local.
Concluiu 6.666 solicitações em 0,9 segundos , com uma taxa de sucesso de 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
Em projetos reais, as listas de URL são frequentemente usadas para configurar solicitações, portanto, o método list é fornecido por conveniência:
echo SaberGM:: list ([
' uri ' => [
' https://www.qq.com/ ' ,
' https://www.baidu.com/ ' ,
' https://www.swoole.com/ ' ,
' http://httpbin.org/ '
]
]);
Em projetos reais de rastreadores, muitas vezes temos que limitar o número de solicitações simultâneas únicas para evitar o bloqueio pelo firewall do servidor, e um parâmetro max_co
pode facilmente resolver esse problema. max_co
enviará as solicitações para a fila em lotes de acordo com o limite superior. e execute-os.
// 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" ;
Quando usado em um servidor residente na memória, certifique-se de ativar manualmente a opção de pool de conexões :
$ swoole = Saber:: create ([
' base_uri ' => ' https://www.swoole.com/ ' ,
' use_pool ' => true
]);
Quando utilizado através desta instância, o recurso de pool de conexões será habilitado, ou seja, o cliente de conexão subjacente com o site www.swoole.com
utilizará um pool de conexões global para acessar, evitando a sobrecarga de criação/conexão cada vez que for utilizado .
Quando o parâmetro é true
, a capacidade do pool de conexões do site é ilimitada . Geralmente, não há problema e o pool de conexões com capacidade ilimitada tem melhor desempenho.
Mas se você usá-lo como um serviço proxy rastreador e encontrar um grande número de solicitações , o número de clientes no pool de conexões aumentará de forma incontrolável e rápida, excedendo até mesmo o número máximo de conexões permitidas pelo site de origem que você solicitou neste momento. , você precisa que use_pool
esteja definido com um valor ideal (int). Neste momento, a camada inferior usará Channel como pool de conexões. Quando o número de clientes criados pelo pool de conexões exceder o número e não for suficiente, a corrotina. que precisa acessar o cliente será suspenso. E espere que a corrotina que está usando o cliente retorne o cliente. Quase não há consumo de desempenho na espera e comutação da corrotina, e é uma solução muito avançada .
Ressalta-se que o pool de conexões está vinculado à服务器IP+端口
, ou seja, caso você tenha múltiplas instâncias voltadas para a mesma服务器IP+端口
, o pool de conexões utilizado entre elas também é o mesmo.
Portanto, quando você cria repetidamente uma instância do服务器IP+端口
, use_pool
especificado pela instância recém-criada pode substituir o valor anterior, ou seja, a camada inferior do pool de conexão altera automaticamente sua capacidade. a camada inferior recriará um novo pool de conexões e transferirá clientes. Quando a capacidade for reduzida, o excesso de clientes no pool de conexões também será destruído.
Além de lembrar de configurar um pool de conexões, o método de tratamento de exceções também precisa estar alinhado com seus hábitos de programação. O tratamento de exceções padrão do Saber
é o抛出异常
mais convencional e rigoroso, mas Saber
também oferece suporte ao uso silencioso de错误码
e状态位
, podem estar mais de acordo com o gosto de muitas pessoas.
SaberGM:: exceptionReport ( 0 ); // 关闭抛出异常报告, 在业务代码之前注册即可全局生效
$ saber -> exceptionReport ( 0 ); //也可以单独设置某个实例
Da mesma forma, a configuração desejada pode ser pré-configurada antes do código de negócio, como onWorkerStart
ou mesmo antes do início swoole_server
.
SaberGM:: default ([
' exception_report ' => 0
' use_pool ' => true
]);
Configurar as opções desejadas como esta pode proporcionar uma experiência melhor!
go ( function (){
// your code with pool ...
saber_pool_release (); // and this script will exit
});
Se você usar um pool de conexão em um script único, como o cliente da corrotina existe no pool, a contagem de referência é 1 e não pode ser liberada, o que fará com que o swoole esteja sempre no loop de eventos e o script não possa sair. precisa chamar manualmente saber_pool_release
ou saber_exit
ou swoole_event_exit
para sair normalmente, ou você pode usar exit para forçar a saída do script atual (não use exit no servidor).
|
símbolo separa vários valores opcionais
chave | tipo | introdução | exemplo | observação |
---|---|---|---|---|
versão_protocolo | corda | Versão do protocolo HTTP | 1.1 | HTTP2 ainda está em planejamento |
base_uri | corda | caminho base | http://httpbin.org | Será mesclado com uri de acordo com rfc3986 |
uri | corda | identificador de recurso | http://httpbin.org/get get /get | Ambos os caminhos absolutos e relativos podem ser usados |
uri_query | string|matriz | solicitar informações | ['foo' => 'bar'] | Não-strings são convertidos automaticamente |
método | corda | Método de solicitação | get put post delete head patch | A camada inferior é automaticamente convertida para maiúscula |
cabeçalhos | variedade | cabeçalho da solicitação | ['DNT' => '1'] | ['accept' => ['text/html'], ['application/xml']] | Os nomes dos campos não diferenciam maiúsculas de minúsculas, mas as regras originais de maiúsculas e minúsculas durante a configuração serão mantidas. Cada valor de campo subjacente será automaticamente dividido em matrizes de acordo com o PSR-7. |
biscoitos | array | string | ['foo '=> 'bar'] | 'foo=bar; foz=baz' | A camada inferior é automaticamente convertida em um objeto Cookies, e seu domínio é configurado para o URI atual, com atributos completos no nível do navegador. | |
agente de usuário | corda | agente do usuário | curl-1.0 | O padrão é chrome na plataforma macos |
referenciador | corda | Endereço de origem | https://www.google.com | O padrão está vazio |
redirecionar | interno | Número máximo de redirecionamentos | 5 | O padrão é 3 e quando for 0 não há redirecionamento. |
keep_alive | bool | Quer se manter conectado | true | false | O padrão é verdadeiro, a conexão será reutilizada automaticamente durante o redirecionamento |
tipo_de_conteúdo | corda | Tipo de codificação de conteúdo enviado | text/plain | SwlibHttpContentType::JSON | O padrão é application/x-www-form-urlencoded |
dados | array | string | dados enviados | 'foo=bar&dog=cat' | ['foo' => 'bar'] | Os dados serão codificados automaticamente com base em content_type |
antes | array callable | | Interceptador de pré-solicitação | function(Request $request){} | Consulte a seção Interceptador para obter detalhes. |
depois | array callable | | Interceptador pós-resposta | function(Response $response){} | Consulte a seção Interceptador para obter detalhes. |
antes_redirecionar | array callable | | Interceptador pós-redirecionamento | function(Request $request, Response $response){} | Consulte a seção Interceptador para obter detalhes. |
tempo esgotado | flutuador | tempo esgotado | 0,5 | O padrão é 5s, suporta tempo limite de milissegundos |
endereço_de_ligação | corda | Endereço de vinculação | 192.168.1.1 ou eth0 | Não definido por padrão |
porta_bind | interno | Porta de ligação | 80 | Não definido por padrão |
procurador | corda | atuando | http://127.0.0.1:1087 | socks5://127.0.0.1:1087 | Suporte http e meias5 |
SSL | interno | Se deve ativar a conexão SSL | 0=关闭 1=开启 2=自动 | Padrão automático |
café | corda | arquivo ca | __DIR__ . '/cacert.pem' | Vem com padrão |
ssl_verify_peer | bool | Verifique o certificado do lado do servidor | false | true | Desativado por padrão |
ssl_allow_self_signed | bool | Permitir certificados autoassinados | true | false | Permitido por padrão |
ssl_cert_file | corda | certificado certificado | __DIR__ . '/ssl.cert' | Não definido por padrão |
ssl_key_file | corda | chave chave privada | __DIR__ . '/ssl.key' | Não definido por padrão |
íconev | variedade | Especifique a conversão de codificação | ['gbk', 'utf-8'] | Existem três parâmetros no total: from,to,use_mb , que são reconhecidos automaticamente por padrão. |
relatório_exceção | interno | Nível de relatório de exceção | HttpExceptionMask::E_ALL | Reportar todas as exceções por padrão |
identificador_de_exceção | chamável | matriz | Função de tratamento personalizado de exceção | function(Exception $e){} | Erros podem ser ignorados quando a função retorna verdadeiro |
tente novamente | chamável | Interceptador automático de novas tentativas | function(Request $request, Response $response){} | Após ocorrer um erro e antes de tentar novamente |
tempo_de_tentativa | interno | Novas tentativas automáticas | Não tente novamente por padrão | |
use_pool | bool|int | conjunto de conexões | true | false |
pool_key | chamável | matriz | Chave do pool de conexões | function(Request $request):string { return $key; } | O padrão é host:port do endereço solicitado |
Para facilidade de uso e tolerância a falhas, os valores-chave dos itens de configuração possuem um mecanismo de alias. Recomenda-se usar o nome original tanto quanto possível:
chave | apelido |
---|---|
método | 0 |
uri | 1 url |
dados | 2 | body |
base_uri | URL_base |
depois | ligar de volta |
tipo_de_conteúdo | content-type | contentType |
biscoitos | biscoitos |
cabeçalhos | cabeçalho |
redirecionar | seguir |
agente de usuário | ua | user-agent |
relatório_exceção | error_report report |
antes_repetir | tente novamente |
referenciador | ref referrer |
O interceptor é um recurso muito poderoso do Sabre, que permite lidar com várias coisas de maneira muito conveniente, como imprimir logs de desenvolvimento:
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
Até mesmo异常自定义处理函数
e会话
personalizadas de tratamento de exceções são implementadas por meio de interceptadores.
Pode haver vários interceptores, que serão executados na ordem de registro, e você pode nomear o interceptador . Você só precisa envolvê-lo com um array e especificar o valor da chave. Se desejar excluir este interceptador, basta substituí-lo. um valor nulo.
[
' after ' => [
' interceptor_new ' => function (){},
' interceptor_old ' => null
]
]
Os interceptores podem ser registrados de quatro maneiras (4 funções de retorno de chamada do PHP):
callable: function (){}
string: ' function_name '
string: ' ClassName::method_name '
array: [ $ object , ' method_name ' ]
A implementação do Cookie é completa ao nível do navegador . Refere-se especificamente à implementação do navegador Chrome e segue as suas regras relevantes.
Cookies são uma coleção de cookies e cada cookie possui as seguintes propriedades:
name
, value
, expires
, path
, session
, secure
, httponly
, hostonly
E a classe Cookies suporta a conversão de vários 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']
Aguarde até que o formato seja transferido para a classe Cookie ou que a classe Cookie seja serializada nesses formatos.
Os cookies também suportam verificação de nome de domínio e limite de tempo sem perder nenhuma informação. Por exemplo, se o domínio for github.com
, o cookie não aparecerá em help.github.com
a menos que o domínio não seja hostonly (curinga .github.com
).
Se for um cookie de sessão (não tem tempo de expiração e expira quando o navegador é fechado), o atributo expires será definido para o horário atual, e você poderá definir um horário específico através do interceptor .
Ao ler o atributo bruto dos Cookies, ele pode ser facilmente persistido no banco de dados , o que é muito adequado para aplicativos rastreadores de login.
Para obter mais detalhes, consulte a documentação e os exemplos da biblioteca Swlib/Http.
O Sabre segue a regra de separar negócios de erros . Quando qualquer parte da solicitação falhar, uma exceção será lançada por padrão .
O que é poderoso é que o tratamento de exceções do Sabre também é diversificado e tão completo quanto o tratamento de exceções nativo do PHP.
O namespace da exceção está localizado em SwlibHttpException
Exceção | Introdução | cena |
---|---|---|
SolicitaçãoExceção | Falha na solicitação | Erro de configuração de solicitação |
ConnectException | Falha na conexão | Se não houver conexão de rede, falha na consulta DNS, tempo limite, etc., o valor de errno é igual ao errno do Linux. Você pode usar swoole_strerror para converter códigos de erro em mensagens de erro. |
TooManyRedirectsException | Número de redirecionamentos excedido | O número de redirecionamentos excede o limite definido e a exceção lançada imprimirá informações de rastreamento de redirecionamento. |
ClientException | Exceção do cliente | O servidor retornou um código de erro 4xx |
ServerException | Exceção de servidor | O servidor retornou um código de erro 5xx |
BadResponseException | Falha ao obter resposta desconhecida | O servidor não respondeu ou retornou um código de erro não reconhecido. |
Além dos métodos de exceção gerais, todas as classes de exceção HTTP também possuem os seguintes métodos:
Método | Introdução |
---|---|
obter Solicitação | Obter instância de solicitação |
temResposta | Quer obter uma resposta |
obterResponse | Obter instância de resposta |
getResponseBodySummary | Obtenha o conteúdo resumido do corpo da resposta |
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
Ao mesmo tempo, o Sabre também suporta o tratamento de exceções de maneira suave, para evitar que os usuários entrem em pânico em ambientes de rede instáveis e tenham que agrupar o código com try em cada etapa:
Defina o nível errorReport, que é globalmente eficaz e não terá efeito nas instâncias criadas .
// 启用所有异常但忽略重定向次数过多异常
SaberGM:: exceptionReport (
HttpExceptionMask:: E_ALL ^ HttpExceptionMask:: E_REDIRECT
);
Os seguintes valores (numéricos ou simbólicos) são usados para criar uma máscara de bits que especifica a mensagem de erro a ser relatada. Você pode usar operadores bit a bit para combinar esses valores ou para mascarar certos tipos de erros. Bandeiras e máscaras
Máscara | Valor | Introdução |
---|---|---|
E_NONE | 0 | ignore todas as exceções |
E_REQUEST | 1 | Corresponde a RequestException |
E_CONNECT | 2 | Corresponde a RequestException |
E_REDIRECT | 4 | Corresponde a RequestException |
E_BAD_RESPONSE | 8 | Corresponde a BadRException |
E_CLIENTE | 16 | Corresponde a ClientException |
E_SERVER | 32 | Corresponde a ServerException |
E_TODOS | 63 | Todas as exceções |
Esta função pode lidar com erros gerados em solicitações HTTP à sua maneira, e você pode definir as exceções que deseja capturar/ignorar com mais liberdade.
Nota: A menos que a função retorne TRUE (ou outro valor verdadeiro), a exceção continuará a ser lançada em vez de ser capturada pela função 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 !
Upload de arquivo | WebSockets | Analisador automático | Tentativa automática | Baixar BigFile | Cache | Pool de clientes | AleatórioUA |
---|---|---|---|---|---|---|---|
4 (alta prioridade) | 3 | 2 | 1 | .5 | .5 | .5 | 0,175 |
Como o principal benefício do HTTP/2 é que ele permite multiplexar muitas solicitações em uma única conexão, [quase] removendo o limite do número de solicitações simultâneas - e não existe esse limite ao falar com seus próprios back-ends. piora ao usar HTTP/2 para backends, devido ao uso de uma única conexão TCP em vez de múltiplas, então Http2 não será uma prioridade (#ref)
Adicione os arquivos de origem deste projeto ao Include Path
do IDE.
(Se instalado usando o compositor, você pode incluir toda a pasta do fornecedor e o PHPStorm a incluirá automaticamente)
Uma boa escrita de comentários faz com que o Sabre suporte perfeitamente os prompts automáticos do IDE. Basta escrever o símbolo de seta após o objeto para visualizar todos os nomes dos métodos do objeto. Um grande número de métodos segue a especificação PSR ou é implementado referindo-se ao. Projeto Guzzle (obrigado).
Para prompts IDE em classes subjacentes relacionadas ao Swoole, você precisa apresentar o swoole-ide-helper do eaglewu (o compositor será instalado por padrão no ambiente de desenvolvimento, no entanto, este projeto é mantido manualmente e não está completo). -ide-helper ou:
Ajudante oficial de Swoole.
Bem-vindo ao enviar questões e PRs.
Como as corrotinas (__call, __callStatic) não podem ser usadas em métodos mágicos, os métodos no código-fonte são definidos manualmente.
Para facilitar o uso, foram fornecidos aliases para todos os métodos de solicitação suportados.
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()