AMPHP คือชุดไลบรารีที่ขับเคลื่อนด้วยเหตุการณ์สำหรับ PHP ซึ่งได้รับการออกแบบโดยคำนึงถึงไฟเบอร์และการทำงานพร้อมกัน แพ็คเกจนี้มอบเซิร์ฟเวอร์แอปพลิเคชัน HTTP/1.1 และ HTTP/2 พร้อมกันที่ไม่มีการปิดกั้นสำหรับ PHP ที่ใช้ Revolt คุณสมบัติหลายอย่างมีให้ในแพ็คเกจแยกกัน เช่น ส่วนประกอบ WebSocket
แพ็คเกจนี้สามารถติดตั้งเป็นการพึ่งพานักแต่งเพลง
composer require amphp/http-server
นอกจากนี้ คุณอาจต้องการติดตั้งไลบรารี nghttp2
เพื่อใช้ประโยชน์จาก FFI เพื่อเพิ่มความเร็วและลดการใช้หน่วยความจำ
ไลบรารีนี้ให้การเข้าถึงแอปพลิเคชันของคุณผ่านโปรโตคอล HTTP การยอมรับคำขอของลูกค้า และส่งต่อคำขอเหล่านั้นไปยังตัวจัดการที่กำหนดโดยแอปพลิเคชันของคุณซึ่งจะส่งคืนการตอบกลับ
คำขอที่เข้ามาจะแสดงด้วยออบเจ็กต์ Request
มีการจัดเตรียมคำขอให้กับผู้ดำเนินการของ RequestHandler
ซึ่งกำหนดเมธอด handleRequest()
ที่ส่งคืนอินสแตนซ์ของ Response
public function handleRequest( Request $ request ): Response
ตัวจัดการคำขอจะครอบคลุมรายละเอียดมากขึ้นในส่วน RequestHandler
เซิร์ฟเวอร์ HTTP นี้สร้างขึ้นบน Revolt event-loop และ Amp เฟรมเวิร์กการทำงานพร้อมกันที่ไม่บล็อก ดังนั้นมันจึงสืบทอดการสนับสนุนดั้งเดิมทั้งหมดอย่างเต็มที่ และเป็นไปได้ที่จะใช้ไลบรารีที่ไม่ปิดกั้นทั้งหมดที่สร้างจาก Revolt
หมายเหตุ โดยทั่วไป คุณควรทำความคุ้นเคยกับ แนวคิด
Future
ด้วย coroutines และระวังฟังก์ชันตัวรวมต่างๆ เพื่อให้สามารถใช้งานเซิร์ฟเวอร์ HTTP ได้สำเร็จ
ฟังก์ชันในตัวเกือบทั้งหมดของ PHP กำลังบล็อก I/O ซึ่งหมายความว่า เธรดที่กำลังดำเนินการ (ส่วนใหญ่เทียบเท่ากับกระบวนการในกรณีของ PHP) จะถูกหยุดอย่างมีประสิทธิภาพจนกว่าจะได้รับการตอบกลับ ตัวอย่างบางส่วนของฟังก์ชันดังกล่าว: mysqli_query
, file_get_contents
, usleep
และอื่นๆ อีกมากมาย
หลักการทั่วไปที่ดีคือ: ฟังก์ชัน PHP ในตัวทุกตัวที่ทำ I/O จะทำในลักษณะบล็อก เว้นแต่คุณจะรู้แน่ชัดว่าไม่ได้เป็นเช่นนั้น
มีไลบรารีที่จัดเตรียมการใช้งานที่ใช้ I/O ที่ไม่ปิดกั้น คุณควรใช้สิ่งเหล่านี้แทนฟังก์ชันในตัว
เราครอบคลุมความต้องการ I/O ที่พบบ่อยที่สุด เช่น ซ็อกเก็ตเครือข่าย การเข้าถึงไฟล์ คำขอ HTTP และเว็บซ็อกเก็ต ไคลเอนต์ฐานข้อมูล MySQL และ Postgres และ Redis หากจำเป็นต้องใช้การบล็อก I/O หรือการคำนวณแบบยาวในการตอบสนองคำขอ ให้พิจารณาใช้ไลบรารีแบบขนานเพื่อรันโค้ดนั้นในกระบวนการหรือเธรดที่แยกจากกัน
คำเตือน อย่าใช้ฟังก์ชัน I/O บล็อกใด ๆ ในเซิร์ฟเวอร์ HTTP
// 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
ไลบรารีนี้มี SocketHttpServer
ซึ่งจะเหมาะสำหรับแอปพลิเคชันส่วนใหญ่ สร้างขึ้นจากส่วนประกอบที่พบในไลบรารีนี้และใน amphp/socket
หากต้องการสร้างอินสแตนซ์ของ 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, 1,000 และ 1,000 ตามค่าเริ่มต้น ตามลำดับ) การบีบอัดการตอบสนองอาจเปิดหรือปิดได้ (เปิดโดยค่าเริ่มต้น) และวิธีการร้องขอจะถูกจำกัดไว้ที่ชุดกริยา HTTP ที่รู้จักตามค่าเริ่มต้นSocketHttpServer::createForBehindProxy()
: สร้างเซิร์ฟเวอร์ที่เหมาะสมสำหรับใช้เมื่ออยู่เบื้องหลังบริการพร็อกซี เช่น nginx ตัวสร้างแบบคงที่นี้ต้องการรายการ IP พร็อกซีที่เชื่อถือได้ (พร้อมซับเน็ตมาสก์เสริม) และกรณีแจงนับของ ForwardedHeaderType
(ตรงกับ Forwarded
หรือ X-Forwarded-For
) เพื่อแยกวิเคราะห์ IP ไคลเอ็นต์ดั้งเดิมจากส่วนหัวของคำขอ ไม่มีการจำกัดจำนวนการเชื่อมต่อกับเซิร์ฟเวอร์ อย่างไรก็ตาม จำนวนคำขอที่เกิดขึ้นพร้อมกันจะถูกจำกัด (1,000 โดยค่าเริ่มต้น ปรับได้หรือสามารถลบออกได้) การบีบอัดการตอบสนองอาจเปิดหรือปิดได้ (เปิดโดยค่าเริ่มต้น) วิธีการร้องขอจะถูกจำกัดไว้ที่ชุดกริยา HTTP ที่รู้จักตามค่าเริ่มต้น หากไม่มีวิธีใดที่ตอบสนองความต้องการของแอปพลิเคชันของคุณ ตัวสร้าง SocketHttpServer
อาจถูกนำมาใช้โดยตรง สิ่งนี้ให้ความยืดหยุ่นอย่างมากในการสร้างและจัดการการเชื่อมต่อไคลเอ็นต์การเชื่อมต่อขาเข้า แต่จะต้องใช้โค้ดเพิ่มเติมเพื่อสร้าง ตัวสร้างต้องการให้ผู้ใช้ส่งอินสแตนซ์ของ SocketServerFactory
ซึ่งใช้ในการสร้างอินสแตนซ์ของไคลเอ็นต์ Socket
(ทั้งสององค์ประกอบของไลบรารี amphp/socket
) และอินสแตนซ์ของ ClientFactory
ซึ่งสร้างอินสแตนซ์ของ Client
อย่างเหมาะสมซึ่งแนบไปกับแต่ละ Request
ที่ทำโดยไคลเอ็นต์ .
RequestHandler
คำขอที่เข้ามาจะแสดงด้วยออบเจ็กต์ Request
มีการจัดเตรียมคำขอให้กับผู้ดำเนินการของ RequestHandler
ซึ่งกำหนดเมธอด handleRequest()
ที่ส่งคืนอินสแตนซ์ของ Response
public function handleRequest( Request $ request ): Response
คำขอของลูกค้าแต่ละคำขอ (เช่น การเรียกไปที่ RequestHandler::handleRequest()
) จะถูกดำเนินการภายใน Coroutine ที่แยกจากกัน ดังนั้นคำขอจะได้รับการจัดการร่วมกันโดยอัตโนมัติภายในกระบวนการของเซิร์ฟเวอร์ เมื่อตัวจัดการคำขอรอ I/O ที่ไม่บล็อก คำขออื่นๆ ของไคลเอ็นต์จะถูกประมวลผลใน Coroutines ที่เกิดขึ้นพร้อมกัน ตัวจัดการคำขอของคุณอาจสร้าง Coroutines อื่น ๆ โดยใช้ Ampasync()
เพื่อดำเนินการหลาย ๆ งานสำหรับคำขอเดียว
โดยปกติแล้ว RequestHandler
จะสร้างการตอบสนองโดยตรง แต่ก็อาจมอบหมายให้กับ RequestHandler
อื่นด้วย ตัวอย่างสำหรับการมอบหมาย RequestHandler
ดังกล่าวคือ Router
อินเทอร์เฟซ RequestHandler
มีไว้เพื่อใช้งานโดยคลาสที่กำหนดเอง สำหรับกรณีการใช้งานที่เรียบง่ายหรือการเยาะเย้ยอย่างรวดเร็ว คุณสามารถใช้ CallableRequestHandler
ซึ่งสามารถล้อมสิ่ง callable
และยอมรับ Request
และส่งคืน Response
กลับ
มิดเดิลแวร์อนุญาตให้มีการประมวลผลคำขอล่วงหน้าและหลังการประมวลผลการตอบกลับ นอกจากนั้น มิดเดิลแวร์ยังสามารถสกัดกั้นการประมวลผลคำขอและส่งคืนการตอบกลับโดยไม่ต้องมอบหมายให้กับตัวจัดการคำขอที่ส่งผ่าน คลาสต้องใช้อินเทอ Middleware
เพื่อสิ่งนั้น
หมายเหตุ โดยทั่วไปมิดเดิลแวร์จะตามหลังคำอื่นๆ เช่น soft- และ hardware ที่เป็นพหูพจน์ อย่างไรก็ตาม เราใช้คำว่า มิดเดิลแวร์ เพื่ออ้างถึงออบเจ็กต์หลายรายการที่ใช้อิน
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
เซิร์ฟเวอร์ HTTP ใช้ ErrorHander
เมื่อได้รับคำขอที่มีรูปแบบไม่ถูกต้องหรือไม่ถูกต้อง ออบเจ็กต์ Request
จะถูกจัดเตรียมไว้หากมีการสร้างจากข้อมูลที่เข้ามา แต่อาจไม่ได้ตั้งค่าไว้เสมอไป
public function handleError(
int $ status ,
? string $ reason = null ,
? Request $ request = null ,
): Response
ไลบรารีนี้จัดเตรียม DefaultErrorHandler
ซึ่งส่งคืนเพจ HTML ที่มีสไตล์เป็นเนื้อหาการตอบสนอง คุณอาจต้องการจัดเตรียมการใช้งานที่แตกต่างกันสำหรับแอปพลิเคชันของคุณ ซึ่งอาจใช้ร่วมกับเราเตอร์ได้หลายรายการ
Request
เป็นเรื่องยากที่คุณจะต้องสร้างอ็อบเจ็กต์ Request
ด้วยตัวเอง เนื่องจากโดยปกติแล้วเซิร์ฟเวอร์จะมอบอ็อบเจกต์เหล่านั้นให้กับ RequestHandler::handleRequest()
/**
* @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
หากคุณทราบความยาวเนื้อหาที่แน่นอนของสตรีมของคุณ คุณสามารถเพิ่มส่วนหัวcontent-length
ได้หลังจาก เรียกsetBody()
/** @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
ที่จะใช้ในคำขอ
รายละเอียดที่เกี่ยวข้องกับไคลเอ็นต์จะรวมอยู่ในออบเจ็กต์ AmpHttpServerDriverClient
ที่ส่งคืนจาก Request::getClient()
อินเทอร์เฟซ 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 ,
)
เรียกใช้ตัวจัดการการกำจัด (เช่น ฟังก์ชันที่ลงทะเบียนผ่านเมธอด onDispose()
)
หมายเหตุ ข้อยกเว้นที่ไม่ถูกตรวจจับจากตัวจัดการการกำจัดจะถูกส่งต่อไปยังตัวจัดการข้อผิดพลาดของลูปเหตุการณ์
public function getBody(): Amp ByteStream ReadableStream
ส่งคืนสตรีมสำหรับเนื้อหาข้อความ
public function setBody( Amp ByteStream ReadableStream | string $ body )
ตั้งค่าสตรีมสำหรับเนื้อหาข้อความ
หมายเหตุ การใช้สตริงจะตั้งค่าส่วนหัว
Content-Length
เป็นความยาวของสตริงที่กำหนดโดยอัตโนมัติ การตั้งค่าReadableStream
จะลบส่วนหัวContent-Length
หากคุณทราบความยาวเนื้อหาที่แน่นอนของสตรีมของคุณ คุณสามารถเพิ่มส่วนหัวcontent-length
ได้หลังจาก เรียกsetBody()
/** @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
ส่งคืนรายการทรัพยากรพุชในแผนที่เชื่อมโยงของสตริง URL ไปยังวัตถุ Push
/** @param array<string>|array<string, array<string>> $headers */
public function push( string $ url , array $ headers ): void
ระบุทรัพยากรที่ลูกค้าน่าจะต้องการดึงข้อมูล (เช่น Link: preload
หรือ HTTP/2 Server Push)
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
ที่จะใช้ในการตอบกลับ ตัวอย่างจะถูกส่งไปเมื่อตั้งค่าเนื้อหาการตอบสนองทั้งหมดให้กับไคลเอนต์แล้ว
RequestBody
ซึ่งส่งคืนจาก Request::getBody()
ให้การเข้าถึงแบบบัฟเฟอร์และสตรีมไปยังเนื้อหาคำขอ ใช้การเข้าถึงแบบสตรีมเพื่อจัดการกับข้อความขนาดใหญ่ ซึ่งมีความสำคัญอย่างยิ่งหากคุณมีขีดจำกัดข้อความที่ใหญ่กว่า (เช่น สิบเมกะไบต์) และไม่ต้องการบัฟเฟอร์ข้อความทั้งหมดไว้ในหน่วยความจำ หากมีคนอัปโหลดเนื้อหาขนาดใหญ่พร้อมกันหลายคน หน่วยความจำอาจหมดอย่างรวดเร็ว
ดังนั้นการจัดการที่เพิ่มขึ้นจึงมีความสำคัญ โดยสามารถเข้าถึงได้ผ่าน read()
API ของ AmpByteStreamReadableStream
ในกรณีที่ไคลเอนต์ยกเลิกการเชื่อมต่อ read()
จะล้มเหลวด้วย AmpHttpServerClientException
ข้อยกเว้นนี้เกิดขึ้นสำหรับทั้ง read()
และ buffer()
API
หมายเหตุ
ClientException
ไม่ จำเป็น ต้องถูกจับ คุณอาจจับได้ถ้าคุณต้องการดำเนินการต่อ แต่ไม่จำเป็นต้องทำ เซิร์ฟเวอร์จะยุติวงจรคำขออย่างเงียบๆ และละทิ้งข้อยกเว้นนั้นไป
แทนที่จะตั้งค่าขีดจำกัดเนื้อหาทั่วไปให้สูง คุณควรพิจารณาเพิ่มขีดจำกัดเนื้อหาเฉพาะเมื่อจำเป็นเท่านั้น ซึ่งเป็นไปได้แบบไดนามิกโดยใช้เมธอด increaseSizeLimit()
บน RequestBody
หมายเหตุ
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
อนุญาตให้เข้าถึงตัวอย่างคำขอ HTTP ซึ่งสามารถเข้าถึงได้ผ่าน Request::getTrailers()
คืนค่า null
หากไม่คาดว่าจะมีตัวอย่างตามคำขอ Trailers::await()
ส่งคืน Future
ซึ่งได้รับการแก้ไขด้วยวัตถุ HttpMessage
ที่ให้วิธีการเข้าถึงส่วนหัวของตัวอย่าง
$ trailers = $ request -> getTrailers ();
$ message = $ trailers ?->await();
เซิร์ฟเวอร์ HTTP จะไม่เป็นคอขวด การกำหนดค่าไม่ถูกต้อง การใช้การบล็อก I/O หรือแอปพลิเคชันที่ไม่มีประสิทธิภาพ
เซิร์ฟเวอร์ได้รับการปรับให้เหมาะสมอย่างเหมาะสมและสามารถรองรับคำขอนับหมื่นครั้งต่อวินาทีบนฮาร์ดแวร์ทั่วไป ขณะเดียวกันก็รักษาระดับการทำงานพร้อมกันของไคลเอ็นต์นับพันรายการในระดับสูง
แต่ประสิทธิภาพนั้นจะลดลงอย่างมากเมื่อมีการใช้งานที่ไม่มีประสิทธิภาพ เซิร์ฟเวอร์มีข้อได้เปรียบที่ดีเนื่องจากมีการโหลดคลาสและตัวจัดการอยู่เสมอ ดังนั้นจึงไม่ต้องเสียเวลาไปกับการคอมไพล์และการเริ่มต้น
กับดักที่พบบ่อยคือการเริ่มดำเนินการกับข้อมูลขนาดใหญ่ด้วยการดำเนินการสตริงแบบง่ายๆ ซึ่งต้องใช้สำเนาขนาดใหญ่ที่ไม่มีประสิทธิภาพจำนวนมาก ควรใช้การสตรีมแทนหากเป็นไปได้สำหรับเนื้อหาคำขอและการตอบกลับที่ใหญ่ขึ้น
ปัญหาจริงๆคือต้นทุน CPU การจัดการ I/O ที่ไม่มีประสิทธิภาพ (ตราบใดที่ไม่มีการปิดกั้น!) เป็นเพียงการชะลอคำขอแต่ละรายการ ขอแนะนำให้จัดส่งพร้อมกันและรวมกลุ่มคำขอ I/O อิสระหลายรายการในท้ายที่สุดผ่านตัวรวมของ Amp แต่ตัวจัดการที่ช้าจะทำให้คำขออื่นๆ ทั้งหมดช้าลงเช่นกัน ขณะที่ตัวจัดการตัวหนึ่งกำลังประมวลผล ตัวจัดการอื่นๆ ทั้งหมดจะไม่สามารถดำเนินการต่อได้ ดังนั้นจึงจำเป็นต้องลดเวลาการคำนวณของตัวจัดการให้เหลือน้อยที่สุด
สามารถพบได้หลายตัวอย่างในไดเร็กทอรี ./examples
ของที่เก็บ สิ่งเหล่านี้สามารถดำเนินการได้เหมือนสคริปต์ PHP ปกติบนบรรทัดคำสั่ง
php examples/hello-world.php
จากนั้นคุณสามารถเข้าถึงเซิร์ฟเวอร์ตัวอย่างได้ที่ http://localhost:1337/
ในเบราว์เซอร์ของคุณ
หากคุณพบปัญหาที่เกี่ยวข้องกับความปลอดภัย โปรดใช้เครื่องมือรายงานปัญหาด้านความปลอดภัยส่วนตัวแทนการใช้ตัวติดตามปัญหาสาธารณะ
ใบอนุญาตเอ็มไอที (MIT) โปรดดูใบอนุญาตสำหรับข้อมูลเพิ่มเติม