目錄
PHP Wrapper在SAE上的应用方法,wrappersae
首頁 php教程 php手册 PHP Wrapper在SAE上的应用方法,wrappersae

PHP Wrapper在SAE上的应用方法,wrappersae

Jun 13, 2016 am 08:40 AM
php wrapper

PHP Wrapper在SAE上的应用方法,wrappersae

本文讲述了PHP Wrapper在SAE上的应用方法。分享给大家供大家参考,具体如下:

一、PHP Wrapper是什么

自PHP 4.3开始,PHP开始允许用户通过stream_wrapper_register()自定义URL风格的协议。用户使用fopen(), copy()等文件系统函数对封装协议进行操作时,PHP会调用注册协议时所提供的类中相应的函数。
PHP手册中给了一个例子,它将VariableStream类注册为var://协议,通过这个协议,用户可以使用文件系统函数直接读写全局变量。例如,用户可以通过 “var://foo” 读写 $GLOBALS['foo'] 。

二、SAE为什么需要PHP Wrapper

出于性能和安全方面的考虑,SAE平台上禁用了本地文件读写和对外的数据抓取。相应的,我们提供了对应的服务来做同样的事情。

由于新服务的接口和PHP本身的接口不太一样,专门为我们平台开发的程序当然不会存在问题,但是大量已有的程序和开源项目,就面临着繁杂的迁移工作。而使用PHP Wrapper对我们的服务的接口进行封装之后,用户就可以更方便地将程序迁移到SAE平台。

三、如何写PHP Wrapper

要通过PHP Wrapper封装一个协议,首先,我们需要写一个 streamWrapper 类,类名可自定义,类的格式为:

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 )
}

登入後複製

类中各方法说明:

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手册:http://cn2.php.net/manual/en/class.streamwrapper.php

写好streamWrapper类之后,使用 stream_wrapper_register () 将这个类注册到Wrapper中,就可以开始使用了。函数使用方法为:

bool stream_wrapper_register ( string $protocol , string $classname [, int $flags = 0 ] )

例如:

stream_wrapper_register("saemc", "SaeMemcacheWrapper");

登入後複製

由于SAE平台不支持对本地文件的写操作,因此Smarty之类的一些需要在本地写文件的开源项目就没办法直接在SAE平台上使用,而有了saemc Wrapper,用户就可以将Smarty编译的模板保存在MC中,很方便的将Smarty迁移到SAE平台上来。

在附件中我们为大家提供了SAE上Memcache Wrapper的实现代码,大家可以下载此附件进行测试。

在测试之前,需要先在本地启动一个端口为22222的Memcached服务:

memcached -m 10 -p 22222 -u nobody -l 127.0.0.1

登入後複製

然后使用下面代码就可以测试了:

//包含附件代码,注册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");

登入後複製

测试页面的输出结果:

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!

登入後複製

我们提供的 Memcache Wrapper并没有实现目录操作的一些方法和Memcache的Timeout,大家可以参考PHP手册,尝试实现目录操作,或者通过context使这个Wrapper支持Memcache的Timeout。

另外,大家可以到下面这个地址查看SAE Stdlib中sae_include的源码,在其中还有我们为Storage服务封装的saestor Wrapper和为Fetchurl服务重新封装的http Wrapper的实现:

http://stdlib.sinaapp.com/?f=sae_include.function.php

四、写Wrapper时的一些注意事项

1. 构造函数

streamWrapper 类很特别,它的构造函数并不是每次都调用的。只有在你的操作触发了stream_open相关的操作时才会调用,比如你用file_get_contents()了。而当你的操作触发和stream无关的函数时,比如file_exists会触发url_stat方法,这个时候构造函数是不会被调用的。

2. 读实现

Wrapper里边有Position和Seek等概念,但是很多服务其实是一次性就读取全部数据的,这个可以在stream_open的时候一次性读回,放到一个属性中,以后seek和tell的时候直接操作属性里边存放的数据就可以了。

3. 追加写实现

有很多服务是一次性写入所有数据,不支持追加写的功能(比如Memcache),这就需要我们自己在Wrapper中来实现追加写。可以将整个value一次性读取出来,将需要追加写的数据追加在读取出来的内容后面之后,再一次性写回。

但是这种追加写的实现方式性能会比较差,尤其是内容体积较大之后,一次性读取所有内容会非常消耗资源,因此在某些服务中我们不得不舍弃对追加写的支持。

4. url_stat的实现

在streamWrapper类的实现中,url_stat的实现是个难点。必须正确的实现url_stat才能使is_writable和is_readable等查询文件元信息的函数正常工作。

而我们需要为我们的虚设备伪造这些值。以mc为例,我们给大家一些参考数据:

url_stat应该返回一个数组,分13个项,内容如下:

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 写零即可;

其中mode的值必须写对:

如果是文件,其值为:

0100000 + 文件权限,如 0100000 + 0777。

如果是目录,其值为:

040000 + 目录权限,如 0400000 + 0777。

5. 关于stat的缓存

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只有在对本地文件进行unlink, rename和rmdir操作时会清除stat缓存,而在通过其他的wrapper进行unlink, rename和rmdir操作时,并不会清除stat缓存。因此在写wrapper时我们要自己在unlink等方法中通过clearstatcache()来清除stat缓存。

点击此处下载附件。

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php curl用法总结》、《php socket用法总结》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《php操作office文档技巧总结(包括word,excel,access,ppt)》、《php日期与时间用法总结》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1667
14
CakePHP 教程
1426
52
Laravel 教程
1328
25
PHP教程
1273
29
C# 教程
1255
24
PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python:代碼示例和比較 PHP和Python:代碼示例和比較 Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

See all articles