2010-10-07 31 views
1

我的網站上有很多圖像,當它們被請求保存我的託管服務器上的磁盤空間時,它們從圖像服務器拉到主服務器上。如果圖像不存在,自動重定向/下載 - 優化

要做到這一點我在01​​文件中的條目,基本上內部重定向人從/images/image.jpgdownload.php進行檢查,看是否該文件存在。如果文件存在,它會提供它(下面的代碼),否則它將使用CURL來拉入遠程文件,然後重定向到它自己header("Location: ".$_SERVER['REQUEST_URI']);,以便它顯示圖像。

以這種方式向瀏覽器提供圖像效率不高嗎?讓Web服務器自然而然地做得更快?閱讀和顯示文件的代碼如下。

$file_extension = strtolower(substr(strrchr($filename,"."),1)); 

header("Pragma: public"); 
header("Content-Type: image/jpg"); 
header("Content-length: ".filesize($filename)); 
header("Content-Transfer-Encoding: binary"); 
header("Content-Length: ".filesize($filename)); 
readfile("$filename"); 

我會變得更好(閱讀:更有效)不使用htaccess的重定向,但實際修改我的404頁,以檢查圖像的確定404的,然後將它們下載?

這裏是定義重定向到download.php

^images/([0-9]+)_([a-z0-9_]+).jpg$ /download.php?id=$1 

回答

3

這是有點不清楚你的意思是'重定向到自己'。是否有任何理由您的download.php不能使用CURL從遠程服務器獲取圖像,然後使用代碼示例以相同的方式提供它?爲什麼需要重定向?

如果可以避免的話,最好不要使用PHP引擎來提供圖片,因爲Apache本身可以更高效地完成此操作。您還會失去Apache的一些默認行爲,例如你的代碼示例沒有發送最後修改的頭文件或處理etags,所以如果用戶重新訪問同一頁面,他們將最終下載圖像而不是使用緩存版本。

您的建議替代方法會更好一些,因爲一旦您的腳本第一次下載了映像,所有後續請求將直接由Apache提供。只要確保你沒有發送404頭和圖像。

或者可以使用htaccess檢查文件是否存在,因此您只能將不存在的圖像的請求重定向到download.php,而不必修改404腳本。像這樣(未經):

RewriteEngine On 
RewriteCond %{REQUEST_URI} ^/images 
RewriteCond %{REQUEST_FILENAME} !-s 
RewriteRule ^.*$ download.php [NC,L] 

這意味着:如果REQUEST_URI與/圖像開始,文件名不符合文件系統上的現有文件,重寫它的download.php。

我還建議尋找X-Sendfile,一個Apache模塊,這使得它非常容易提供圖像(和其他二進制數據)。在PHP中使用它是作爲發送包含該文件的路徑頭一樣簡單:

header("X-Sendfile: /home/whatever/public/images/something.jpg"); 

阿帕奇然後爲你做的所有工作休息 - 閱讀和輸出文件的內容和發送所有適當的頭。該模塊默認情況下通常不啓用,因此您可能需要安裝它或與您的主機進行覈對。

+0

在.htaccess中檢查文件存在是一個非常好的主意,關於從哪裏開始的想法?什麼是X-SendFile? – Chris 2010-10-07 18:15:00

+0

我試圖使用X-Sendfile(這看起來很棒btw!)但它沒有工作lol – Chris 2010-10-07 18:22:02

+0

我編輯了我的答案與htaccess示例和X-Sendfile的解釋。如果您對X-Sendfile有任何問題,請檢查phpinfo()以確保它已啓用,並檢查Apache錯誤日誌是否仍然無效。 – 2010-10-07 18:31:31

0

我覺得發球直接圖像將永遠是比你的代碼,不會讓使用瀏覽器緩存,但我不知道快.htaccess

+0

就瀏覽器而言,一旦加載圖像不會改變,因爲它的文件大小和文件名沒有改變。至少瀏覽器似乎緩存它! – Chris 2010-10-07 18:07:46

+0

是的,但圖像加載通過一個PHP文件,所以我不知道它是否工作? – MatTheCat 2010-10-07 18:10:11

0

就客戶端到瀏覽器的連接而言,它與通常的數據服務一樣快。 Apache不關心信息來自哪裏,它只是發送它交給的數據。如果數據是讀取文件或像C++程序這樣的一千萬個結果的結果,那麼這只是一點點。

你的方法比較慢的地方是從圖像服務器上拉出圖像。這基本上意味着圖像被髮送兩次。一次從映像服務器 - >主機服務器,然後再從主機服務器 - >客戶機。如果您的圖像服務器和主機服務器位於同一局域網上,節點相對較少,連接速度非常快,那麼這可能不會有明顯的差異。如果圖像服務器位於不同的網絡上,或者圖像文件非常大,則差異可能會很大,並且可能不值得花費磁盤空間。

1

你會與剛用前綴你重寫更好:

RewriteCOnd %{REQUEST_FILENAME} !-f 

...如果你下載的文件中的download.php,爲什麼不直接展示給用戶?不需要重定向。

+0

我原本是這麼做的,但認爲這樣做會更快?此外,具體的RewriteCond做什麼?我將如何將它納入我的htaccess? (病毒更新問題) – Chris 2010-10-07 18:20:11

+0

如果文件不存在,它只會重定向到你的download.php文件。 – Wrikken 2010-10-07 18:38:15