Skip to main content

PSR-7 Style with Functional Routing

You can use PSR-7 compatible request and response objects with functional routing for a more testable, object-oriented approach.

ServerRequest

The ServerRequest class wraps the current HTTP request:

use PhpCompatible\Router\ServerRequest;

router(function() {
route(method(GET), url_path_params('/users/:id'), function() {
$request = new ServerRequest();

$id = $request->getRouteParam(':id');
$filter = $request->getQueryParam('filter', 'all');

echo json_response(HTTP_OK, array(
'user_id' => $id,
'filter' => $filter
));
});
});

Request Methods

$request = new ServerRequest();

// Route parameters (from :param placeholders)
$id = $request->getRouteParam(':id');
$params = $request->getAttributes();

// Query parameters (?key=value)
$page = $request->getQueryParam('page', 1);
$all = $request->getQueryParams();

// Request body (JSON)
$data = $request->getParsedBody();
$name = $request->getBodyParam('name');

// Headers
$auth = $request->getHeaderLine('Authorization');
$hasAuth = $request->hasHeader('Authorization');

// Request info
$method = $request->getMethod();
$uri = $request->getUri();
$isPost = $request->isMethod('POST');
$isAjax = $request->isAjax();
$isJson = $request->isJson();

JsonResponse

Return structured JSON responses:

use PhpCompatible\Router\JsonResponse;

router(function() {
route(method(GET), url_path('/api/users'), function() {
$users = get_all_users();
$response = JsonResponse::response(HTTP_OK, array('users' => $users));
$response->send();
});

route(method(POST), url_path('/api/users'), function() {
$request = new ServerRequest();
$data = $request->getParsedBody();

if (empty($data['name'])) {
$response = JsonResponse::response(HTTP_BAD_REQUEST, array('error' => 'Name required'));
$response->send();
stop();
}

$user = create_user($data);
$response = JsonResponse::response(HTTP_CREATED, array('user' => $user));
$response->send();
});
});

Common Status Codes

JsonResponse::response(HTTP_OK, $data);                    // 200
JsonResponse::response(HTTP_CREATED, $data); // 201
JsonResponse::response(HTTP_NO_CONTENT); // 204
JsonResponse::response(HTTP_BAD_REQUEST, $data); // 400
JsonResponse::response(HTTP_UNAUTHORIZED, $data); // 401
JsonResponse::response(HTTP_FORBIDDEN, $data); // 403
JsonResponse::response(HTTP_NOT_FOUND, $data); // 404
JsonResponse::response(HTTP_INTERNAL_SERVER_ERROR, $data); // 500

HtmlResponse

Return HTML with proper headers:

use PhpCompatible\Router\HtmlResponse;

router(function() {
route(method(GET), url_path('/'), function() {
$response = HtmlResponse::response(HTTP_OK, '<h1>Welcome</h1>');
$response->send();
});

route(method(GET), url_path_params('/users/:id'), function() {
$request = new ServerRequest();
$id = $request->getRouteParam(':id');
$user = get_user($id);

$html = render_template('user.php', array('user' => $user));
$response = HtmlResponse::response(HTTP_OK, $html);
$response->send();
});
});
Templates

For a blazing fast PHP templating solution, see php-compatible/templates.

Single Action Controllers

Use invokable classes with functional routing:

use PhpCompatible\Router\ServerRequest;
use PhpCompatible\Router\JsonResponse;

class ShowUser
{
public function __invoke(ServerRequest $request)
{
$id = $request->getRouteParam(':id');
$user = $this->findUser($id);

if (!$user) {
return JsonResponse::response(HTTP_NOT_FOUND, array('error' => 'User not found'));
}

return JsonResponse::response(HTTP_OK, array('user' => $user));
}

private function findUser($id)
{
// Database lookup
return array('id' => $id, 'name' => 'Alice');
}
}

router(function() {
route(method(GET), url_path_params('/users/:id'), ShowUser::class);
});

Mixing Styles

You can mix PSR-7 style with traditional functions:

router(function() {
// PSR-7 style
route(method(GET), url_path('/api/users'), function() {
$request = new ServerRequest();
$page = $request->getQueryParam('page', 1);
$response = JsonResponse::response(HTTP_OK, array('users' => array(), 'page' => $page));
$response->send();
});

// Traditional style
route(method(GET), url_path('/legacy'), function() {
echo json_response(HTTP_OK, array('legacy' => true));
});
});