[英]Serve static files without hard coding all file types header information
I am currently making a router in my project and I realised a problem.我目前正在我的项目中制作路由器,但我意识到了一个问题。 I am using the .htaccess file to redirect all routes to my
router.php
file.我正在使用 .htaccess 文件将所有路由重定向到我的
router.php
文件。 This creates a problem where all of my css/images/js files are redirected to my .htaccess file too.这会产生一个问题,我的所有 css/images/js 文件也都被重定向到我的 .htaccess 文件。 This is the code for my .htacess file:
这是我的 .htacess 文件的代码:
RewriteEngine on
Options +Multiviews
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/?$ $1.php
RewriteRule ^(.*)$ router.php [NC,L,QSA]
I had tried solving this problem by manually detecting if it is one of the recognised static file type and manually returning the contents.我曾尝试通过手动检测它是否是可识别的静态文件类型之一并手动返回内容来解决此问题。 In my router class, I checked if the give file type is a recognised static file type.
在我的路由器类中,我检查了给定文件类型是否是可识别的静态文件类型。 If it is a static file type I will render it if not I will give it to the handle function which basically checks if the route is recognised and returns the call to a function.
如果它是静态文件类型,我将呈现它,否则我会将它交给句柄函数,该函数基本上检查路由是否被识别并返回对函数的调用。
if ($isStatic["check"]) {
$this->render->returnStaticFiles($data["uri"], $isStatic["type"], $isStatic["ext"] ?? "");
} else {
$this->handle($data["uri"]);
}
However, the problem with this is I need to manually add the static file types to an array and use a function to set the right headers or else it is just going to be recognised as text/html and that doesn't work with either css or images.但是,问题是我需要手动将静态文件类型添加到数组中并使用函数来设置正确的标题,否则它只会被识别为text/html并且不适用于任何 css或图像。 Css will not get parsed and images will simply return as binary texts as gibberish.
Css 不会被解析,图像只会以二进制文本的形式返回,就像乱码一样。 This is how I currently implement the render class:
这就是我目前实现渲染类的方式:
<?php
namespace app\Router;
use JetBrains\PhpStorm\ArrayShape;
class Render
{
public array $static_file_types = ["js", "css", "html", "json"];
public array $image_types = ["png", "jpg", "jpeg"];
public function __construct(
public string $root_dir = "",
public string $home = "http://localhost/"
){}
public function throwError(int $statusCode = 500) :string
{
$err_dir = $this->root_dir . "errors\\";
$file_contents = file_get_contents($err_dir . "$statusCode.php") ?? false;
if (!$file_contents) {
return str_replace(
["{code}", "{home}"],
[$statusCode, $this->home],
file_get_contents($err_dir . "err_template.php")
);
}
return str_replace("{home}", $this->home, $file_contents);
}
public function returnStaticFiles(string $uri, string $type, string $ext) : void
{
if ($type == "cnt") {
$this->setHeader($ext);
include_once $this->root_dir . $uri;
} elseif ($type == "img") {
$this->handleImage($this->root_dir . urldecode($uri), $ext);
} else {
echo "This file is not supported sorry";
exit();
}
}
private function handleImage(string $path_to_image, string $type) : void
{
if (file_exists($path_to_image)) {
$image = fopen($path_to_image, "r");
header("Content-Type: image/$type");
header("Content-Length: " . filesize($path_to_image));
fpassthru($image);
} else {
echo "This image does not exist sorry";
}
}
#[ArrayShape(["check" => "bool", "type" => "string", "ext" => "string"])]
public function checkIsStatic($uri) : array
{
$_uri = explode(".", $uri);
$ext = end($_uri);
if (in_array($ext, $this->static_file_types)) {
return ["check" => true, "type" => "cnt", "ext" => $ext];
} elseif (in_array($ext, $this->image_types)) {
return ["check" => true, "type" => "img", "ext" => $ext];
} else {
return ["check" => false, "type" => ""];
}
}
private function setHeader($ext): void
{
switch ($ext) {
case "css":
header("Content-Type: text/css"); break;
case "js":
header("Content-Type: text/javascript"); break;
case "json":
header("Content-Type: application/json"); break;
default:
header("Content-Type: text/html"); break;
}
}
}
This is working just fine but is there any way around this?这工作得很好,但有什么办法解决这个问题吗? I might need to serve PDF content or other file types such as audio or video and I don't think this is an optimal solution for it.
我可能需要提供 PDF 内容或其他文件类型,例如音频或视频,我认为这不是最佳解决方案。 I tried searching it but I don't think I can find anything.
我尝试搜索它,但我认为我找不到任何东西。
I appreciate any assistance.我感谢任何帮助。
Turns out it was a simple solve.原来这是一个简单的解决方案。 I just changed the redirect everything to
router.php
into another line RewriteRule !.(js|css|ico|gif|jpg|png)$ router.php [L]
我只是将重定向所有内容更改为
router.php
到另一行RewriteRule !.(js|css|ico|gif|jpg|png)$ router.php [L]
This checks if the file is not a js or css or etc then it redirects to router.php file or else it would normally serve the file.这会检查文件是否不是 js 或 css 等,然后它会重定向到 router.php 文件,否则它通常会提供该文件。 I think my question is not clear enough for other people to understand so I hope this answer clears things up.
我认为我的问题不够清楚,其他人无法理解,所以我希望这个答案可以解决问题。
Big shoutout to this link which made everything right: rewrite rule in .htaccess: what does it do对这个链接的大喊大叫,它使一切都正确: 在.htaccess中重写规则:它做了什么
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.