Usually when you’re offering output in XML/JSON format, it’s an API and so the information you want to send the user is structured.
If so, then rka-content-type-renderer may help you as it will render an array into either JSON, XML or HTML based on the Accept
Header.
This is a simple Slim route that uses it:
$app->get("/users", function ($request, $response, $args) {
$data = [
'items' => [
[
'name' => 'Alex',
'is_admin' => true,
],
[
'name' => 'Robin',
'is_admin' => false,
],
],
];
$renderer = new RKA\ContentTypeRenderer\Renderer();
$response = $renderer->render($request, $response, $data);
return $response;
});
To get XML output, the user simply requests XML via the HTTP Accept
header:
$ curl -H "Accept: application/xml" http:/localhost:8888/users
<?xml version="1.0"?>
<root>
<items>
<name>Alex</name>
<is_admin>1</is_admin>
</items>
<items>
<name>Robin</name>
<is_admin>0</is_admin>
</items>
</root>
To get JSON:
$ curl -H "Accept: application/json" http:/localhost:8888/users
{
"items": [
{
"name": "Alex",
"is_admin": true
},
{
"name": "Robin",
"is_admin": false
}
]
}
Now, if you wanted to allow uses to set the format via the URL rather than the Accept header, I would use a format
query parameter, so that the URL looks like http:/localhost:8888/users?format=xml
.
To do this, write some middleware:
// middleware that converts ?format=xxx to an Accept header
$app->add(function ($request, $response, $next) {
$format = $request->getParam('format');
if ($format) {
$mapping = [
'html' => 'text/html',
'xml' => 'application/xml',
'json' => 'application/json',
];
if (isset($mapping[$format])) {
$request = $request->withHeader('Accept', $mapping[$format]);
}
}
return $next($request, $response, $next);
});
and now http:/localhost:8888/users?format=xml
will render XML.