AMPHP는 파이버 및 동시성을 염두에 두고 설계된 PHP용 이벤트 중심 라이브러리 모음입니다. 이 패키지는 Revolt를 기반으로 하는 PHP용 비차단 동시 HTTP/1.1 및 HTTP/2 애플리케이션 서버를 제공합니다. WebSocket 구성요소와 같은 여러 기능이 별도의 패키지로 제공됩니다.
이 패키지는 Composer 종속성으로 설치할 수 있습니다.
composer require amphp/http-server
또한 FFI를 활용하여 속도를 높이고 메모리 사용량을 줄이기 위해 nghttp2
라이브러리를 설치할 수도 있습니다.
이 라이브러리는 HTTP 프로토콜을 통해 애플리케이션에 대한 액세스를 제공하고, 클라이언트 요청을 수락하고 해당 요청을 애플리케이션에서 정의한 핸들러에 전달하여 응답을 반환합니다.
들어오는 요청은 Request
개체로 표시됩니다. Response
인스턴스를 반환하는 handleRequest()
메서드를 정의하는 RequestHandler
구현자에게 요청이 제공됩니다.
public function handleRequest( Request $ request ): Response
요청 핸들러는 RequestHandler
섹션에서 더 자세히 다룹니다.
이 HTTP 서버는 Revolt 이벤트 루프와 비차단 동시성 프레임워크 Amp 위에 구축되었습니다. 따라서 모든 기본 요소에 대한 완전한 지원을 상속받으며 Revolt 위에 구축된 모든 비차단 라이브러리를 사용할 수 있습니다.
참고 일반적으로 HTTP 서버를 성공적으로 사용하려면
Future
개념 과 코루틴을 숙지하고 여러 결합자 기능을 알고 있어야 합니다.
PHP의 거의 모든 내장 기능은 차단 I/O를 수행합니다. 즉, 실행 스레드(대부분 PHP의 경우 프로세스와 동일)가 응답을 수신할 때까지 효과적으로 중단된다는 의미입니다. 이러한 함수의 몇 가지 예: mysqli_query
, file_get_contents
, usleep
등.
좋은 경험 법칙은 다음과 같습니다. I/O를 수행하는 모든 내장 PHP 함수는 확실히 그렇지 않은 경우를 제외하고는 차단 방식으로 수행됩니다.
비차단 I/O를 사용하는 구현을 제공하는 라이브러리가 있습니다. 내장 함수 대신 이러한 기능을 사용해야 합니다.
우리는 네트워크 소켓, 파일 액세스, HTTP 요청 및 웹 소켓, MySQL 및 Postgres 데이터베이스 클라이언트, Redis와 같은 가장 일반적인 I/O 요구 사항을 다룹니다. 요청을 이행하기 위해 차단 I/O를 사용하거나 긴 계산이 필요한 경우 병렬 라이브러리를 사용하여 별도의 프로세스나 스레드에서 해당 코드를 실행하는 것이 좋습니다.
경고 HTTP 서버에서는 차단 I/O 기능을 사용하지 마십시오.
// Here's a bad example, DO NOT do something like the following!
$ handler = new ClosureRequestHandler ( function () {
sleep ( 5 ); // Equivalent to a blocking I/O function with a 5 second timeout
return new Response ;
});
// Start a server with this handler and hit it twice.
// You'll have to wait until the 5 seconds are over until the second request is handled.
귀하의 애플리케이션은 HttpServer
인스턴스에 의해 제공됩니다. 이 라이브러리는 이 라이브러리와 amphp/socket
에 있는 구성 요소를 기반으로 구축되어 대부분의 애플리케이션에 적합한 SocketHttpServer
제공합니다.
SocketHttpServer
인스턴스를 생성하고 요청을 수신하려면 최소한 네 가지가 필요합니다.
RequestHandler
인스턴스,ErrorHander
의 인스턴스,PsrLogLoggerInterface
인스턴스 및 <?php
use Amp ByteStream ;
use Amp Http HttpStatus ;
use Amp Http Server DefaultErrorHandler ;
use Amp Http Server Request ;
use Amp Http Server RequestHandler ;
use Amp Http Server Response ;
use Amp Http Server SocketHttpServer ;
use Amp Log ConsoleFormatter ;
use Amp Log StreamHandler ;
use Monolog Logger ;
use Monolog Processor PsrLogMessageProcessor ;
require __DIR__ . ' /vendor/autoload.php ' ;
// Note any PSR-3 logger may be used, Monolog is only an example.
$ logHandler = new StreamHandler ( ByteStream getStdout ());
$ logHandler -> pushProcessor ( new PsrLogMessageProcessor ());
$ logHandler -> setFormatter ( new ConsoleFormatter ());
$ logger = new Logger ( ' server ' );
$ logger -> pushHandler ( $ logHandler );
$ requestHandler = new class () implements RequestHandler {
public function handleRequest ( Request $ request ) : Response
{
return new Response (
status: HttpStatus:: OK ,
headers: [ ' Content-Type ' => ' text/plain ' ],
body: ' Hello, world! ' ,
);
}
};
$ errorHandler = new DefaultErrorHandler ();
$ server = SocketHttpServer:: createForDirectAccess ( $ logger );
$ server -> expose ( ' 127.0.0.1:1337 ' );
$ server -> start ( $ requestHandler , $ errorHandler );
// Serve requests until SIGINT or SIGTERM is received by the process.
Amp trapSignal ([ SIGINT , SIGTERM ]);
$ server -> stop ();
위의 예는 수신된 모든 요청에 대해 일반 텍스트 응답을 보내는 간단한 서버를 만듭니다.
SocketHttpServer
고급 및 사용자 정의 사용을 위한 일반 생성자 외에 일반적인 사용 사례를 위한 두 개의 정적 생성자를 제공합니다.
SocketHttpServer::createForDirectAccess()
: 위의 예에서 사용된 이 명령은 직접 네트워크 액세스에 적합한 HTTP 애플리케이션 서버를 생성합니다. 조정 가능한 제한은 IP당 연결 수, 총 연결 수, 동시 요청 수(기본적으로 각각 10, 1000, 1000)에 적용됩니다. 응답 압축은 켜거나 끌 수 있으며(기본적으로 켜짐) 요청 방법은 기본적으로 알려진 HTTP 동사 집합으로 제한됩니다.SocketHttpServer::createForBehindProxy()
: nginx와 같은 프록시 서비스 뒤에서 사용하기에 적합한 서버를 생성합니다. 이 정적 생성자에는 요청 헤더에서 원래 클라이언트 IP를 구문 분석하기 위해 신뢰할 수 있는 프록시 IP 목록(선택적 서브넷 마스크 포함)과 ForwardedHeaderType
( Forwarded
또는 X-Forwarded-For
에 해당)의 열거형 사례가 필요합니다. 서버 연결 수에는 제한이 없지만 동시 요청 수는 제한됩니다(기본적으로 1000개, 조정 가능 또는 제거 가능). 응답 압축은 켜거나 끌 수 있습니다(기본적으로 켜짐). 요청 방법은 기본적으로 알려진 HTTP 동사 집합으로 제한됩니다. 이러한 메서드 중 어느 것도 애플리케이션 요구 사항을 충족하지 못하는 경우 SocketHttpServer
생성자를 직접 사용할 수 있습니다. 이는 들어오는 연결 클라이언트 연결을 생성하고 처리하는 방법에 엄청난 유연성을 제공하지만 생성하려면 더 많은 코드가 필요합니다. 생성자는 사용자가 클라이언트 Socket
인스턴스( amphp/socket
라이브러리의 두 구성 요소 모두)를 생성하는 데 사용되는 SocketServerFactory
인스턴스와 클라이언트가 만든 각 Request
에 첨부되는 Client
인스턴스를 적절하게 생성하는 ClientFactory
인스턴스를 전달하도록 요구합니다. .
RequestHandler
들어오는 요청은 Request
개체로 표시됩니다. Response
인스턴스를 반환하는 handleRequest()
메서드를 정의하는 RequestHandler
구현자에게 요청이 제공됩니다.
public function handleRequest( Request $ request ): Response
각 클라이언트 요청(예: RequestHandler::handleRequest()
호출)은 별도의 코루틴 내에서 실행되므로 요청은 서버 프로세스 내에서 자동으로 협력적으로 처리됩니다. 요청 핸들러가 비차단 I/O를 기다리는 경우 다른 클라이언트 요청은 동시 코루틴에서 처리됩니다. 요청 처리기는 단일 요청에 대해 여러 작업을 실행하기 위해 Ampasync()
사용하여 자체적으로 다른 코루틴을 생성할 수 있습니다.
일반적으로 RequestHandler
는 응답을 직접 생성하지만 다른 RequestHandler
에 위임할 수도 있습니다. 이러한 위임 RequestHandler
의 예는 Router
입니다.
RequestHandler
인터페이스는 사용자 정의 클래스로 구현됩니다. 매우 간단한 사용 사례나 빠른 조롱의 경우 모든 callable
래핑하고 Request
를 수락하고 Response
를 반환할 수 있는 CallableRequestHandler
를 사용할 수 있습니다.
미들웨어를 사용하면 요청 전처리와 응답 후처리가 가능합니다. 그 외에도 미들웨어는 요청 처리를 가로채고 전달된 요청 처리기에 위임하지 않고 응답을 반환할 수도 있습니다. 클래스는 이를 위해 Middleware
인터페이스를 구현해야 합니다.
참고 미들웨어는 일반적으로 소프트 및 하드웨어와 같은 다른 단어 뒤에 복수형이 붙습니다. 그러나 우리는 미들웨어 라는 용어를 사용하여
Middleware
인터페이스를 구현하는 여러 개체를 나타냅니다.
public function handleRequest( Request $ request , RequestHandler $ next ): Response
handleRequest
는 Middleware
인터페이스의 유일한 메소드입니다. Middleware
요청 자체를 처리하지 않는 경우 응답 생성을 수신된 RequestHandler
에 위임해야 합니다.
function stackMiddleware( RequestHandler $ handler , Middleware ... $ middleware ): RequestHandler
AmpHttpServerMiddlewarestackMiddleware()
사용하여 여러 미들웨어를 스택할 수 있습니다. 이는 RequestHandler
를 첫 번째 인수로 받아들이고 다양한 수의 Middleware
인스턴스를 허용합니다. 반환된 RequestHandler
제공된 순서대로 각 미들웨어를 호출합니다.
$ requestHandler = new class implements RequestHandler {
public function handleRequest ( Request $ request ): Response
{
return new Response (
status: HttpStatus:: OK ,
headers: [ " content-type " => " text/plain; charset=utf-8 " ],
body: " Hello, World! " ,
);
}
}
$ middleware = new class implements Middleware {
public function handleRequest ( Request $ request , RequestHandler $ next ): Response
{
$ requestTime = microtime ( true );
$ response = $ next -> handleRequest ( $ request );
$ response -> setHeader ( " x-request-time " , microtime ( true ) - $ requestTime );
return $ response ;
}
};
$ stackedHandler = Middleware stackMiddleware ( $ requestHandler , $ middleware );
$ errorHandler = new DefaultErrorHandler ();
// $logger is a PSR-3 logger instance.
$ server = SocketHttpServer:: createForDirectAccess ( $ logger );
$ server -> expose ( ' 127.0.0.1:1337 ' );
$ server -> start ( $ stackedHandler , $ errorHandler );
ErrorHandler
ErrorHander
형식이 잘못되었거나 유효하지 않은 요청이 수신될 때 HTTP 서버에서 사용됩니다. Request
객체는 들어오는 데이터로부터 생성된 경우 제공되지만 항상 설정되지는 않을 수도 있습니다.
public function handleError(
int $ status ,
? string $ reason = null ,
? Request $ request = null ,
): Response
이 라이브러리는 양식화된 HTML 페이지를 응답 본문으로 반환하는 DefaultErrorHandler
제공합니다. 잠재적으로 라우터와 함께 여러 개를 사용하여 애플리케이션에 대해 다른 구현을 제공할 수 있습니다.
Request
일반적으로 서버에 의해 RequestHandler::handleRequest()
에 제공되므로 Request
개체를 직접 구성해야 하는 경우는 거의 없습니다.
/**
* @param string $method The HTTP method verb.
* @param array<string>|array<string, array<string>> $headers An array of strings or an array of string arrays.
*/
public function __construct(
private readonly Client $ client ,
string $ method ,
Psr Http Message UriInterface $ uri ,
array $ headers = [],
Amp ByteStream ReadableStream | string $ body = '' ,
private string $ protocol = ' 1.1 ' ,
? Trailers $ trailers = null ,
)
public function getClient(): Client
요청을 보내는 Сlient
반환합니다.
public function getMethod(): string
이 요청을 수행하는 데 사용된 HTTP 메소드를 반환합니다(예: "GET"
.
public function setMethod( string $ method ): void
요청 HTTP 메소드를 설정합니다.
public function getUri(): Psr Http Message UriInterface
요청 URI
반환합니다.
public function setUri( Psr Http Message UriInterface $ uri ): void
요청에 대한 새 URI
설정합니다.
public function getProtocolVersion(): string
HTTP 프로토콜 버전을 문자열(예: "1.0", "1.1", "2")로 반환합니다.
public function setProtocolVersion( string $ protocol )
요청에 대한 새 프로토콜 버전 번호를 설정합니다.
/** @return array<non-empty-string, list<string>> */
public function getHeaders(): array
헤더를 문자열 배열의 문자열 인덱스 배열로 반환하거나 헤더가 설정되지 않은 경우 빈 배열로 반환합니다.
public function hasHeader( string $ name ): bool
주어진 헤더가 존재하는지 확인합니다.
/** @return list<string> */
public function getHeaderArray( string $ name ): array
주어진 헤더에 대한 값의 배열을 반환하거나 헤더가 존재하지 않는 경우 빈 배열을 반환합니다.
public function getHeader( string $ name ): ? string
주어진 헤더의 값을 반환합니다. 명명된 헤더에 여러 헤더가 있는 경우 첫 번째 헤더 값만 반환됩니다. 특정 헤더에 대한 모든 값의 배열을 반환하려면 getHeaderArray()
사용하세요. 헤더가 없으면 null
반환합니다.
public function setHeaders( array $ headers ): void
주어진 배열에서 헤더를 설정합니다.
/** @param array<string>|string $value */
public function setHeader( string $ name , array | string $ value ): void
헤더를 지정된 값으로 설정합니다. 해당 이름을 가진 모든 이전 헤더 행이 대체됩니다.
/** @param array<string>|string $value */
public function addHeader( string $ name , array | string $ value ): void
주어진 이름을 가진 추가 헤더 라인을 추가합니다.
public function removeHeader( string $ name ): void
해당 헤더가 있는 경우 해당 헤더를 제거합니다. 동일한 이름의 헤더 행이 여러 개 존재하는 경우 모두 제거됩니다.
public function getBody(): RequestBody
요청 본문을 반환합니다. RequestBody
사용하면 InputStream
에 대한 스트리밍 및 버퍼링 액세스가 가능합니다.
public function setBody( ReadableStream | string $ body )
메시지 본문의 스트림을 설정합니다.
참고 문자열을 사용하면 자동으로
Content-Length
헤더가 지정된 문자열의 길이로 설정됩니다.ReadableStream
을 설정하면Content-Length
헤더가 제거됩니다. 스트림의 정확한 콘텐츠 길이를 알고 있는 경우setBody()
호출한 후content-length
헤더를 추가할 수 있습니다.
/** @return array<non-empty-string, RequestCookie> */
public function getCookies(): array
쿠키 이름의 연관 맵에 있는 모든 쿠키를 RequestCookie
에 반환합니다.
public function getCookie( string $ name ): ? RequestCookie
이름 또는 null
로 쿠키 값을 가져옵니다.
public function setCookie( RequestCookie $ cookie ): void
요청에 Cookie
추가합니다.
public function removeCookie( string $ name ): void
요청에서 쿠키를 제거합니다.
public function getAttributes(): array
요청의 변경 가능한 로컬 저장소에 저장된 모든 속성의 배열을 반환합니다.
public function removeAttributes(): array
요청의 변경 가능한 로컬 저장소에서 모든 요청 속성을 제거합니다.
public function hasAttribute( string $ name ): bool
요청의 변경 가능한 로컬 저장소에 해당 이름의 속성이 존재하는지 확인하세요.
public function getAttribute( string $ name ): mixed
요청의 변경 가능한 로컬 저장소에서 변수를 검색합니다.
참고 특성 이름은 클래스와 같이 공급업체 및 패키지 네임스페이스로 네임스페이스를 지정해야 합니다.
public function setAttribute( string $ name , mixed $ value ): void
요청의 변경 가능한 로컬 저장소에 변수를 할당합니다.
참고 특성 이름은 클래스와 같이 공급업체 및 패키지 네임스페이스로 네임스페이스를 지정해야 합니다.
public function removeAttribute( string $ name ): void
요청의 변경 가능한 로컬 저장소에서 변수를 제거합니다.
public function getTrailers(): Trailers
요청 Trailers
에 대한 액세스를 허용합니다.
public function setTrailers( Trailers $ trailers ): void
요청에 사용할 Trailers
개체를 할당합니다.
클라이언트 관련 세부 정보는 Request::getClient()
에서 반환된 AmpHttpServerDriverClient
객체에 번들로 제공됩니다. Client
인터페이스는 원격 및 로컬 소켓 주소와 TLS 정보(해당되는 경우)를 검색하는 방법을 제공합니다.
Response
Response
클래스는 HTTP 응답을 나타냅니다. 요청 핸들러와 미들웨어에 의해 Response
반환됩니다.
/**
* @param int $code The HTTP response status code.
* @param array<string>|array<string, array<string>> $headers An array of strings or an array of string arrays.
*/
public function __construct(
int $ code = HttpStatus:: OK ,
array $ headers = [],
Amp ByteStream ReadableStream | string $ body = '' ,
? Trailers $ trailers = null ,
)
dispose 핸들러(즉, onDispose()
메서드를 통해 등록된 함수)를 호출합니다.
참고 처리 핸들러에서 포착되지 않은 예외는 이벤트 루프 오류 핸들러로 전달됩니다.
public function getBody(): Amp ByteStream ReadableStream
메시지 본문의 스트림을 반환합니다.
public function setBody( Amp ByteStream ReadableStream | string $ body )
메시지 본문의 스트림을 설정합니다.
참고 문자열을 사용하면 자동으로
Content-Length
헤더가 지정된 문자열의 길이로 설정됩니다.ReadableStream
을 설정하면Content-Length
헤더가 제거됩니다. 스트림의 정확한 콘텐츠 길이를 알고 있는 경우setBody()
호출한 후content-length
헤더를 추가할 수 있습니다.
/** @return array<non-empty-string, list<string>> */
public function getHeaders(): array
헤더를 문자열 배열의 문자열 인덱스 배열로 반환하거나 헤더가 설정되지 않은 경우 빈 배열로 반환합니다.
public function hasHeader( string $ name ): bool
주어진 헤더가 존재하는지 확인합니다.
/** @return list<string> */
public function getHeaderArray( string $ name ): array
주어진 헤더에 대한 값의 배열을 반환하거나 헤더가 존재하지 않는 경우 빈 배열을 반환합니다.
public function getHeader( string $ name ): ? string
주어진 헤더의 값을 반환합니다. 명명된 헤더에 여러 헤더가 있는 경우 첫 번째 헤더 값만 반환됩니다. 특정 헤더에 대한 모든 값의 배열을 반환하려면 getHeaderArray()
사용하세요. 헤더가 없으면 null
반환합니다.
public function setHeaders( array $ headers ): void
주어진 배열에서 헤더를 설정합니다.
/** @param array<string>|string $value */
public function setHeader( string $ name , array | string $ value ): void
헤더를 지정된 값으로 설정합니다. 해당 이름을 가진 이전 헤더 행이 모두 교체됩니다.
/** @param array<string>|string $value */
public function addHeader( string $ name , array | string $ value ): void
주어진 이름을 가진 추가 헤더 라인을 추가합니다.
public function removeHeader( string $ name ): void
해당 헤더가 있는 경우 해당 헤더를 제거합니다. 동일한 이름의 헤더 행이 여러 개 존재하는 경우 모두 제거됩니다.
public function getStatus(): int
응답 상태 코드를 반환합니다.
public function getReason(): string
상태 코드를 설명하는 이유 문구를 반환합니다.
public function setStatus( int $ code , string | null $ reason ): void
숫자로 된 HTTP 상태 코드(100~599)와 이유 문구를 설정합니다. 상태 코드와 관련된 기본 문구를 사용하려면 이유 문구로 null을 사용하세요.
/** @return array<non-empty-string, ResponseCookie> */
public function getCookies(): array
쿠키 이름의 연관 맵에 있는 모든 쿠키를 ResponseCookie
에 반환합니다.
public function getCookie( string $ name ): ? ResponseCookie
해당 이름을 가진 쿠키가 없으면 이름으로 쿠키 값을 가져오거나 null
가져옵니다.
public function setCookie( ResponseCookie $ cookie ): void
응답에 쿠키를 추가합니다.
public function removeCookie( string $ name ): void
응답에서 쿠키를 제거합니다.
/** @return array<string, Push> Map of URL strings to Push objects. */
public function getPushes(): array
Push
개체에 대한 URL 문자열의 연관 맵에서 푸시 리소스 목록을 반환합니다.
/** @param array<string>|array<string, array<string>> $headers */
public function push( string $ url , array $ headers ): void
클라이언트가 가져와야 할 리소스를 나타냅니다. (예: Link: preload
또는 HTTP/2 서버 푸시).
public function isUpgraded(): bool
분리 콜백이 설정된 경우 true
반환하고, 없는 경우 false
반환합니다.
/** @param Closure(DriverUpgradedSocket, Request, Response): void $upgrade */
public function upgrade( Closure $ upgrade ): void
응답이 클라이언트에 기록되면 호출될 콜백을 설정하고 응답 상태를 101 Switching Protocols
로 변경합니다. 콜백은 DriverUpgradedSocket
인스턴스, 업그레이드를 시작한 Request
및 이 Response
수신합니다.
상태를 101이 아닌 다른 것으로 변경하면 콜백이 제거될 수 있습니다.
public function getUpgradeCallable(): ? Closure
존재하는 경우 업그레이드 기능을 반환합니다.
/** @param Closure():void $onDispose */
public function onDispose( Closure $ onDispose ): void
응답이 삭제될 때 호출되는 함수를 등록합니다. 응답은 클라이언트에 기록되거나 미들웨어 체인에서 대체되면 폐기됩니다.
public function getTrailers(): Trailers
응답 Trailers
에 대한 액세스를 허용합니다.
public function setTrailers( Trailers $ trailers ): void
응답에 사용할 Trailers
개체를 할당합니다. 전체 응답 본문이 클라이언트로 설정되면 예고편이 전송됩니다.
Request::getBody()
에서 반환된 RequestBody
요청 본문에 대한 버퍼링 및 스트리밍 액세스를 제공합니다. 스트리밍 액세스를 사용하여 대용량 메시지를 처리합니다. 이는 메시지 제한이 더 크고(예: 수십 메가바이트) 모든 메시지를 메모리에 버퍼링하고 싶지 않은 경우 특히 중요합니다. 여러 사람이 동시에 큰 본문을 업로드하는 경우 메모리가 빨리 소모될 수 있습니다.
따라서 AmpByteStreamReadableStream
의 read()
API를 통해 액세스할 수 있는 증분 처리가 중요합니다.
클라이언트 연결이 끊어지면 AmpHttpServerClientException
으로 인해 read()
가 실패합니다. 이 예외는 read()
및 buffer()
API 모두에 대해 발생합니다.
참고
ClientException
을 포착할 필요는 없습니다. 계속하고 싶다면 잡을 수 있지만 반드시 그럴 필요는 없습니다. 서버는 요청 주기를 자동으로 종료하고 해당 예외를 삭제합니다.
일반 본문 제한을 높게 설정하는 대신 필요한 경우에만 본문 제한을 늘리는 것을 고려해야 합니다. 이는 RequestBody
의 increaseSizeLimit()
메서드를 사용하여 동적으로 가능합니다.
참고
RequestBody
자체는 양식 데이터 구문 분석을 제공하지 않습니다. 필요한 경우amphp/http-server-form-parser
사용할 수 있습니다.
Request
와 마찬가지로 RequestBody
인스턴스는 Request
의 일부로 제공되므로 생성할 필요가 거의 없습니다.
public function __construct(
ReadableStream | string $ stream ,
? Closure $ upgradeSize = null ,
)
public function increaseSizeLimit( int $ limit ): void
개별 요청 핸들러가 HTTP 서버에 대해 기본 설정된 것보다 더 큰 요청 본문을 처리할 수 있도록 본문 크기 제한을 동적으로 늘립니다.
Trailers
클래스를 사용하면 Request::getTrailers()
통해 액세스할 수 있는 HTTP 요청의 트레일러에 액세스할 수 있습니다. 요청에 트레일러가 필요하지 않은 경우 null
이 반환됩니다. Trailers::await()
트레일러 헤더에 액세스하기 위한 메소드를 제공하는 HttpMessage
객체로 해결되는 Future
를 반환합니다.
$ trailers = $ request -> getTrailers ();
$ message = $ trailers ?->await();
HTTP 서버는 병목 현상이 발생하지 않습니다. 잘못된 구성, 차단 I/O 사용 또는 비효율적인 응용 프로그램이 있습니다.
서버는 잘 최적화되어 있으며 수천 개의 클라이언트에 대한 높은 동시성을 유지하면서 일반적인 하드웨어에서 초당 수만 개의 요청을 처리할 수 있습니다.
그러나 비효율적인 애플리케이션에서는 성능이 크게 저하됩니다. 서버에는 클래스와 핸들러가 항상 로드된다는 장점이 있으므로 컴파일 및 초기화에 시간이 낭비되지 않습니다.
일반적인 함정은 간단한 문자열 작업으로 빅 데이터 작업을 시작하여 비효율적인 큰 복사본을 많이 필요로 하는 것입니다. 대신, 더 큰 요청 및 응답 본문에는 가능한 경우 스트리밍을 사용해야 합니다.
문제는 실제로 CPU 비용입니다. 비효율적인 I/O 관리(비차단인 경우)는 개별 요청을 지연시킬 뿐입니다. 동시에 디스패치하고 결국에는 Amp의 결합자를 통해 여러 개의 독립적인 I/O 요청을 묶는 것이 권장되지만, 느린 핸들러는 다른 모든 요청도 느리게 만듭니다. 하나의 핸들러가 컴퓨팅을 수행하는 동안 다른 모든 핸들러는 계속할 수 없습니다. 따라서 핸들러의 계산 시간을 최소한으로 줄이는 것이 필수적입니다.
저장소의 ./examples
디렉터리에서 몇 가지 예제를 찾을 수 있습니다. 이는 명령줄에서 일반 PHP 스크립트로 실행될 수 있습니다.
php examples/hello-world.php
그런 다음 브라우저에서 http://localhost:1337/
의 예제 서버에 액세스할 수 있습니다.
보안 관련 문제를 발견한 경우 공개 문제 추적기를 사용하는 대신 비공개 보안 문제 보고기를 사용하세요.
MIT 라이센스(MIT). 자세한 내용은 라이센스를 참조하세요.