【问题标题】:How to serve static files using Klein.php如何使用 Klein.php 提供静态文件
【发布时间】:2026-02-01 07:35:01
【问题描述】:

我正在尝试使用 Klein.php 提供位于 /web 目录中的静态文件,如下所示:

$klein->respond('/web/[*]', function($request, $response, $service, $app) {
    return $service->file(__DIR__ . $request->pathname());
});

但是在终端收到这个错误

[Sat Jun 14 18:14:25 2014] PHP Fatal error: 
 Call to undefined method Klein\ServiceProvider::file()
 in /home/youssef/Desktop/gestion-stages/front_controller.php on line 50

【问题讨论】:

    标签: php routing klein-mvc


    【解决方案1】:

    试试这个:

    $klein->respond('/web/[*]', function($request, $response, $service, $app) {
        return $response->file(__DIR__ . $request->pathname());
    });
    

    看起来 file() 是 Response 的方法,而不是 ServiceProvider:

    https://github.com/chriso/klein.php/blob/737e7268f5c3fdc6d6f1371cb2ee0264892e8540/src/Klein/Response.php#L85

    Klein 是一个很棒的小框架,但我确实发现我有时必须深入挖掘源代码。从好的方面来说,源代码有很好的 cmets 和干净的代码。阅读这类项目会让你成为更好的程序员。

    如果您遇到任何问题,主要开发人员通常会很好地响应 GitHub 上的问题:https://github.com/chriso/klein.php/issues?state=open

    另一种选择

    我应该注意的最后一件事。如果这是您真正想要做的,而不是一个简化的示例,那么您可以使用 Apache mod_rewrite 或 Nginx 中的等价物来完成相同的事情,并且具有更好的性能,因为您没有执行任何 PHP那时的代码。另一方面,如果你想做一些更高级的事情,比如在决定是否提供文件之前检查用户的登录凭据,或者在你的文档根目录之外提供文件,你这样做的方式可能是正确的。

    我不太擅长编写 mod_rewrite 规则,但我认为您可以这样做:

    RewriteRule ^/web/(.+) /your/desired/path/$1 [R,L]
    

    假设目的地可以通过网络访问。参考:http://httpd.apache.org/docs/2.2/rewrite/remapping.html

    或者,如果它不能通过网络访问,您可以设置一个别名: http://httpd.apache.org/docs/2.2/urlmapping.html#outside

    我还没有测试过重写规则,我也从来没有弄乱过别名,但我认为这些可以解决问题。当然,这一切都假设您使用的是 Apache,可以访问 Apache 配置,或者至少是 .htacces 配置,并且除了提供静态文件之外,您没有更宏大的计划。我还假设您总体上对 Apache 配置有些熟悉,我知道不是每个人都熟悉。但是,如果这似乎可行,请尝试一下。或者随意忽略它。

    【讨论】:

    • 实际上是 klein 的 README 文件中的一个错误导致我使用 $service 而不是 $response。
    • 我看到你在 GitHub 上打开了一个错误报告来修复错误。感谢那! github.com/chriso/klein.php/issues/207
    【解决方案2】:

    我最终将这个简单的 sn-p 与 PHP 内置服务器一起使用:

    <?php
    // before creating a Klein inctance
    if (preg_match('#^/web/#', $_SERVER["REQUEST_URI"])) {
        return false;    // serve the requested resource as-is.
    }
    

    当然服务器是这样运行的

    php -S localhost:8000 -t . front_controller.php
    

    【讨论】:

    • 是第一个 sn-p 的 front_controller.php 内容还是您将其插入代码库中的其他位置?