0

私はスリムフレームワークでこの問題を抱えています。render メソッドを持つクラス Template があり、ルート ハンドラによって返された場合、Slim がこのクラスのオブジェクトをレンダリングするようにしたい

$app->get('/test', function() {
    return new Template('main', function() use ($error) {
        return array(
            'content' => "Hello"
        );
    });
});

子クラスを作成しました(System.phpで)

class System extends Slim {
   function __constructor() {
       Slim::__construct();
   }
   private function auto_render_fun($callable) {
        $app = $this;
        return function() use ($callable, $app) {
            $args = func_get_args();
            $ret = call_user_func_array($callable, $args);
            if ($ret instanceof Template) {
                //render Template - Slim ignore return value
                $app->response()->body($ret->render());
            }
        };
    }
    protected function mapRoute($args) {
        $last = count($args)-1;
        $args[$last] = $this->auto_render_fun($args[$last]);
        return Slim::mapRoute($args);
    }
}

notFoundで同じことをしたかった

$app->notFound(function () use ($app) {
    $response = $app->response();
    $response['Content-Type'] = 'text/html';
    return new Template('main', function() {
        return array('content' => new Template('error_404', null));
    });
});

そのため、notFound 関数を上書きして Closure をラップし、その戻り値をレンダリングしました

最初に、より小さなコードを使用しようとします

public function notFound($callable = null) {
    if (!is_null(($callable))) {
        $this->router->notFound($this->auto_render_fun($callable));
    } else {
        Slim::notFound();
    }
}

私もこれを試します(古いコードをコピーして変更します)。

public function notFound($callable = null) {
    if ( !is_null($callable) ) {
        $this->router->notFound($this->auto_render_fun($callable));
        //            $this->router->notFound($callable);    // old line
    } else {
        ob_start();
        $customNotFoundHandler = $this->router->notFound();
        if ( is_callable($customNotFoundHandler) ) {
            call_user_func($customNotFoundHandler);
        } else {
            call_user_func(array($this, 'defaultNotFound'));
        }
        $this->halt(404, ob_get_clean());
    }
}

しかし、それが機能しなかった理由は、ここでスリムによってキャッシュされていると思われるのは、 https://github.com/codeguy/Slim/blob/master/Slim/Slim.php#Slim_Exception_Stopを呼び出すコードの行であるためです。 $this->notFound(); L1160 try..catch の中にあります。

これがスタック トレースです (notFound 関数内にキャッシュしましたが、Slim クラスで処理する必要があります)。

Slim_Exception_Stop in file libs/Slim/Slim/Slim.php at 862
0: Slim->stop() in libs/Slim/Slim/Slim.php at 882
1: Slim->halt(integer, string) in libs/System.php at 187
2: System->notFound() in libs/Slim/Slim/Slim.php at 1161
3: Slim->call() in libs/Slim/Slim/Middleware/Flash.php at 84
4: Slim_Middleware_Flash->call() in libs/Slim/Slim/Middleware/MethodOverride.php at 91
5: Slim_Middleware_MethodOverride->call() in libs/Slim/Slim/Middleware/PrettyExceptions.php at 65
6: Slim_Middleware_PrettyExceptions->call() in libs/Slim/Slim/Middleware/PrettyExceptions.php at 65
7: Slim_Middleware_PrettyExceptions->call() in libs/Slim/Slim/Slim.php at 1098
8: Slim->run() in index.php at 573
4

1 に答える 1

0

わかりました、理由が見つかりました。例外は適切に処理されましたが、コンテンツがありませんでした。私はそれがクラスに関するものだと誤って思い込んでいますが、単純に Slim コードにはバグがあります。

public function halt( $status, $message = '' ) {
    $this->cleanBuffer();
    $this->response->status($status);
    $this->response->body($message);
    $this->stop();
}

関数は、このようにハンドラーで使用するデータを上書きします

$app->notFound(function() {
   $app->response()->body('Error');
});

機能しません。見つからない関数は次のようになります

public function notFound($callable = null) {
    if (!is_null(($callable))) {
        $this->router->notFound($this->auto_render_fun($callable));
    } else {
        $customNotFoundHandler = $this->router->notFound();
        if (is_callable($customNotFoundHandler)) {
            call_user_func($customNotFoundHandler);
        } else {
            call_user_func(array($this, 'defaultNotFound'));
        }
        $this->response->status(404);
        $this->stop();
    }
}
于 2012-08-24T21:19:45.870 に答える