【问题标题】:.htaccess - image filed treated as PHP file.htaccess - 图像文件被视为 PHP 文件
【发布时间】:2016-11-03 18:59:04
【问题描述】:

我编写了一个简单的 PHP REST 应用程序,但在提供静态文件时遇到了问题。我的目录结构如下:

  • 公开
    • 内容(这里是静态文件)
    • index.php
  • src(我的应用程序来源)
  • 供应商(Composer 依赖项)

我的项目中有两个 .htaccess 文件 - 在根目录和公共目录中:

root .htaccess

RewriteEngine on
RewriteRule    ^$    public/    [L]
RewriteRule    (.*) public/$1    [L]

public .htaccess(标准 Slim 模板)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA]

这些配置看起来像这样,因为我希望将所有请求重定向到公共目录并省略请求 uri 中的那部分以使用 http://host.com/rest/XXX 而不是 http://host.com/rest/public/XXX

现在我无法使用 http://host.com/rest/content/file-test.ext 访问文件 - 因为我收到错误,它似乎被视为 PHP 文件:

Warning: Unexpected character in input: '' (ASCII=30) state=0 in /rest/public/content/file-test.ext on line 298

Parse error: syntax error, unexpected '@' in /rest/public/content/file-test.ext on line 298

我已经尝试使用RewriteEngine offphp_flags engine off 将单独的.htaccess 文件放在内容目录中。

我无法更改任何网络服务器配置,因为托管由第三部分人提供,我什至无法请求任何更改。 host.com/rest 我设置为我的文档根目录,当我通过 FTP 连接时,我无法从该目录向上移动,因此关于网络服务器配置更改的解决方案在我的情况下不正确。

请帮助我让静态文件正常工作!

【问题讨论】:

  • 如果你使用的是 slim,为什么不直接在路由前加上 /rest/ 而不是重写呢?然后只需为/rest/content 设置一个别名以指向/public/content?一个建议是将您的 Web 根目录实际指向公共文件夹,并将您的源代码保留在 Web 根目录之外
  • @MagnusEriksson - 我已经将路线指定为/rest/method。你说的别名是什么意思?你知道一些将 Slim 请求传递到特定目录以返回文件流的方法吗?我无法将公共目录设置为内容根目录,因为我无法管理服务器并且没有机会请求更改。
  • 您的网络服务器应该将公用文件夹配置为文档根目录。
  • 我有网络服务器文档根集,但无法更改或向上导航。我只能通过 FTP 连接并上传文件,而没有任何机会从该文档根目录中上去。地址也设置为该文档根目录,我无法更改它。如果我能够以其他方式处理该问题,我不会询问该 htaccess 配置。

标签: php apache .htaccess slim


【解决方案1】:

利用 Slim:它将控制权保留在您的手中,您无法解决 .htaccess 的问题。

还有:

  • 您可以随时更改路线或包含文件夹。
  • 您可以设置其他标题,例如用于缓存。
$app->get('/content/{pathToImage}', function($request, $response, $args) {
    $pathToFile = $args['pathToImage'];
    $containingFolder = '../content/'; // the actual folder where files are stored
    // if you want to omit file extension in the url, we'll have to find it out
    $matches = glob($containingFolder.$fileName.'.*');
    if ($matches) {
        $clientImagePath = array_shift($matches); // let's grab the first file matching our mask
        $clientImage = @file_get_contents($clientImagePath);
        $finfo = new \Finfo(FILEINFO_MIME_TYPE);
        $response->write($clientImage);
        return $response->withHeader('Content-Type', $finfo->buffer($clientImage));
    } else {
        // if no matches found, throw exception that will be handled by Slim
        throw new \Slim\Exception\NotFoundException($request, $response);
    }
});

如果您可以接受像 content/image.png(具有文件扩展名)这样的 URL,您可以通过更简单的方式来执行此操作:

$app->get('/assets/images/{pathToImage}', function($request, $response, $args) {
    $pathToFile = $args['pathToImage'];
    $path = '../content/'.$fileName;
    $image = @file_get_contents($path);
    $finfo = new \Finfo(FILEINFO_MIME_TYPE);
    $response->write($image);
    return $response->withHeader('Content-Type', $finfo->buffer($image));
});

【讨论】:

  • 非常感谢!按我的预期工作。我只需要为不存在的文件添加验证:) 很好的解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-10
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-04
  • 1970-01-01
相关资源
最近更新 更多