klein/klein.php

klein executes onHttpError function everytime with 404 code

Opened this issue ยท 8 comments

from the documentations I'm using this function

$klein->onHttpError(function ($code, $router,$matched,$method_matched,$http_exception) {
switch ($code) {
    case 404:
         $router->response()->body(
            '404 Page'
        );
        break;
    case 405:
        $router->response()->body(
            'You can\'t do that!'
        );
        break;
    default:
        $router->response()->body(
            'Oh no, a bad error happened that caused a '. $code
        );
 }
});

But even if there is no exception, this function is rendering and printing 404 page in the end of every page. Am I doing something wrong? I tried checking $matched but no luck.

And I want to use $service->render() in error handling, How can I do that? Because service is not accessible in particular onHttpError function.

I don't get 404 on every page, maybe you have a broken require, however, your second point affects me as per: -

I would like to use onHttpError instead of the old respond 404 method but yes have the same problem about getting access to $service->render() so my 404 does not throw the person to an empty page without the layout.

I can make it work the old way with
$klein->respond('404', function ($request, $response, $service) {

but I get this

Deprecated: Use of 404/405 "routes" is deprecated. Use $klein->onHttpError() instead.

While I can't help with the 404 you keep getting as the code you provided works fine, you can however, access the ServiceProvider object using this code:

$klein->onHttpError(function ($code, $router) {
    $service = $router->service();
});

@nbish11 - thanks heaps Nathan, following example now works like a charm, time to fix my other sites using klein. :-) ๐Ÿ‘

# 404 Not Found
$klein->onHttpError(function ($code, $router) {
    if ($code == 404) {
        $service = $router->service();
        $request = $router->request();

        header("HTTP/1.0 404 Not Found");
        $service->pagerequested = $request->uri();
        $service->render(INCLUDE_FOLDER.'master.php',
            array(
                'title' => '404 Not Found',
                'content' => '404.php',
                'active_menu' => '',
                'url' => '404',
                'description' => 'Page not found',
                'created' => '2015-08-13',
                'modified' => '2015-08-13T12:00:00+11:00'
            ));
    }
});

Sorry @LaziestDev no idea about your bottom page 404, have you turned on PHP error handling ie.

ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);

@PeterSawyer Glad to be of help.

Thanks @nbish11 & @PeterSawyer for your help. I figured out the first issue, it was because of skipRemaining() method which was sending 404 error code to onHttpError(). Then I explored the existing issues and I found #285 which solved my first issue. And 2nd I figured out today only, But really thanks. My current 404 case section is

case 404:
    $service = $router->service();
    $service->title = "404 Page";
    $service->render('public/404.php');
break;

Thanks for sharing. I was wondering how to inject into my routers and $router->service() was the answer.

$service = $router->service();
$service->mod_myClass = new myClass();

Then you just access it from within the closed functions:

function ($request, $response, $service, $app ) {
    return $service->mod_myClass('do_something');
}

Does anybody know if this causes a major performance hit? Also, what is the point of $app? I've not gotten that far in the documentation.

$app is a brilliant way of storing "services". These are usually objects that are instantiated only once per request/response cycle (like a singleton, but not). Example:

$klein = new Klein\Klein;

// respond to all requests
$klein->respond(function ($request, $response, $service, $app) {
    $app->register('db', function () {
        $dbh = new PDO('mysql:host=localhost;dbname=testdb', 'root', '');
        return $dbh;
    });
});

// now later on
$klein->respond('GET', '/posts', function ($request, $response, $service, $app) {
    // $db has already been initialized above
    // all subsequent calls will use the same instance
    return $app->db->name;
});

As for performance, I'm not too sure.

@nbish11 nice one.