我正在開發一個涉及PHP內置web服務器的測試項目,我正在測試一些想法。php內置的web服務器緩存問題
我想實現我自己的常用資源(png,jpg,json,txt等...)的緩存機制,以減少內置服務器在php中的負載。
我開始內置的服務器是這樣的:
PHP -S 127.0.0.1:80 -t公共router.php
所以,文檔根內置服務器設置爲public
,它運行router.php
(因爲我正在考慮實現一個簡單的重寫功能)。
這是我的router.php
文件的內容:
<?php
// Register request uri
$requestUri = isset($_SERVER['REQUEST_URI'])
? $_SERVER['REQUEST_URI']
: '/';
// Handle app resources with caching
if (preg_match('/\.(?:png|jpg|jpeg|gif|xml|json|css|eot|svg|otf|ttf|woff|woff2|scss|less|txt|ico)$/', $requestUri))
{
// Generate file name
$fileName = __DIR__ .'/public'. $requestUri;
// Parse file data
$lastModified = filemtime($fileName);
$etagFile = md5_file($fileName);
$ifModifiedSince = (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false);
$etagHeader = (isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false);
// Set caching header
header('Last-Modified: '. gmdate('D, d M Y H:i:s', $lastModified) .' GMT');
header('Etag: '. $etagFile);
header('Cache-Control: public');
// Check if the requested resource has changed
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified || $etagHeader == $etagFile)
{
// File has not changed
header('HTTP/1.1 304 Not Modified');
exit;
}
else
{
// Parse requested resource's mime type
$finfo = new finfo(FILEINFO_MIME);
$mime_type = $finfo->buffer(
file_get_contents($fileName, false, null, -1, 64),
FILEINFO_MIME_TYPE
);
// Serve requested resource
header('Content-Type: '. $mime_type);
header('Content-Length: '. filesize($fileName));
@readfile($fileName);
$finfo = null;
exit;
}
}
// Parse requested page & action
list ($page, $action) =
array_pad(array_values(array_filter(explode('/', $requestUri, 3), 'strlen')), 2, 'index');
if ($page == 'index') $page = 'server';
// Test - to do rest of routing
var_dump('page = '. $page);
var_dump('action = '. $action);
// include 'app/'. $page .'/'. $action .'.php';
?>
我通過訪問以下網址測試reource(PNG圖像)緩存:http://localhost/apple-icon-120x120.png
所以,這是資源的第一負載,所以服務回報與預期HTTP 200
響應的資源,需要約307ms
:
現在,如果我PRES S中的F5
重新加載頁面,服務器返回HTTP 304
(不修改)如預期,並且請求了約5ms
(偉大的!):
如果我按F5
第三次,服務器仍然返回HTTP 304
(不修改)如預期,不過這一次的請求大約306ms
了一次(好像是資源沒有緩存):
如果我硬逼F5
,處理請求的時間是隨機5m
之間alternativing約307ms
。
任何想法,爲什麼它的行爲是這樣的?一旦資源被緩存,不應該不斷地返回304
並處理請求約5ms
?爲什麼零星的行爲?
我確實看到返回的內容大小爲225 bytes
(當它知道數據已被封裝)時,我無法弄清楚請求處理時間的瓶頸在哪裏。我的主機運行帶有Intel i7 CPU,6GB RAM & SSD驅動器的Windows。