1 回答

TA貢獻(xiàn)1783條經(jīng)驗(yàn) 獲得超4個(gè)贊
您有兩個(gè)基本選項(xiàng):首先,使用外部圖像加載器/處理程序腳本(例如<img src="image.php?i=sunshine.jpg" />
);其次,對(duì)圖像數(shù)據(jù)進(jìn)行 base64 編碼(例如<img src="data:image/png;base64, i26dfdXAd..." />
)。第二個(gè)選項(xiàng)會(huì)讓你的 HTML 變得臃腫,就像沒(méi)有明天一樣。那么讓我們簡(jiǎn)單地看一下image.php
處理程序方法。
處理程序如何知道要顯示什么圖像?它需要一個(gè)查詢字符串,例如image.php?i=sunshine.jpg
;或image.php?i=sunshine&x=jpg
;或者image.php?i=sunshine&x=jpg&s=600
,如果您想加載特定尺寸,等等。您必須在 HTML 源中使用該格式,沒(méi)有腳本可以自動(dòng)知道要加載什么圖像。然后,發(fā)送參數(shù)的是“誰(shuí)”(您),而不是“什么”。您需要確保變量得到正確的清理(正如您的示例處理程序所做的那樣);與任何用戶可修改的輸入一樣,它們不應(yīng)該被信任,尤其是靠近文件系統(tǒng)操作(目錄遍歷等)的任何地方。$_GET['i']
這些變量將作為、等供您的處理程序腳本使用$_GET['x']
。
如果您覺(jué)得 URL 參數(shù)很麻煩,或者看起來(lái)很臟,您可以隨時(shí)重寫 URL。將圖像鏈接為<img src="images/sunshine.jpg" />
,并.htaccess
在 /images/ 文件夾(僅包含您的腳本)中設(shè)置重寫規(guī)則,將所有圖像請(qǐng)求傳遞到處理程序腳本。您還可以使用此方法來(lái)處理縮小的圖像版本,并將源 URL<img src="images/sunshine__600.jpg" />
映射到重寫規(guī)則。
關(guān)于使用readfile()
(脫口而出大塊數(shù)據(jù)的最內(nèi)存友好的方式),只要您在調(diào)用header('Content-type: image/jpeg');
之前輸出(或其他適當(dāng)?shù)?MIME 標(biāo)頭)readfile()
,它就會(huì)以所需的方式工作。也就是說(shuō),瀏覽器不會(huì)知道網(wǎng)絡(luò)服務(wù)器直接從文件系統(tǒng)提供的圖像與通過(guò)處理程序從網(wǎng)絡(luò)根外部提供的圖像之間的區(qū)別。它只是帶有圖像 HTTP 標(biāo)頭的數(shù)據(jù)。
編輯:獎(jiǎng)金。編寫了一個(gè)簡(jiǎn)約的安全部署文件處理程序。
<?php
/*?
?* Receive image call as: <img src="img.php?i=name.jpg" />
?* Output matching image file from $basepath directory
?*/
$basepath = '../images/'; // Path to image folder
$mimes = [ // Allowed image types:
? ? 'jpg' => 'image/jpeg',
? ? 'png' => 'image/png',
? ? 'gif' => 'image/gif',
? ? 'svg' => 'image/svg+xml',
];
!isset($_GET['i']) && die(); // Nothing to do here.
// Parse & Verify Extension
$ext = strtolower(pathinfo($_GET['i'], PATHINFO_EXTENSION));
!isset($mimes[$ext]) && die('Invalid filetype!'); // If MIME N/A: die!
// Parse & Sanitize Filename?
$file = basename($_GET['i']);
$file = preg_replace('#[^[:alnum:] ._-]#', '', $file);
$filepath = realpath($basepath . $file);
$filepath === false && die('Invalid filename!'); // If image N/A: die!
// Output MIME header and image:
header('Content-Type:' . $mimes[$ext]);
readfile($filepath);
exit;
如果您需要容納jpeg
等變體,只需 a) 復(fù)制數(shù)組中的 MIME 定義$mimes
,或 b) 添加擴(kuò)展規(guī)范化例程。如果您需要訪問(wèn)子文件夾中的圖像,例如?i=sun/shine.jpg
,請(qǐng)重新編寫不帶basename
.?(確保您不會(huì)受到目錄遍歷的影響?。?。[:alnum:] ._-]
將從請(qǐng)求的文件名中刪除除 以外的字符。根據(jù)需要修改正則表達(dá)式。
- 1 回答
- 0 關(guān)注
- 205 瀏覽
添加回答
舉報(bào)