從5.2開始APC加入了一個叫APC_UPLOAD_PROGRESS的東東,解決了困擾大家已久的進度條問題。並且它把原來的上傳時把臨時檔案全部緩衝到記憶體改成了當臨時檔案達到設定值時就自動儲存到硬碟,有效地改善了記憶體利用狀況。
它的作用原理是在上傳時候賦予每個上傳一個唯一的ID,當 PHP 指令碼收到一個上傳檔案時,解釋程式將自動檢查 $_POST數組中名為 APC_UPLOAD_PROGRESS 的隱藏欄位,它將成為緩衝變數,儲存關於上傳的資訊,這樣指令碼就可以通過上傳的ID來訪問上傳檔案的狀態資訊。
APC是Alternative PHP Cache的簡稱,是 PHP 的一個免費公開的最佳化代碼緩衝。它用來提供免費,公開並且強健的架構來緩衝和最佳化 PHP 的中間代碼。
APC模組的參數配置
| 代碼如下 |
複製代碼 |
Name Default Changeable Changelog apc.enabled 1 PHP_INI_ALL apc.shm_segments 1 PHP_INI_SYSTEM apc.shm_size 30 PHP_INI_SYSTEM apc.optimization 0 PHP_INI_ALL apc.num_files_hint 1000 PHP_INI_SYSTEM apc.ttl 0 PHP_INI_SYSTEM apc.gc_ttl 3600 PHP_INI_SYSTEM apc.cache_by_default On PHP_INI_SYSTEM apc.filters "" PHP_INI_SYSTEM apc.mmap_file_mask "" PHP_INI_SYSTEM apc.slam_defense 0 PHP_INI_SYSTEM apc.file_update_protection 2 PHP_INI_SYSTEM apc.enable_cli 0 PHP_INI_SYSTEM > APC 3.0.6 |
好了配置好了現在就開始寫程式了
XML/HTML代碼
| 代碼如下 |
複製代碼 |
<!–以下為上傳表單–> <form enctype="multipart/form-data" id="upload_form" action="" method="POST"> <input type="hidden" name="APC_UPLOAD_PROGRESS" id="progress_key" value="upid"/> 視頻標題:<input type="text" id="subject" name="subject"/> 視頻說明:<input type="text" id="content" name="content"/> 視頻TAG(以逗號分割)<input type="text" id="tag" name="tags"/> <input type="file" id="upfile" name="upfile"/> <input type="submit" id="filesubmit" value="上傳" onclick="startProgress(‘upid’); return true;"/> <!–注意:startProgress(‘upid’)中的參數是你從php中分配的唯一上傳參數–> </form> <!–以下為上傳進度條–> <div id="upstatus" style="width: 500px; height: 30px; border: 1px solid ##ffffde; color:#796140;"> </div <div id="progressouter" style="width: 500px; height: 20px; border: 3px solid #de7e00; display:none;"> <div id="progressinner" style="position: relative; height: 20px; color:#796140; background-color: #f6d095; width: 0%; "></div> </div> |
最主要的就是那個APC_UPLOAD_PROGRESS的隱藏欄位,有了它指令碼才能去訪問目前上傳檔案的狀態,另外加一個顯示上傳狀態的div就好了。
下面是處理Ajax的指令碼,我用了Jquery架構,json傳遞訊息。
JavaScript代碼
| 代碼如下 |
複製代碼 |
function getProgress(upid){ var url = "<{$siteurl}>epadmin/upprocess"; $.getJSON( url, { progress_key: upid }, function(json){ $("#progressinner").width(json.per+"%"); $("#upstatus").html(‘檔案大小:’+json.total+‘KB’+‘ 已上傳:’+json.current+‘KB’); if (json.per < 100){ setTimeout(function(){ getProgress(upid); }, 10); }else{ $("#upstatus").html("視頻上傳完成,正在處理資料,請稍後……"); } } ) } function startProgress(upid){ $("#progressouter").css({ display:"block" }); setTimeout(function(){ getProgress(upid); }, 100); }
再 |
下來就是讀取上傳狀態的PHP代碼了,至於上傳檔案的處理可以按照平常自己的來寫.
| 代碼如下 |
複製代碼 |
//上傳檔案操作函數,可按照自己的需要編寫 function upflvAction() { if($_SERVER['REQUEST_METHOD']==‘POST’){ $subject = trim($this->f->filter($this->_request->getPost(‘subject’))); $content = trim($this->f->filter($this->_request->getPost(‘content’))); Zend_Loader::loadClass(‘Custom_FlvOp’); $flv = new Custom_FlvOp; $flv->uploadFlv(‘upfile’,$subject,$content); } } //這就是讀取上傳狀態的函數了~~ function upprocessAction() { if(isset($_GET['progress_key'])) { $status = apc_fetch(‘upload_’.$_GET['progress_key']); $json = array( ‘per’=>$status['current']/$status['total']*100, ‘total’=>round($status['total']/1024), ‘current’=>round($status['current']/1024), ); require_once("Zend/Json.php"); echo Zend_Json::encode($json); } } |
一些關於apc配置詳解
apc.enabled 布爾型
apc.enabled 可以被設成 0 來禁用 APC。這主要是有用的,當 APC 被靜態編譯入 PHP 時,因為沒有其它方法來禁用它(當編譯為 DSO 的時候,可以將 php.ini 中的 extension 行注釋掉)。
apc.shm_segments 整型
對編譯緩衝分配共用記憶體塊的數量。如果APC用光了共用記憶體,而且你已經設定 apc.shm_size為系統允許的最大值的情況下,你可以試著去提高這個參數的值。
apc.shm_size 整型
每個共用記憶體塊的大小是以MB為單位的。在預設情況下,一些系統(包括大多數BSD變種系統)的共用記憶體塊的大小限制的很低。
apc.optimization 整型
最佳化等級。設為0則禁用最佳化,越高的值使用越強有力的最佳化。期待有適度的速度上的改進。這個還是實驗性質的。
apc.num_files_hint 整型
對在你的Web伺服器上被包含和請求的不同的源檔案的數量的提示。如果你無法確定,設定為0或者省略;這個設定主要可能用於有成千的源檔案的網站。
apc.ttl 整型
當一個緩衝條目在緩衝區的位置被另一個條目需要時,我們需要考慮的是這個緩衝條目在緩衝區的位置被允許閒置秒數。將這個參數設定為0意味著你的緩衝可能充滿不新鮮的條目,同時導致新的條目無法被緩衝。
apc.gc_ttl 整型
緩衝條目在垃圾收集列表中存活的秒數。這個值提供了出錯保護在執行一個緩衝源檔案,而同時伺服器處理序死了的事件中。如果那個源檔案被修改,記憶體配置給舊版本的緩衝條目將不會被回收,直到這個參數設定的TTL值到的時候。設定為0就是禁止這個特性。
apc.cache_by_default 布爾型
預設為On,但可以被設定為Off並和以加號開頭的apc.filters配合使用,檔案僅僅在匹配過濾器時才被緩衝。
apc.filters 字串
一個以逗號分割的POSIX擴充Regex的列表。如果任何模式比對源檔案名稱,這個檔案將不會被緩衝。注意用來匹配的檔案名稱是傳遞給 include/require 的檔案名稱,而不是絕對路徑。如果Regex的第一個字元是 + ,則這個運算式就意味著任何匹配運算式的檔案將會被緩衝,如果第一個字元是 - 則任何匹配都不會被緩衝。 - 是預設值,所以可以被省略。
apc.mmap_file_mask 字串
apc.slam_defense 整型
在非常繁忙的伺服器上,無論你啟動服務還是修改檔案,你都會導致一種多進程都試圖在同一個時間緩衝同一個檔案的競爭。這個選項設定了進程跳過試圖去緩衝一個未被緩衝的檔案的百分比。或者可以把這個想象成一個單獨進程跳過緩衝的機率。例如,設定apc.slam_defense為75就意味著進程有75%的機率不去緩衝未被緩衝的檔案。所以,設定的越高,越能減少緩衝的碰撞機率。設定為0則禁用這個特性。
apc.file_update_protection 整型
當你在一個運行著的伺服器上修改檔案時,你應該執行原子操作。也就是,先寫一個臨時檔案,當寫完後再重新命名(mv)這個檔案到它的最終位置。許多文字編輯器,cp,tar和其他一些類似程式都不是這樣操作的。這就意味著有機會去訪問和(緩衝)檔案,當這個檔案還在被寫的情況下。apc.file_update_protection的設定使得快取標籤新檔案的延遲。預設值是2,意味著如果發現檔案的修改時間距離訪問時間不到2秒,檔案將不會被緩衝。訪問寫到一半的檔案的不幸使用者將會看到離奇的情況,但至少這種情況不是持續的。如果你確信你經常使用原子操作來更新你的檔案,你可以關閉這個保護通過設定這個參數為0。如果你的系統充滿io操作,並導致更新程式花費超過2秒,你可能需要去增大這個值。
apc.enable-cli 整型
大多是為了測試和調試。為CLI版本的PHP開啟動APC功能。一般來說,你將不會想到為每一個 CLI請求建立,移植和放棄APC的緩衝,但對於各種測試情況,這是很容易的為了CLI版本開啟APC。