搜索
首页后端开发php教程PHP Wrapper在SAE上的应用方法,wrappersae_PHP教程

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程序设计有所帮助。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1125234.htmlTechArticlePHP Wrapper在SAE上的应用方法,wrappersae 本文讲述了PHP Wrapper在SAE上的应用方法。分享给大家供大家参考,具体如下: 一、PHP Wrapper是什么 自...
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
使用数据库存储会话的优点是什么?使用数据库存储会话的优点是什么?Apr 24, 2025 am 12:16 AM

使用数据库存储会话的主要优势包括持久性、可扩展性和安全性。1.持久性:即使服务器重启,会话数据也能保持不变。2.可扩展性:适用于分布式系统,确保会话数据在多服务器间同步。3.安全性:数据库提供加密存储,保护敏感信息。

您如何在PHP中实现自定义会话处理?您如何在PHP中实现自定义会话处理?Apr 24, 2025 am 12:16 AM

在PHP中实现自定义会话处理可以通过实现SessionHandlerInterface接口来完成。具体步骤包括:1)创建实现SessionHandlerInterface的类,如CustomSessionHandler;2)重写接口中的方法(如open,close,read,write,destroy,gc)来定义会话数据的生命周期和存储方式;3)在PHP脚本中注册自定义会话处理器并启动会话。这样可以将数据存储在MySQL、Redis等介质中,提升性能、安全性和可扩展性。

什么是会话ID?什么是会话ID?Apr 24, 2025 am 12:13 AM

SessionID是网络应用程序中用来跟踪用户会话状态的机制。1.它是一个随机生成的字符串,用于在用户与服务器之间的多次交互中保持用户的身份信息。2.服务器生成并通过cookie或URL参数发送给客户端,帮助在用户的多次请求中识别和关联这些请求。3.生成通常使用随机算法保证唯一性和不可预测性。4.在实际开发中,可以使用内存数据库如Redis来存储session数据,提升性能和安全性。

您如何在无状态环境(例如API)中处理会议?您如何在无状态环境(例如API)中处理会议?Apr 24, 2025 am 12:12 AM

在无状态环境如API中管理会话可以通过使用JWT或cookies来实现。1.JWT适合无状态和可扩展性,但大数据时体积大。2.Cookies更传统且易实现,但需谨慎配置以确保安全性。

您如何防止与会议有关的跨站点脚本(XSS)攻击?您如何防止与会议有关的跨站点脚本(XSS)攻击?Apr 23, 2025 am 12:16 AM

要保护应用免受与会话相关的XSS攻击,需采取以下措施:1.设置HttpOnly和Secure标志保护会话cookie。2.对所有用户输入进行输出编码。3.实施内容安全策略(CSP)限制脚本来源。通过这些策略,可以有效防护会话相关的XSS攻击,确保用户数据安全。

您如何优化PHP会话性能?您如何优化PHP会话性能?Apr 23, 2025 am 12:13 AM

优化PHP会话性能的方法包括:1.延迟会话启动,2.使用数据库存储会话,3.压缩会话数据,4.管理会话生命周期,5.实现会话共享。这些策略能显着提升应用在高并发环境下的效率。

什么是session.gc_maxlifetime配置设置?什么是session.gc_maxlifetime配置设置?Apr 23, 2025 am 12:10 AM

thesession.gc_maxlifetimesettinginphpdeterminesthelifespanofsessiondata,setInSeconds.1)它'sconfiguredinphp.iniorviaini_set().2)abalanceIsiseededeedeedeedeedeedeedto to to avoidperformance andununununununexpectedLogOgouts.3)

您如何在PHP中配置会话名?您如何在PHP中配置会话名?Apr 23, 2025 am 12:08 AM

在PHP中,可以使用session_name()函数配置会话名称。具体步骤如下:1.使用session_name()函数设置会话名称,例如session_name("my_session")。2.在设置会话名称后,调用session_start()启动会话。配置会话名称可以避免多应用间的会话数据冲突,并增强安全性,但需注意会话名称的唯一性、安全性、长度和设置时机。

See all articles

热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

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。