Jump to content

Making Slim generate 404 response in application


Go to solution Solved by kicken,

Recommended Posts

The following script supports the following paths, and any other path will return a 404 response:

  • /source/type1/subtype1
  • /source/type1/subtype2
  • /source/type2/subtype1
  • /source/type2/subtype2
<?php

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require __DIR__.'/../vendor/autoload.php';

$c = new \Slim\Container($settings);
$c['SourceFactory'] = function ($c) {
    return new \RestApp\SourceFactory();
};
$c['notFoundHandler'] = function ($c) {
    return function ($request, $response) use ($c) {
        return $c['response']
        ->withStatus(404)
        ->withHeader('Content-Type', 'text/html')
        ->write('Page not found');
    };
};
$app = new \Slim\App($c);

$app->post('/sources/{type: type1|type2}/{subtype: subtype1|subtype2}', function (Request $request, Response $response, $args) {
    $rs=$this->get('SourceFactory')->getByType($args['type'],$args['subtype'])->add($request->getParsedBody());
    return $response->withJson($rs[0],$rs[1]);
});

$app->run();

Instead of putting the logic in the slim path definitions (i.e. /sources/{type: type1|type2}/{subtype: subtype1|subtype2}), I would like to put the logic in the getByType() method, and have my slim path simply be /sources/{type}/{subtype}.  To do so, I envision getByType() returning something like the following if  type  and subtype are not what they should be. 

<?php
namespace RestApp;
class MissingPage
{
    public function __call($method, $args) {
        echo "This page is missing";
    }    
}

Okay, this should work.  But I don't want it to just return This page is missing, but return the same content and headers should a path not have been supported such as /invalidPath/foo/bar.

 

Hope what I am asking makes sense :)

 

Any recommendations?

 

Thanks

 

Maybe easier than I thought.   I "think" the header defaults to text/html, and if not, expect there is a way to make it.  Not sure that this is the "Slim" way of doing it, but it should work fine.

<?php
namespace RestApp;
class MissingPage
{
    public function __call($method, $args) {
        return ['Page not found',404];
    }    
}
  • Solution

Use an exception and the error handler to return an appropriate error page.

 

$c['errorHandler'] = function($c){
	return function ($request, $response, $exception) use ($c){
		if ($exception instanceof NotFoundException){
			return $c['notFoundHandler']($request, $response);
		} else {
			return $c['response']->withStatus(500)
				->withHeader('Content-type: text/html')
				->write('Generic error')
			;
		}
	};
};
class SourceFactory {
	public function getByType($type, $subtype){
		throw new NotFoundException();
	}
}
 

class NotFoundException extends Exception {}
Whenever you want to trigger a not found error you'd just throw the exception. That will stop the current code path and jump to the error handler. The error handler will detect that it's a not found exception and call the not found handler to generate the response.

 

You could do the same with other http error conditions if you wanted, like authentication required, forbidden, etc. Symfony does something like this in their framework. They define a HTTPExceptionInterface adding methods to get the status code and extra headers. Then they have various implementations like NotFoundHttpException.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.