1 回答
TA貢獻1783條經驗 獲得超5個贊
您有兩個基本選項:首先,使用外部圖像加載器/處理程序腳本(例如<img src="image.php?i=sunshine.jpg" />);其次,對圖像數據進行 base64 編碼(例如<img src="data:image/png;base64, i26dfdXAd..." />)。第二個選項會讓你的 HTML 變得臃腫,就像沒有明天一樣。那么讓我們簡單地看一下image.php處理程序方法。
處理程序如何知道要顯示什么圖像?它需要一個查詢字符串,例如image.php?i=sunshine.jpg;或image.php?i=sunshine&x=jpg;或者image.php?i=sunshine&x=jpg&s=600,如果您想加載特定尺寸,等等。您必須在 HTML 源中使用該格式,沒有腳本可以自動知道要加載什么圖像。然后,發送參數的是“誰”(您),而不是“什么”。您需要確保變量得到正確的清理(正如您的示例處理程序所做的那樣);與任何用戶可修改的輸入一樣,它們不應該被信任,尤其是靠近文件系統操作(目錄遍歷等)的任何地方。$_GET['i']這些變量將作為、等供您的處理程序腳本使用$_GET['x']。
如果您覺得 URL 參數很麻煩,或者看起來很臟,您可以隨時重寫 URL。將圖像鏈接為<img src="images/sunshine.jpg" />,并.htaccess在 /images/ 文件夾(僅包含您的腳本)中設置重寫規則,將所有圖像請求傳遞到處理程序腳本。您還可以使用此方法來處理縮小的圖像版本,并將源 URL<img src="images/sunshine__600.jpg" />映射到重寫規則。
關于使用readfile()(脫口而出大塊數據的最內存友好的方式),只要您在調用header('Content-type: image/jpeg');之前輸出(或其他適當的 MIME 標頭)readfile(),它就會以所需的方式工作。也就是說,瀏覽器不會知道網絡服務器直接從文件系統提供的圖像與通過處理程序從網絡根外部提供的圖像之間的區別。它只是帶有圖像 HTTP 標頭的數據。
編輯:獎金。編寫了一個簡約的安全部署文件處理程序。
<?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) 復制數組中的 MIME 定義$mimes,或 b) 添加擴展規范化例程。如果您需要訪問子文件夾中的圖像,例如?i=sun/shine.jpg,請重新編寫不帶basename.?(確保您不會受到目錄遍歷的影響?。?code>[:alnum:] ._-]將從請求的文件名中刪除除 以外的字符。根據需要修改正則表達式。
- 1 回答
- 0 關注
- 224 瀏覽
添加回答
舉報
