Làm cách nào để đặt dữ liệu biểu mẫu nhiều phần trong PHP?

Mặc dù chúng tôi triển khai PSR-18 bằng cách sử dụng Guzzle - thông qua HttPlug - tôi không muốn sử dụng các lớp cụ thể của Guzzle trong cơ sở mã của mình, vì điều đó có thể ngăn chúng tôi di chuyển suôn sẻ sang một bản tóm tắt HTTP khác. Và nó không tương thích với PSR-18

Gửi yêu cầu đăng bài

Có hai phương thức gửi dữ liệu với yêu cầu POST; . Đầu tiên là bản dịch cấu trúc GET sang phần thân POST

POST /a/post/url HTTP/1.1
Host: www.domain.ext
Content-Type: application/x-www-form-urlencoded

field=value&another+field=another+value

Phần thân này có thể đạt được thông qua PHP's


    
    

3

$body = http_build_query[
    ['field' => 'value', 'another field' => 'another value'], 
    '', 
    '&', 
    PHP_QUERY_RFC1738
];

Nhưng sử dụng phương pháp tạo yêu cầu POST này không cho phép gửi tệp đính kèm. Đối với những tình huống đó, bạn sẽ cần dùng đến multipart/form-data

nhiều phần/biểu mẫu dữ liệu

Tệp đính kèm không chỉ là dữ liệu [nhị phân] của tệp, nó là tên tệp, loại nội dung và thông tin meta có thể khác. Vì điều này cần một số hình thức cấu trúc, loại nội dung multipart/form-data đã được giới thiệu trong


    
    

6

Thực tế, những gì đoạn mã trên làm là tạo một yêu cầu giống như thế này

POST /a/post/url HTTP/1.1
Host: www.domain.ext
Content-Type: multipart/format-data; boundary="a.random.boundary"

--a.random.boundary
Content-Disposition: form-data; name="name"
Content-Length: 4

name
--a.random.boundary
Content-Disposition: form-data; name="file"; filename="screenshot.png"
Content-Type: image.png

{$screenshotData}
--a.random.boundary--

Và mặc dù điều này có thể thực hiện được khi sử dụng giao diện PSR-18 và PSR-15, nhưng nó yêu cầu một số kiến ​​thức về cách thức hoạt động của phần này trong thông số kỹ thuật HTTP

$boundary = 'a.random.boundary';
$request = [new RequestFactory[]]
    ->createRequest['POST', '//www.domain.ext/a/post/url']
    ->withHeader['Content-Type', "multipart/form-data; boundary=\"{$boundary}\""]
    ->withBody[[new StreamFactory[]]->createStream["--{$boundary}" . "\r\n".
"Content-Disposition: form-data; name=\"name\"" . "\r\n" .
"\r\n" . 
"{$name}" . "\r\n" . 
"--{$boundary}" . "\r\n" .    
"Content-Disposition: form-data; name=\"file\"; filename=\"screenshot.php\"" . "\r\n" .
"Content-Type: image/png" . "\r\n" .
"\r\n" . 
"{$screenShotData}" . "\r\n" .
"--{$boundary}--"]];

$this->httpClient->sendRequest[$request];

Đây là rất nhiều công việc và nó có một vài cạm bẫy; . Nhưng khi tôi cố gắng gửi tệp tới JIRA, tôi nhận được thông báo lỗi là


    
    

7. Sau khi gỡ lỗi khá nhiều, tôi nhận thấy rằng JIRA [hoặc Java] yêu cầu

    
    

8 làm ký tự dòng mới

Bây giờ tôi có thể tạo một thư viện đẹp cho, nhưng tôi hơi lười, vì vậy tôi thường chuyển sang Packagist trước để xem có ai đã làm việc này chưa. Khi tìm kiếm Packagist cho các gói để xử lý tất cả những điều này cho tôi, bạn sẽ tìm thấy một số gói, nhưng các gói nổi bật là lượt tải xuống và các ngôi sao khôn ngoan.


    
    

9

Trình tạo luồng nhiều phần

Trình tạo luồng nhiều phần là một gói được tạo bởi nhóm cũng chịu trách nhiệm về HttPlug. Nó - như tên cho thấy - thực sự có nghĩa là xây dựng các luồng nhiều phần

Trình tạo cho Luồng PSR-7 nhiều phần. Trình tạo tạo các luồng độc lập từ bất kỳ triển khai PSR-7 nào

Để tạo yêu cầu tuân thủ PSR-7 với nội dung nhiều phần, chúng tôi cần tạo một phiên bản của trình tạo luồng nhiều phần

use Http\Message\MultipartStream\MultipartStreamBuilder;

$builder = new MultipartStreamBuilder[$streamFactory];
$builder->addResource[
    'file', 
    fopen['/path/to/uploaded/file', 'r'], 
    [
        'filename' => 'filename.ext', 
        'headers' => ['Content-Type' => 'application/octet-stream']
    ]
];

$request = $requestFactory
    ->createRequest['POST', '//...']
    ->withHeader['Content-Type', 'multipart/form-data; boundary="' . $builder->getBoundary[] . '"']
    ->withBody[$builder->build[]];

$response = $client->sendRequest[$request];    

Điều thú vị về thư viện này là nó trả về một thể hiện của

POST /a/post/url HTTP/1.1
Host: www.domain.ext
Content-Type: application/x-www-form-urlencoded

field=value&another+field=another+value
0. Ngẫu nhiên cùng một loại đối tượng
POST /a/post/url HTTP/1.1
Host: www.domain.ext
Content-Type: application/x-www-form-urlencoded

field=value&another+field=another+value
1 mong đợi

Nhược điểm của thư viện này là trình tạo luồng không phải là bất biến. Việc đưa nó vào ứng dụng của bạn có thể hơi phức tạp vì bộ chứa DI của bạn sẽ trả về một phiên bản mới của trình tạo luồng mỗi khi nó được đưa vào. Bên cạnh đó, tôi thích tiêm dựa trên giao diện, đó là sở thích cá nhân. Một cách giải quyết nhỏ cho vấn đề này có thể dễ dàng tạo ra thông qua một nhà máy

Chủ Đề