PHP Slim4の解読、レスポンス編

Responseの基本

Slimのリクエストやレスポンスの読み書きはストリームにより行われているようです。
リクエストであれば「php://input」や「php://temp」、レスポンスは「php://temp」へのストリームです。
Streamについては後で説明します。

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Factory\AppFactory;
use Slim\Psr7\Stream;

$app = AppFactory::create();
$app->setBasePath('/slim-public');

$app->addRoutingMiddleware();
$app->addErrorMiddleware(true, true, true);

$app->get('/', function(Request $request, Response $response, array $args){

    // getBodyはStreamオブジェクトを返します。
    // $fp = fopen('php://temp', 'rw+');
    $body = $response->getBody();

    // fwrite($fp, 'Hello World')
    $body->write('Hello World');

    // stream_get_meta_data($fp)
    $metas = $body->getMetadata();

    return $response;
});

$app->run();

$body->write()はストリームをfwrite()してますし、
$body->getMetadata()stream_get_meta_data()でストリームからメタデータをとってます。

Responseからテキストを取得するgetContent()が効かない

通常は$app->get()のコールバックでレスポンスを取得しますが、今回はAppから作成して使います。

use Slim\Factory\AppFactory;

$app = AppFactory::create();

// レスポンスを作成
$response = $app->getResponseFactory()->createResponse();

$response->getBody()->write('Hello World');
$contents = $response->getBody()->getContents();

echo "Content = $contents";

結果

Content =

予想と違いHello Worldは表示されません。
rewind()を使ってファイルポインタを先頭に戻します。

use Slim\Factory\AppFactory;

$app = AppFactory::create();

$response = $app->getResponseFactory()->createResponse();
$response->getBody()->write('Hello World');

// getContents()を呼ぶ前にrewind()でファイルポインタを先頭に戻す
$response->getBody()->rewind();
$contents = $response->getBody()->getContents();

echo "Content = $contents";

結果

Content = Hello World

Responseのrewind()とseek()

操作はファイル操作を知ってれば大体あつかえるはずです。

use Slim\Factory\AppFactory;

$app = AppFactory::create();
$response = $app->getResponseFactory()->createResponse();
$response->getBody()->write('Hello World');
$response->getBody()->seek(6); // ファイルポインタを6に持っていく
$response->getBody()->write('XXX'); // XXXを書き込む
$response->getBody()->rewind(); // ファイルポインタを先頭に戻す
$contents = $response->getBody()->getContents();

echo "Content = $contents";

結果

Content = Hello XXXld

Responseを標準出力に出力する

Appのrun()メソッドではレスポンスを出力するために内部でResponseEmitterが使われてます。

use Slim\Factory\AppFactory;
use Slim\ResponseEmitter;

$app = AppFactory::create();

$response = $app->getResponseFactory()->createResponse();
$response->getBody()->write('Hello World');

$responseEmitter = new ResponseEmitter();
$responseEmitter->emit($response); // レスポンスを出力

Streamクラス

レスポンスのgetBody()から得られるのはSlim\Psr7\Stream型のインスタンスです。
StreamはコンストラクタでPHPのストリームを受け取ります。

use Slim\Psr7\Stream;

$fp = fopen('php://temp', 'rw+');
$stream = new Stream($fp);

$stream->write('Hello Stream');
$stream->rewind();

echo $stream->getContents();

結果

Hello Stream

certificate Docker Gutenberg Hyper-V openssl PHP React ReduxToolkit REST ubuntu WordPress オレオレ認証局 フレームワーク