《PHP實戰:PHP Wrapper在SAE上的應用方法》要點:
本文介紹了PHP實戰:PHP Wrapper在SAE上的應用方法,希望對您有用。如果有疑問,可以聯系我們。
PHP實戰本文講述了PHP Wrapper在SAE上的應用辦法.分享給大家供大家參考,具體如下:
PHP實戰一、PHP Wrapper是什么
PHP實戰自PHP 4.3開始,PHP開始允許用戶通過stream_wrapper_register()自定義URL風格的協議.用戶使用fopen(), copy()等文件系統函數對封裝協議進行操作時,PHP會調用注冊協議時所提供的類中相應的函數.
PHP手冊中給了一個例子,它將VariableStream類注冊為var://協議,通過這個協議,用戶可以使用文件系統函數直接讀寫全局變量.例如,用戶可以通過 “var://foo” 讀寫 $GLOBALS['foo'] .
PHP實戰二、SAE為什么需要PHP Wrapper
PHP實戰出于性能和平安方面的考慮,SAE平臺上禁用了本地文件讀寫和對外的數據抓取.相應的,我們提供了對應的服務來做同樣的事情.
PHP實戰由于新服務的接口和PHP本身的接口不太一樣,專門為我們平臺開發的程序當然不會存在問題,但是大量已有的程序和開源項目,就面臨著繁雜的遷移工作.而使用PHP Wrapper對我們的服務的接口進行封裝之后,用戶就可以更方便地將程序遷移到SAE平臺.
PHP實戰三、如何寫PHP Wrapper
PHP實戰要通過PHP Wrapper封裝一個協議,首先,我們需要寫一個 streamWrapper 類,類名可自定義,類的格式為:
PHP實戰
streamWrapper {
public resource $context ;
__construct ( void )
public bool dir_closedir ( void )
public bool dir_opendir ( string $path , int $options )
public string dir_readdir ( void )
public bool dir_rewinddir ( void )
public bool mkdir ( string $path , int $mode , int $options )
public bool rename ( string $path_from , string $path_to )
public bool rmdir ( string $path , int $options )
public resource stream_cast ( int $cast_as )
public void stream_close ( void )
public bool stream_eof ( void )
public bool stream_flush ( void )
public bool stream_lock ( mode $operation )
public bool stream_open ( string $path , string $mode , int $options , string &$opened_path )
public string stream_read ( int $count )
public bool stream_seek ( int $offset , int $whence = SEEK_SET )
public bool stream_set_option ( int $option , int $arg1 , int $arg2 )
public array stream_stat ( void )
public int stream_tell ( void )
public int stream_write ( string $data )
public bool unlink ( string $path )
public array url_stat ( string $path , int $flags )
}
PHP實戰類中各辦法說明:
PHP實戰streamWrapper::__construct ― 構造函數,僅在stream_open前被調用
streamWrapper::dir_closedir ― 關閉目錄句柄,響應closedir()函數
streamWrapper::dir_opendir ― 打開目錄句柄,響應opendir()函數
streamWrapper::dir_readdir ― 從目錄句柄讀取條目,響應readdir()函數
streamWrapper::dir_rewinddir ― 倒回目錄句柄,響應rewinddir()函數
streamWrapper::mkdir ― 創建目錄,響應mkdir()函數
streamWrapper::rename ― 目錄或文件重命名,響應rename()函數
streamWrapper::rmdir ― 刪除目錄,響應rmdir()函數
streamWrapper::stream_cast ― 檢索基礎資源,響應stream_select()函數
streamWrapper::stream_close ― 關閉資源,響應fclose()函數
streamWrapper::stream_eof ― 檢查文件指針是否已經在文件末尾,響應feof()函數
streamWrapper::stream_flush ― 清除輸出緩存,響應fflush()函數
streamWrapper::stream_lock ― 咨詢文件鎖定,響應flock()函數
streamWrapper::stream_open ― 打開文件或URL為流,響應fopen()函數
streamWrapper::stream_read ― 從流中讀取內容,響應fread(), fgets()函數
streamWrapper::stream_seek ― 在流中定位指針,響應fseek()函數
streamWrapper::stream_set_option ― 改變流設置
streamWrapper::stream_stat ― 檢索文件資源的信息,響應fstat()函數
streamWrapper::stream_tell ― 檢索流中指針的位置,響應ftell()函數
streamWrapper::stream_write ― 向流中寫入內容,響應fwrite(), fputs()函數
streamWrapper::unlink ― 刪除文件,響應unlink()函數
streamWrapper::url_stat ― 檢索文件的信息,響應所有stat()相關的函數,例如file_exists(), is_dir(), is_file(), filesize(), fileinode()等等
PHP實戰詳細說明請參考PHP手冊:http://cn2.php.net/manual/en/class.streamwrapper.php
PHP實戰寫好streamWrapper類之后,使用 stream_wrapper_register () 將這個類注冊到Wrapper中,就可以開始使用了.函數使用辦法為:
PHP實戰bool stream_wrapper_register ( string $protocol , string $classname [, int $flags = 0 ] )
PHP實戰例如:
PHP實戰
stream_wrapper_register("saemc", "SaeMemcacheWrapper");
PHP實戰由于SAE平臺不支持對本地文件的寫操作,因此Smarty之類的一些需要在本地寫文件的開源項目就沒方法直接在SAE平臺上使用,而有了saemc Wrapper,用戶就可以將Smarty編譯的模板保存在MC中,很方便的將Smarty遷移到SAE平臺上來.
PHP實戰在附件中我們為大家提供了SAE上Memcache Wrapper的實現代碼,大家可以下載此附件進行測試.
PHP實戰在測試之前,需要先在本地啟動一個端口為22222的Memcached服務:
PHP實戰
memcached -m 10 -p 22222 -u nobody -l 127.0.0.1
PHP實戰然后使用下面代碼就可以測試了:
PHP實戰
//包含附件代碼,注冊saemc Wrapper
include_once('wrapper.php');
//測試 saemc Wrapper
$fp = fopen( "saemc://test.txt", "w+" ) or die("fopen faild!");
fwrite( $fp, "line1\n" ) or die("fwrite line1 faild!");
fwrite( $fp, "line2\n" ) or die("fwrite line2 faild!");
fwrite( $fp, "line3\n" ) or die("fwrite line3 faild!");
var_dump(ftell($fp));
fseek( $fp, 0 );
while ( !feof( $fp ) ) {
$c = fgets( $fp ) or die("fgets faild!");
var_dump($c);
}
fclose( $fp );
var_dump(file_get_contents("saemc://test.txt"));
var_dump(file_put_contents("saemc://path/test.txt", "hello world!\n"));
var_dump(file_put_contents("saemc://path/test.txt", "hello world!\n", FILE_APPEND));
var_dump(file_get_contents("saemc://path/test.txt"));
var_dump(copy("saemc://path/test.txt", "saemc://path/test_new.txt"));
var_dump(file_get_contents("saemc://path/test_new.txt"));
var_dump(unlink("saemc://path/test.txt"));
var_dump(file_get_contents("saemc://path/test.txt"));
var_dump(rename("saemc://path/test_new.txt", "saemc://path/test.txt"));
var_dump(file_get_contents("saemc://path/test.txt"));
echo "====test include====\n";
include_once("saemc://path/test.txt");
PHP實戰測試頁面的輸出結果:
PHP實戰
int(18)
string(6) "line1
"
string(6) "line2
"
string(6) "line3
"
string(18) "line1
line2
line3
"
int(13)
int(13)
string(26) "hello world!
hello world!
"
bool(true)
string(26) "hello world!
hello world!
"
bool(true)
bool(false)
bool(true)
string(26) "hello world!
hello world!
"
====test include====
hello world!
hello world!
PHP實戰我們提供的 Memcache Wrapper并沒有實現目錄操作的一些辦法和Memcache的Timeout,大家可以參考PHP手冊,嘗試實現目錄操作,或者通過context使這個Wrapper支持Memcache的Timeout.
PHP實戰另外,大家可以到下面這個地址查看SAE Stdlib中sae_include的源碼,在其中還有我們為Storage服務封裝的saestor Wrapper和為Fetchurl服務重新封裝的http Wrapper的實現:
PHP實戰http://stdlib.sinaapp.com/?f=sae_include.function.php
PHP實戰四、寫Wrapper時的一些注意事項
PHP實戰1. 構造函數
PHP實戰streamWrapper 類很特別,它的構造函數并不是每次都調用的.只有在你的操作觸發了stream_open相關的操作時才會調用,比如你用file_get_contents()了.而當你的操作觸發和stream無關的函數時,比如file_exists會觸發url_stat辦法,這個時候構造函數是不會被調用的.
PHP實戰2. 讀實現
PHP實戰Wrapper里邊有Position和Seek等概念,但是很多服務其實是一次性就讀取全部數據的,這個可以在stream_open的時候一次性讀回,放到一個屬性中,以后seek和tell的時候直接操作屬性里邊存放的數據就可以了.
PHP實戰3. 追加寫實現
PHP實戰有很多服務是一次性寫入所有數據,不支持追加寫的功能(比如Memcache),這就需要我們自己在Wrapper中來實現追加寫.可以將整個value一次性讀取出來,將需要追加寫的數據追加在讀取出來的內容后面之后,再一次性寫回.
PHP實戰但是這種追加寫的實現方式性能會比較差,尤其是內容體積較大之后,一次性讀取所有內容會非常消耗資源,因此在某些服務中我們不得不舍棄對追加寫的支持.
PHP實戰4. url_stat的實現
PHP實戰在streamWrapper類的實現中,url_stat的實現是個難點.必須正確的實現url_stat才能使is_writable和is_readable等查詢文件元信息的函數正常工作.
PHP實戰而我們需要為我們的虛設備偽造這些值.以mc為例,我們給大家一些參考數據:
PHP實戰url_stat應該返回一個數組,分13個項,內容如下:
PHP實戰dev 設備號 - 寫0即可;
ino inode號 - 寫0即可;
mode 文件mode - 這個是文件的權限控制符號,稍后詳細說明;
nlink link - 寫0即可;
uid uid - Linux上用posix_get_uid可以取到,windows上為0;
gid gid - Linux上用posix_get_gid可以取到,windows上為0;
rdev 設備類型 - 當為inode設備時有值;
size - 文件大小;
atime - 最后讀時間 格式為unix時間戳;
mtime - 最后寫時間;
ctime - 創建時間;
blksize - blocksize of filesystem IO 寫零即可;
blocks - number of 512-byte blocks allocated 寫零即可;
PHP實戰其中mode的值必須寫對:
PHP實戰如果是文件,其值為:
PHP實戰0100000 + 文件權限,如 0100000 + 0777.
PHP實戰如果是目錄,其值為:
PHP實戰040000 + 目錄權限,如 0400000 + 0777.
PHP實戰5. 關于stat的緩存
PHP實戰PHP會在同一個頁面的執行過程中對文件的元信息進行緩存.
根據PHP文檔對 clearstatcache() 這個辦法的說明得知:在使用 stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype(), 或 fileperms() 辦法查詢文件信息時,PHP會將文件的stat的緩存以提高性能. clearstatcache()辦法可以用來清除這個緩存,當unlink()會自動清除stat緩存.
PHP實戰而實際上,PHP只有在對本地文件進行unlink, rename和rmdir操作時會清除stat緩存,而在通過其他的wrapper進行unlink, rename和rmdir操作時,并不會清除stat緩存.因此在寫wrapper時我們要自己在unlink等辦法中通過clearstatcache()來清除stat緩存.
PHP實戰點擊此處下載附件.
PHP實戰更多關于PHP相關內容感興趣的讀者可查看本站專題:《php curl用法總結》、《php socket用法總結》、《PHP網絡編程技巧總結》、《PHP基本語法入門教程》、《php操作office文檔技巧總結(包括word,excel,access,ppt)》、《php日期與時間用法總結》、《php面向對象程序設計入門教程》、《php字符串(string)用法總結》、《php+mysql數據庫操作入門教程》及《php常見數據庫操作技巧匯總》
PHP實戰希望本文所述對大家PHP程序設計有所贊助.
《PHP實戰:PHP Wrapper在SAE上的應用方法》是否對您有啟發,歡迎查看更多與《PHP實戰:PHP Wrapper在SAE上的應用方法》相關教程,學精學透。維易PHP學院為您提供精彩教程。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/6798.html