Swoole人性化组件库
의 PHP 고성능 HTTP 클라이언트인 HTTP Saber(Da Mao Wang)는 Swoole의 기본 코루틴을 기반으로 하며 다양한 작업 스타일을 지원하고 하단에 고성능 솔루션을 제공하여 개발자가 기능적 작업에 집중할 수 있도록 합니다. Curl의 동기식 차단 및 번거로운 구성에서 해방되었습니다.
영문문서
가장 좋은 설치 방법은 Composer 패키지 관리자를 이용하는 것입니다.
composer require swlib/saber
Swoole의 최하위 계층은 코루틴 스케줄링을 구현하며 비즈니스 계층은 인식할 필요가 없습니다 . 개발자는 동기식 코드 작성을 사용하여 이를 인식하지 않고도 비동기식 IO 및 초고성능의 효과를 달성할 수 있으며 개별 코드 로직을 피하고 기존 비동기 콜백으로 인한 과도한 트래핑으로 인해 코드를 유지 관리할 수 없게 됩니다.
onRequet
, onReceive
, onConnect
및 기타 이벤트 콜백 함수에서 사용하거나 go 키워드로 래핑해야 합니다( swoole.use_shortname
은 기본적으로 활성화되어 있습니다).
go ( function () {
echo SaberGM:: get ( ' http://httpbin.org/get ' );
})
자동 데이터 패키징: 들어오는 데이터는 content-type에 지정된 유형 형식으로 자동 변환됩니다.
기본값은
x-www-form-urlencoded
이며json
과 같은 다른 형식도 지원됩니다.
SaberGM
:= Saber Global Manager
. 클래스 이름이 다소 길다고 생각되면 class_alias
사용하여 별칭을 직접 선택할 수 있습니다. 서비스에서 인스턴스를 생성하는 방법을 사용하고 단축으로 SaberGM
사용하는 것이 좋습니다.
SaberGM:: get ( ' http://httpbin.org/get ' );
SaberGM:: delete ( ' http://httpbin.org/delete ' );
SaberGM:: post ( ' http://httpbin.org/post ' , [ ' foo ' => ' bar ' ]);
SaberGM:: put ( ' http://httpbin.org/put ' , [ ' foo ' => ' bar ' ]);
SaberGM:: patch ( ' http://httpbin.org/patch ' , [ ' foo ' => ' bar ' ]);
적용 가능한 API 프록시 서비스
$ saber = Saber:: create ([
' base_uri ' => ' http://httpbin.org ' ,
' headers ' => [
' Accept-Language ' => ' en,zh-CN;q=0.9,zh;q=0.8 ' ,
' Content-Type ' => ContentType:: JSON ,
' DNT ' => ' 1 ' ,
' User-Agent ' => null
]
]);
echo $ saber -> get ( ' /get ' );
echo $ saber -> delete ( ' /delete ' );
echo $ saber -> post ( ' /post ' , [ ' foo ' => ' bar ' ]);
echo $ saber -> patch ( ' /patch ' , [ ' foo ' => ' bar ' ]);
echo $ saber -> put ( ' /put ' , [ ' foo ' => ' bar ' ]);
세션은 쿠키 정보를 자동으로 저장하며 브라우저 수준에서 구현이 완료됩니다.
$ session = Saber:: session ([
' base_uri ' => ' http://httpbin.org ' ,
' redirect ' => 0
]);
$ session -> get ( ' /cookies/set?foo=bar&k=v&apple=banana ' );
$ session -> get ( ' /cookies/delete?k ' );
echo $ session -> get ( ' /cookies ' )-> body ;
참고: 여기에서는 동시 리디렉션 최적화 솔루션이 사용됩니다. 다중 리디렉션은 항상 동시적이며 대기열의 단일 요청으로 변환되지 않습니다.
$ responses = SaberGM:: requests ([
[ ' uri ' => ' http://github.com/ ' ],
[ ' uri ' => ' http://github.com/ ' ],
[ ' uri ' => ' https://github.com/ ' ]
]);
echo " multi-requests [ { $ responses -> success_num } ok, { $ responses -> error_num } error ]: n" . " consuming-time: { $ responses -> time } s n" ;
// multi - requests [ 3 ok , 0 error ] :
// consuming - time : 0 . 79090881347656s
// 别名机制可以省略参数书写参数名
$ saber = Saber:: create ([ ' base_uri ' => ' http://httpbin.org ' ]);
echo $ saber -> requests ([
[ ' get ' , ' /get ' ],
[ ' post ' , ' /post ' ],
[ ' patch ' , ' /patch ' ],
[ ' put ' , ' /put ' ],
[ ' delete ' , ' /delete ' ]
]);
현재 json
, xml
, html
및 url-query
[ $ json , $ xml , $ html ] = SaberGM:: list ([
' uri ' => [
' http://httpbin.org/get ' ,
' http://www.w3school.com.cn/example/xmle/note.xml ' ,
' http://httpbin.org/html '
]
]);
var_dump ( $ json -> getParsedJsonArray ());
var_dump ( $ json -> getParsedJsonObject ());
var_dump ( $ xml -> getParsedXmlArray ());
var_dump ( $ xml -> getParsedXmlObject ( true ));
var_dump ( $ html -> getParsedDomObject ()-> getElementsByTagName ( ' h1 ' )-> item ( 0 )-> textContent );
HTTP 및 SOCKS5 프록시 지원
$ uri = ' http://myip.ipip.net/ ' ;
echo SaberGM:: get ( $ uri , [ ' proxy ' => ' http://127.0.0.1:1087 ' ])-> body ;
echo SaberGM:: get ( $ uri , [ ' proxy ' => ' socks5://127.0.0.1:1086 ' ])-> body ;
기본 자동 코루틴 예약은 매우 큰 파일의 비동기 전송 과 중단점 재개 전송을 지원할 수 있습니다.
동시에 세 개의 파일 업로드(세 가지 매개변수 스타일
string
|array
|object
)
$ file1 = __DIR__ . ' /black.png ' ;
$ file2 = [
' path ' => __DIR__ . ' /black.png ' ,
' name ' => ' white.png ' ,
' type ' => ContentType:: MAP [ ' png ' ],
' offset ' => null , // re - upload from break
' size ' => null //upload a part of the file
];
$ file3 = new SwUploadFile (
__DIR__ . ' /black.png ' ,
' white.png ' ,
ContentType:: MAP [ ' png ' ]
);
echo SaberGM:: post ( ' http://httpbin.org/post ' , null , [
' files ' => [
' image1 ' => $ file1 ,
' image2 ' => $ file2 ,
' image3 ' => $ file3
]
]
);
다운로드는 데이터를 받은 후 메모리에 HttpBody를 연결하는 대신 비동기적으로 디스크에 직접 씁니다. 따라서 다운로드는 매우 큰 파일 의 다운로드를 완료하기 위해 소량의 메모리 만 사용합니다. 또한 중단점 재개 다운로드도 지원합니다. 중단점 다운로드를 수행하기 위한 오프셋 매개변수 설정.
세이버 배경화면의 비동기 다운로드
$ download_dir = ' /tmp/saber.jpg ' ;
$ response = SaberGM:: download (
' https://ws1.sinaimg.cn/large/006DQdzWly1fsr8jt2botj31hc0wxqfs.jpg ' ,
$ download_dir
);
if ( $ response -> success ) {
exec ( ' open ' . $ download_dir );
}
크롤러 프로젝트에서는 세션이 만료된 후 다시 로그인하는 등 실패한 요청을 자동으로 재시도하는 것이 매우 일반적인 요구 사항입니다.
Saber
에는 이 기능이 내장되어 있으며拦截器
사용하여 이를 향상시킬 수 있습니다.
retry_time
설정되지 않았지만 retry
인터셉터가 설정된 경우 retry_time
1로 설정됩니다. retry
인터셉터의 콜백 메소드가 false
반환하는 경우 retry_time
이 무엇이든 false
가 반환되면 재시도가 종료됩니다.
$ uri = ' http://eu.httpbin.org/basic-auth/foo/bar ' ;
$ res = SaberGM:: get (
$ uri , [
' exception_report ' => 0 ,
' retry_time ' => 3 ,
' retry ' => function ( Saber Request $ request ) {
echo " retry... n" ;
$ request -> withBasicAuth ( ' foo ' , ' bar ' ); //发现失败后添加验证信息
if ( ' i don not want to retry again ' ) {
return false ; // shutdown
}
}
]
);
echo $ res ;
때때로 HTTP 리소스는 항상 변경되지 않습니다. 요청 효율성을 높이기 위해 브라우저가 변경되지 않는 리소스를 캐시하는 방법을 배울 수 있습니다. Saber
캐싱 논리(CURD 또는 파일 읽기 및 쓰기)를 자체적으로 유지하지 않고도 이를 자동으로 완료합니다. 어쨌든 서버를 차단하지는 않습니다. Saber
Swoole과 밀접한 관련이 있기 때문에 미들웨어 메커니즘을 사용하지 않지만 캐싱은内存/文件/数据库
및 기타 방법을 사용할 수 있으므로 아직 구현되지는 않았지만 Saber
에 포함됩니다. 의 후속 로드맵입니다.
$ bufferStream = new BufferStream ();
$ bufferStream -> write ( json_encode ([ ' foo ' => ' bar ' ]));
$ response = SaberGM:: psr ()
-> withMethod ( ' POST ' )
-> withUri ( new Uri ( ' http://httpbin.org/post?foo=bar ' ))
-> withQueryParams ([ ' foo ' => ' option is higher-level than uri ' ])
-> withHeader ( ' content-type ' , ContentType:: JSON )
-> withBody ( $ bufferStream )
-> exec ()-> recv ();
echo $ response -> getBody ();
websocketFrame 데이터 프레임의 __toString 메서드를 통해 반환된 데이터 문자열을 직접 인쇄할 수 있습니다.
$ websocket = SaberGM:: websocket ( ' ws://127.0.0.1:9999 ' );
while ( true ) {
echo $ websocket -> recv ( 1 ) . "n" ;
$ websocket -> push ( " hello " );
co:: sleep ( 1 );
}
테스트 머신은 구성이 가장 낮은 MacBook Pro이고, 요청 서버는 로컬 에코 서버입니다.
0.9초 만에 6666건의 요청을 완료했으며 성공률은 100%입니다.
co:: set ([ ' max_coroutine ' => 8191 ]);
go ( function () {
$ requests = [];
for ( $ i = 6666 ; $ i --;) {
$ requests [] = [ ' uri ' => ' http://127.0.0.1 ' ];
}
$ res = SaberGM:: requests ( $ requests );
echo " use { $ res -> time } s n" ;
echo " success: $ res -> success_num , error: $ res -> error_num " ;
});
// on MacOS
// use 0 . 91531705856323s
// success : 6666 , error : 0
실제 프로젝트에서는 요청 구성에 URL 목록을 사용하는 경우가 많으므로 편의를 위해 list 메소드를 제공합니다.
echo SaberGM:: list ([
' uri ' => [
' https://www.qq.com/ ' ,
' https://www.baidu.com/ ' ,
' https://www.swoole.com/ ' ,
' http://httpbin.org/ '
]
]);
실제 크롤러 프로젝트에서는 서버 방화벽에 의해 차단되는 것을 방지하기 위해 단일 동시 요청 수를 제한해야 하는 경우가 많으며, max_co
매개변수를 max_co
하면 상한선에 따라 요청을 일괄적으로 대기열에 푸시할 수 있습니다. 패키지를 수신하고 실행합니다.
// max_co is the max number of concurrency request once , it ' s very useful to prevent server - waf limit .
$ requests = array_fill ( 0 , 10 , [ ' uri ' => ' https://www.qq.com/ ' ]);
echo SaberGM:: requests ( $ requests , [ ' max_co ' => 5 ])-> time . "n" ;
echo SaberGM:: requests ( $ requests , [ ' max_co ' => 1 ])-> time . "n" ;
메모리 상주 서버에서 사용하는 경우 연결 풀 옵션을 수동으로 활성화해야 합니다 .
$ swoole = Saber:: create ([
' base_uri ' => ' https://www.swoole.com/ ' ,
' use_pool ' => true
]);
이 인스턴스를 통해 사용하면 연결 풀 기능이 활성화됩니다. 즉, www.swoole.com
웹 사이트의 기본 연결 클라이언트는 글로벌 연결 풀을 사용하여 액세스하므로 사용할 때마다 생성/연결하는 오버헤드가 방지됩니다. .
매개변수가 true
인 경우 웹사이트의 연결 풀 용량은 무제한 입니다. 일반적으로 문제가 없으며, 무제한 용량의 연결 풀이 더 나은 성능을 발휘합니다.
그러나 이를 크롤러 프록시 서비스로 사용하고 많은 수의 요청이 발생하면 연결 풀의 클라이언트 수가 제어할 수 없을 정도로 빠르게 증가하여 현재 요청한 소스 웹 사이트에서 허용하는 최대 연결 수를 초과합니다. , use_pool
이상적인 값 (int)으로 설정해야 합니다. 이때 하위 계층은 연결 풀로 생성된 클라이언트 수가 이 수를 초과하여 충분하지 않은 경우 채널을 사용합니다. 클라이언트에 액세스해야 하는 서비스는 일시 중지됩니다. 그리고 클라이언트를 사용하고 있는 코루틴이 클라이언트를 반환할 때까지 기다립니다. 코루틴 대기 및 전환에는 성능 소모가 거의 없으며 매우 발전된 솔루션입니다.
연결 풀은服务器IP+端口
에 바인딩됩니다. 즉, 동일한服务器IP+端口
에 직면하는 여러 인스턴스가 있는 경우 둘 사이에 사용되는 연결 풀도 동일합니다.
따라서服务器IP+端口
의 인스턴스를 반복적으로 생성하면 새로 생성된 인스턴스에서 지정한 use_pool
이전 값을 덮어쓸 수 있습니다. 즉, 연결 풀의 하위 계층은 용량이 증가하면 자동으로 용량이 변경됩니다. 하위 계층에서는 새로운 연결 풀을 다시 생성하고 고객을 이전합니다. 용량이 줄어들면 연결 풀의 초과 클라이언트도 삭제됩니다.
연결 풀 구성을 기억하는 것 외에도 예외 처리 방법은 프로그래밍 습관과 일치해야 합니다. Saber
의 기본 예외 처리는 가장 주류적이고 엄격한抛出异常
이지만 Saber
错误码
의 자동 사용도 지원합니다.错误码
와状态位
많은 사람들의 취향에 더 부합할 수 있습니다.
SaberGM:: exceptionReport ( 0 ); // 关闭抛出异常报告, 在业务代码之前注册即可全局生效
$ saber -> exceptionReport ( 0 ); //也可以单独设置某个实例
같은 방식으로 onWorkerStart
와 같은 비즈니스 코드 이전이나 swoole_server
시작되기 전에 원하는 구성을 미리 구성할 수 있습니다.
SaberGM:: default ([
' exception_report ' => 0
' use_pool ' => true
]);
이와 같이 원하는 옵션을 구성하면 더 나은 경험을 제공할 수 있습니다!
go ( function (){
// your code with pool ...
saber_pool_release (); // and this script will exit
});
일회성 스크립트에서 연결 풀을 사용하는 경우 코루틴 클라이언트가 풀에 존재하므로 참조 횟수가 1이고 해제할 수 없으며 이로 인해 swoole이 항상 이벤트 루프에 있게 되고 스크립트가 종료될 수 없습니다. 정상적으로 종료하려면 saber_pool_release
수동으로 호출해야 합니다. 또는 saber_exit
또는 swoole_event_exit
사용하여 현재 스크립트를 강제 종료할 수 있습니다(서버에서는 종료를 사용하지 마십시오).
|
기호는 여러 선택적 값을 구분합니다.
열쇠 | 유형 | 소개 | 예 | 주목 |
---|---|---|---|---|
프로토콜_버전 | 끈 | HTTP 프로토콜 버전 | 1.1 | HTTP2는 아직 계획 중입니다. |
베이스_우리 | 끈 | 기본 경로 | http://httpbin.org | rfc3986에 따라 uri와 병합됩니다. |
우리 | 끈 | 리소스 식별자 | http://httpbin.org/get get /get | 절대 경로와 상대 경로를 모두 사용할 수 있습니다. |
uri_query | 문자열|배열 | 정보 요청 | ['foo' => 'bar'] | 문자열이 아닌 항목은 자동으로 변환됩니다. |
방법 | 끈 | 요청 방법 | get delete head patch put post | 하단 레이어는 자동으로 대문자로 변환됩니다. |
헤더 | 정렬 | 요청 헤더 | ['DNT' => '1'] | ['accept' => ['text/html'], ['application/xml']] | 필드 이름은 대소문자를 구분하지 않지만 설정 중 원래 대소문자 규칙은 유지됩니다. 각 기본 필드 값은 PSR-7에 따라 자동으로 배열로 나뉩니다. |
쿠키 | array | string | ['foo '=> 'bar'] | 'foo=bar; foz=baz' | 맨 아래 레이어는 자동으로 Cookies 개체로 변환되고 해당 도메인은 브라우저 수준의 전체 속성과 함께 현재 URI로 설정됩니다. | |
사용자 에이전트 | 끈 | 사용자 에이전트 | curl-1.0 | Macos 플랫폼의 기본값은 chrome입니다. |
추천인 | 끈 | 소스 주소 | https://www.google.com | 기본값은 비어 있습니다. |
리디렉션 | 정수 | 최대 리디렉션 수 | 5 | 기본값은 3이고, 0이면 리디렉션이 없습니다. |
keep_alive | 부울 | 연결을 유지할지 여부 | true | false | 기본값은 true입니다. 리디렉션 중에 연결이 자동으로 재사용됩니다. |
content_type | 끈 | 전송된 콘텐츠 인코딩 유형 | text/plain | SwlibHttpContentType::JSON | 기본값은 application/x-www-form-urlencoded입니다. |
데이터 | array | string | 전송된 데이터 | 'foo=bar&dog=cat' ['foo' => 'bar'] | 데이터는 content_type에 따라 자동으로 인코딩됩니다. |
~ 전에 | callable array | 사전 요청 인터셉터 | function(Request $request){} | 자세한 내용은 인터셉터 섹션을 참조하세요. |
~ 후에 | callable array | 사후 응답 인터셉터 | function(Response $response){} | 자세한 내용은 인터셉터 섹션을 참조하세요. |
before_redirect | callable array | 리디렉션 후 인터셉터 | function(Request $request, Response $response){} | 자세한 내용은 인터셉터 섹션을 참조하세요. |
시간 초과 | 뜨다 | 시간 초과 | 0.5 | 기본값은 5초이며 밀리초 시간 제한을 지원합니다. |
바인딩_주소 | 끈 | 바인딩 주소 | 192.168.1.1 또는 eth0 | 기본적으로 설정되지 않음 |
바인딩_포트 | 정수 | 바인딩 포트 | 80 | 기본적으로 설정되지 않음 |
대리 | 끈 | 연기 | http://127.0.0.1:1087 socks5://127.0.0.1:1087 | http 및 양말 지원5 |
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' | 기본적으로 설정되지 않음 |
아이콘 | 정렬 | 인코딩 변환 지정 | ['gbk', 'utf-8'] | 총 3개의 매개변수( from,to,use_mb )가 있으며 기본적으로 자동으로 인식됩니다. |
예외_보고 | 정수 | 예외 보고 수준 | HttpExceptionMask::E_ALL | 기본적으로 모든 예외 보고 |
예외_처리 | 호출 가능|배열 | 예외 커스텀 처리 기능 | function(Exception $e){} | 함수가 true를 반환하면 오류를 무시할 수 있습니다. |
다시 해 보다 | 호출 가능 | 자동 재시도 인터셉터 | function(Request $request, Response $response){} | 오류 발생 후 재시도 전 |
재시도_시간 | 정수 | 자동 재시도 | 기본적으로 다시 시도하지 않음 | |
use_pool | 부울|int | 연결 풀 | true | false |
pool_key | 호출 가능|배열 | 연결 풀 키 | function(Request $request):string { return $key; } | 기본값은 요청된 주소의 host:port 입니다. |
사용 편의성과 내결함성을 위해 구성 항목의 키 값에는 가능한 한 원래 이름을 사용하는 것이 좋습니다.
열쇠 | 별명 |
---|---|
방법 | 0 |
우리 | 1 url |
데이터 | 2 | body |
베이스_우리 | base_url |
~ 후에 | 콜백 |
content_type | content-type contentType |
쿠키 | 쿠키 |
헤더 | 헤더 |
리디렉션 | 따르다 |
사용자 에이전트 | ua user-agent |
예외_보고 | 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
그리고 Cookies 클래스는 다음과 같은 여러 형식의 변환을 지원합니다.
foo=bar; foz=baz; apple=banana
Set-Cookie: logged_in=no; domain=.github.com; path=/; expires=Tue, 06 Apr 2038 00:00:00 -0000; secure; HttpOnly
['foo'=>'bar', 'foz'=>'baz']
형식이 Cookie 클래스로 전송되거나 Cookie 클래스가 이러한 형식으로 직렬화될 때까지 기다립니다.
쿠키는 정보 손실 없이 도메인 이름 및 시간 제한 확인도 지원합니다. 예를 들어 도메인이 github.com
인 경우 도메인이 호스트 전용( .github.com
와일드카드)이 아닌 한 help.github.com
에 쿠키가 표시되지 않습니다.
세션 쿠키(만료 시간이 없고 브라우저를 닫으면 만료됨)인 경우 만료 속성이 현재 시간으로 설정되며 인터셉터를 통해 특정 시간을 설정할 수 있습니다.
쿠키의 원시 속성을 읽어 데이터베이스에 쉽게 유지할 수 있으며 이는 로그인 크롤러 애플리케이션에 매우 적합합니다.
자세한 내용은 Swlib/Http 라이브러리 설명서 및 예제를 참조하세요.
Sabre는 비즈니스와 오류를 분리하는 규칙을 따릅니다. 요청의 일부가 실패하면 기본적으로 예외가 발생합니다 .
강력한 점은 Sabre의 예외 처리가 PHP의 기본 예외 처리만큼 다양하고 완벽하다는 것입니다.
예외 네임스페이스는 SwlibHttpException
에 있습니다.
예외 | 소개 | 장면 |
---|---|---|
요청 예외 | 요청 실패 | 요청 구성 오류 |
ConnectException | 연결 실패 | 네트워크 연결이 없거나 DNS 쿼리가 실패하거나 시간 초과 등이 발생하는 경우 errno 값은 Linux errno와 같습니다. swoole_strerror를 사용하여 오류 코드를 오류 메시지로 변환할 수 있습니다. |
너무많은리디렉션예외 | 리디렉션 수를 초과했습니다. | 리디렉션 수가 설정된 제한을 초과했으며 예외가 발생하면 리디렉션 추적 정보가 인쇄됩니다. |
클라이언트예외 | 클라이언트 예외 | 서버가 4xx 오류 코드를 반환했습니다. |
서버예외 | 서버 예외 | 서버가 5xx 오류 코드를 반환했습니다. |
BadResponseException | 알 수 없는 응답 가져오기 실패 | 서버가 응답하지 않거나 인식할 수 없는 오류 코드를 반환했습니다. |
일반적인 예외 메서드 외에도 모든 HTTP 예외 클래스에는 다음 메서드도 있습니다.
방법 | 소개 |
---|---|
getRequest | 요청 인스턴스 가져오기 |
hasResponse | 응답을 받을지 여부 |
getResponse | 응답 인스턴스 가져오기 |
getResponseBody요약 | 응답 본문의 요약 콘텐츠 가져오기 |
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는 사용자가 불안정한 네트워크 환경에서 패닉에 빠지고 모든 단계에서 try로 코드를 래핑해야 하는 것을 방지하기 위해 온화한 방식으로 예외 처리를 지원합니다.
전역적으로 적용 되며 생성된 인스턴스에는 적용되지 않는 errorReport 수준을 설정합니다.
// 启用所有异常但忽略重定向次数过多异常
SaberGM:: exceptionReport (
HttpExceptionMask:: E_ALL ^ HttpExceptionMask:: E_REDIRECT
);
다음 값(숫자 또는 기호)은 보고할 오류 메시지를 지정하는 비트마스크를 만드는 데 사용됩니다. 비트 연산자를 사용하여 이러한 값을 결합하거나 특정 유형의 오류를 마스킹할 수 있습니다. 깃발과 마스크
마스크 | 값 | 소개 |
---|---|---|
E_NONE | 0 | 모든 예외를 무시 |
E_요청 | 1 | RequestException에 해당 |
E_CONNECT | 2 | RequestException에 해당 |
E_REDIRECT | 4 | RequestException에 해당 |
E_BAD_RESPONSE | 8 | BadRException에 해당 |
E_CLIENT | 16 | ClientException에 해당 |
E_SERVER | 32 | ServerException에 해당 |
E_ALL | 63 | 모든 예외 |
이 기능은 HTTP 요청에서 발생하는 오류를 자신만의 방식으로 처리할 수 있으며, catch/무시하려는 예외를 보다 자유롭게 정의할 수 있습니다.
참고: 함수가 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 !
파일 업로드 | 웹소켓 | 자동파서 | 자동 재시도 | 빅파일 다운로드 | 은닉처 | 클라이언트풀 | 랜덤UA |
---|---|---|---|---|---|---|---|
4(우선순위 높음) | 3 | 2 | 1 | .5 | .5 | .5 | .175 |
HTTP/2의 주요 이점은 단일 연결 내에서 많은 요청을 멀티플렉싱할 수 있으므로 동시 요청 수에 대한 제한이 [거의] 제거되며 자체 백엔드와 통신할 때 이러한 제한이 없다는 것입니다. 백엔드에 HTTP/2를 사용하면 여러 연결 대신 단일 TCP 연결이 사용되기 때문에 상황이 더 악화되므로 Http2가 우선 순위가 아닙니다(#ref).
이 프로젝트의 소스 파일을 IDE의 Include Path
에 추가합니다.
(작곡기를 사용하여 설치한 경우 전체 공급업체 폴더를 포함할 수 있으며 PHPStorm이 자동으로 이를 포함합니다.)
좋은 코멘트 작성을 통해 Saber는 IDE 자동 프롬프트를 완벽하게 지원합니다. 모든 개체 메서드 이름을 보려면 개체 뒤에 화살표 기호를 쓰면 됩니다. 많은 메서드는 PSR 사양을 따르거나 참조하여 구현됩니다. Guzzle 프로젝트 (감사합니다) .
기본 Swoole 관련 클래스에 대한 IDE 프롬프트의 경우 Eaglewu의 swoole-ide-helper를 도입해야 합니다(컴포저는 개발 환경에 기본적으로 설치됩니다). 그러나 이 프로젝트는 수동으로 유지 관리되며 Swoft를 사용할 수도 있습니다. -ide-helper 또는:
Swoole의 공식 ide-helper입니다.
이슈 및 PR 제출을 환영합니다.
코루틴(__call, __callStatic)은 매직 메서드에서 사용할 수 없으므로 소스 코드의 메서드는 수동으로 정의됩니다.
사용 편의성을 위해 지원되는 모든 요청 방법에 별칭이 제공되었습니다.
public static function psr( array $ options = []): Swlib Saber Request
public static function wait(): Swlib Saber
public static function request( array $ options = [])
public static function get (string $ uri , array $ options = [])
public static function delete (string $ uri , array $ options = [])
public static function head (string $ uri , array $ options = [])
public static function options (string $ uri , array $ options = [])
public static function post (string $ uri , $ data = null , array $ options = [])
public static function put (string $ uri , $ data = null , array $ options = [])
public static function patch (string $ uri , $ data = null , array $ options = [])
public static function download (string $ uri , string $ dir , int $ offset , array $ options = [])
public static function requests (array $ requests , array $ default_options = []): Swlib Saber ResponseMap
public static function list(array $ options , array $ default_options = []): Swlib Saber ResponseMap
public static function websocket (string $ uri )
public static function default (?array $ options = null ): array
public static function exceptionReport (?int $ level = null ): int
public static function exceptionHandle (callable $ handle ): void
public static function create( array $ options = []): self
public static function session( array $ options = []): self
public static function websocket( string $ uri ): WebSocket
public function request( array $ options )
public function get( string $ uri , array $ options = [])
public function delete( string $ uri , array $ options = [])
public function head( string $ uri , array $ options = [])
public function options( string $ uri , array $ options = [])
public function post( string $ uri , $ data = null , array $ options = [])
public function put( string $ uri , $ data = null , array $ options = [])
public function patch( string $ uri , $ data = null , array $ options = [])
public function download( string $ uri , string $ dir , int $ offset , array $ options = [])
public function requests( array $ requests , array $ default_options = []): ResponseMap
public function list( array $ options , array $ default_options = []): ResponseMap
public function upgrade(? string $ path = null ): WebSocket
public function psr( array $ options = []): Request
public function wait(): self
public function exceptionReport(? int $ level = null ): int
public function exceptionHandle( callable $ handle ): void
public static function getAliasMap(): array
public function setOptions( array $ options = [], ? Swlib Saber Request $ request = null ): self
public static function getDefaultOptions(): array
public static function setDefaultOptions( array $ options = [])
public function getExceptionReport(): int
public function setExceptionReport( int $ level ): self
public function isWaiting(): bool
public function getPool()
public function withPool( $ bool_or_max_size ): self
public function tryToRevertClientToPool( bool $ connect_failed = false )
public function getSSL(): int
public function withSSL( int $ mode = 2 ): self
public function getCAFile(): string
public function withCAFile( string $ ca_file = __DIR__ . ' /cacert.pem ' ): self
public function getSSLCertFile(): string
public function withSSLCertFile( string $ cert_file ): self
public function getSSLKeyFile(): string
public function withSSLKeyFile( string $ key_file ): self
public function withSSLVerifyPeer( bool $ verify_peer = false , ? string $ ssl_host_name = '' ): self
public function withSSLAllowSelfSigned( bool $ allow = true ): self
public function getSSLConf()
public function getKeepAlive()
public function withKeepAlive( bool $ enable ): self
public function withBasicAuth(? string $ username = null , ? string $ password = null ): self
public function withXHR( bool $ enable = true )
public function getProxy(): array
public function withProxy( string $ host , int $ port ): self
public function withSocks5( string $ host , int $ port , ? string $ username , ? string $ password ): self
public function withoutProxy(): self
public function getBindAddress(): ? string
public function withBindAddress( string $ address ): self
public function getBindPort(): ? int
public function withBindPort( int $ port ): self
public function getTimeout(): float
public function withTimeout( float $ timeout ): self
public function getRedirect(): int
public function getName()
public function withName( $ name ): self
public function withRedirect( int $ time ): self
public function isInQueue(): bool
public function withInQueue( bool $ enable ): self
public function getRetryTime(): int
public function withRetryTime( int $ time ): self
public function withAutoIconv( bool $ enable ): self
public function withExpectCharset( string $ source = ' auto ' , string $ target = ' utf-8 ' , bool $ use_mb = false ): self
public function withDownloadDir( string $ dir ): self
public function withDownloadOffset( int $ offset ): self
public function resetClient( $ client )
public function exec()
public function recv()
public function getRequestTarget(): string
public function withRequestTarget( $ requestTarget ): self
public function getMethod(): string
public function withMethod( $ method ): self
public function getUri(): Psr Http Message UriInterface
public function withUri(? Psr Http Message UriInterface $ uri , $ preserveHost = false ): self
public function getCookieParams(): array
public function getCookieParam( string $ name ): string
public function withCookieParam( string $ name , ? string $ value ): self
public function withCookieParams( array $ cookies ): self
public function getQueryParam( string $ name ): string
public function getQueryParams(): array
public function withQueryParam( string $ name , ? string $ value ): self
public function withQueryParams( array $ query ): self
public function getParsedBody(? string $ name = null )
public function withParsedBody( $ data ): self
public function getUploadedFile( string $ name ): Psr Http Message UploadedFileInterface
public function getUploadedFiles(): array
public function withUploadedFile( string $ name , ? Psr Http Message UploadedFileInterface $ uploadedFile ): self
public function withoutUploadedFile( string $ name ): self
public function withUploadedFiles( array $ uploadedFiles ): self
public function __toString()
public function getProtocolVersion(): string
public function withProtocolVersion( $ version ): self
public function hasHeader( $ name ): bool
public function getHeader( $ name ): array
public function getHeaderLine( $ name ): string
public function getHeaders( bool $ implode = false , bool $ ucwords = false ): array
public function getHeadersString( bool $ ucwords = true ): string
public function withHeader( $ raw_name , $ value ): self
public function withHeaders( array $ headers ): self
public function withAddedHeaders( array $ headers ): self
public function withAddedHeader( $ raw_name , $ value ): self
public function withoutHeader( $ name ): self
public function getBody(): Psr Http Message StreamInterface
public function withBody(? Psr Http Message StreamInterface $ body ): self
public function getCookies()
public function setCookie( array $ options ): self
public function unsetCookie( string $ name , string $ path = '' , string $ domain = '' ): self
public function withInterceptor( string $ name , array $ interceptor )
public function withAddedInterceptor( string $ name , array $ functions ): self
public function withoutInterceptor( string $ name ): self
public function callInterceptor( string $ name , $ arguments )
public function getSpecialMark( string $ name = ' default ' )
public function withSpecialMark( $ mark , string $ name = ' default ' ): self
public function isSuccess(): bool
public function getUri(): Psr Http Message UriInterface
public function getTime(): float
public function getRedirectHeaders(): array
public function getStatusCode()
public function withStatus( $ code , $ reasonPhrase = '' )
public function getReasonPhrase()
public function __toString()
public function getProtocolVersion(): string
public function withProtocolVersion( $ version ): self
public function hasHeader( $ name ): bool
public function getHeader( $ name ): array
public function getHeaderLine( $ name ): string
public function getHeaders( bool $ implode = false , bool $ ucwords = false ): array
public function getHeadersString( bool $ ucwords = true ): string
public function withHeader( $ raw_name , $ value ): self
public function withHeaders( array $ headers ): self
public function withAddedHeaders( array $ headers ): self
public function withAddedHeader( $ raw_name , $ value ): self
public function withoutHeader( $ name ): self
public function getBody(): Psr Http Message StreamInterface
public function withBody(? Psr Http Message StreamInterface $ body ): self
public function getCookies()
public function setCookie( array $ options ): self
public function unsetCookie( string $ name , string $ path = '' , string $ domain = '' ): self
public function getSpecialMark( string $ name = ' default ' )
public function withSpecialMark( $ mark , string $ name = ' default ' ): self
public function getParsedJsonArray( bool $ reParse = false ): array
public function getParsedJsonObject( bool $ reParse = false ): object
public function getParsedQueryArray( bool $ reParse = false ): array
public function getParsedXmlArray( bool $ reParse = false ): array
public function getParsedXmlObject( bool $ reParse = false ): SimpleXMLElement
public function getParsedDomObject( bool $ reParse = false ): DOMDocument
public function getDataRegexMatch( string $ regex , $ group = null , int $ fill_size )
public function getDataRegexMatches( string $ regex , int $ flag ): array
public function isExistInData( string $ needle , int $ offset )
public function enqueue( $ request )
public function getMaxConcurrency(): int
public function withMaxConcurrency( int $ num = - 1 ): self
public function recv(): Swlib Saber ResponseMap
public function withInterceptor( string $ name , array $ interceptor )
public function withAddedInterceptor( string $ name , array $ functions ): self
public function withoutInterceptor( string $ name ): self
public function callInterceptor( string $ name , $ arguments )
public $ time = 0.0 ;
public $ status_map = [];
public $ success_map = [];
public $ success_num = 0 ;
public $ error_num = 0 ;
public function offsetSet( $ index , $ response )
public function __toString()
public function withMock( bool $ ssl ): self
public function recv( float $ timeout = - 1 )
public function push( string $ data , int $ opcode = 1 , bool $ finish = true ): bool
public function close(): bool
public $ finish = true ;
public $ opcode = null ;
public $ data = null ;
public function getOpcodeDefinition()
public function getOpcode()
public function getData()
public function __toString()