PSR-7 Standard – Part 4 – File Uploads
This post is part of series:
- Part 1: Overview
- Part 2: Request and URI
- Part 3: Response
- Part 4: File Uploads
- Part 5: HTTP-Client
- Part 6: Server Request
- Part 7: Middleware
- Part 8: Usage in a Magento module
After we learned what a Request and a Response are, let’s now look how we can send files to the server. Then have a look on how we can process them with Guzzle on the server side.
Client Side Script
As you can see in the diagram, a file upload is also handled as stream.
First we create script “file_upload.php” with this content which initializes the autoloader and creates a sample file for the upload test.
<?php require_once 'vendor/autoload.php'; // create a test file file_put_contents('foo.txt', '"Foo" is the content of the file');
After we have a text file, we can create our stream with the Guzzle PSR-7 component. Please add the code to the existing file.
// put test file into multipart stream
$multipart = new \GuzzleHttp\Psr7\MultipartStream([
[
'name' => 'upload_file',
'contents' => fopen('foo.txt', 'r')
],
]);
The MultipartStream
gives us the ability to send more than once file to the server. As last part of the script we need to create a Request to send the MultipartStream
to the server.
$request = new \GuzzleHttp\Psr7\Request('POST', 'http://127.0.0.1:8080');
$request = $request->withBody($multipart);
$client = new \GuzzleHttp\Client();
$response = $client->send($request);
echo $response->getBody();
Server Side Script
Please create the script “server_file.php” to receive the files.
<?php
require_once __DIR__ . '/vendor/autoload.php';
$request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals();
$files = $request->getUploadedFiles();
$response = new \GuzzleHttp\Psr7\Response();
$response = $response->withStatus(200, 'OK');
$uploadedFiles = $request->getUploadedFiles();
$uploadedFileInfos = [];
foreach ($uploadedFiles as $uploadedFile) {
/** @var $uploadedFile \GuzzleHttp\Psr7\UploadedFile */
$uploadedFileInfos[] = [
'file_name' => $uploadedFile->getClientFilename(),
'mime_type' => $uploadedFile->getClientMediaType(),
'size' => $uploadedFile->getSize(),
'content' => (string) $uploadedFile->getStream()
];
}
$response = $response->withBody(
\GuzzleHttp\Psr7\stream_for(print_r($uploadedFileInfos))
);
echo \GuzzleHttp\Psr7\str($response);
The script is very simple. It creates a ServerRequest
(we talk about this in a future blog post). The ServerRequest
can handle the MultipartStream
and return the files with the handy method method getUploadedFiles
. This methods is now a standard to get all data of the uploaded files. If you know how files are handled without PSR-7 you know that this is a really enhancement.
For debugging we collect all data of the uploaded files and return them back as response to the client.
Test the Upload
Run the server in console:
php -S 127.0.0.1:8080 server_file.php
Run the client script in a second console:
php file_upload.php
If you did everything correct you should now see the result of the server script:
HTTP/1.1 200 OK Array ( [0] => Array ( [file_name] => foo.txt [mime_type] => text/plain [size] => 32 [content] => "Foo" is the content of the file ) )
That’s it. The next blog post will give you some inside into the HTTP Client.
– Creator of n98-magerun
– Fan of football club @wormatia
– Magento user since version 0.8 beta
– 8x certified Magento developer
– PHP Top 1.000 developer (yes, I’m PHP4 certified and sooooo old)
– Chief development officer at netz98