Home  >  Article  >  Backend Development  >  How to apply PHP Wrapper on SAE_php skills

How to apply PHP Wrapper on SAE_php skills

WBOY
WBOYOriginal
2016-05-16 19:53:101055browse

This article describes how to apply PHP Wrapper on SAE. Share it with everyone for your reference, the details are as follows:

1. What is PHP Wrapper

Since PHP 4.3, PHP has begun to allow users to customize URL style protocols through stream_wrapper_register(). When users use file system functions such as fopen() and copy() to operate the encapsulated protocol, PHP will call the corresponding function in the class provided when registering the protocol.
An example is given in the PHP manual, which registers the VariableStream class as the var:// protocol. Through this protocol, users can use file system functions to directly read and write global variables. For example, users can read and write $GLOBALS['foo'] via "var://foo".

2. Why does SAE need PHP Wrapper

For performance and security reasons, local file reading and writing and external data capture are disabled on the SAE platform. Accordingly, we provide corresponding services to do the same thing.

Since the interface of the new service is different from the interface of PHP itself, programs developed specifically for our platform will certainly not have problems, but a large number of existing programs and open source projects will face complicated migration work. After using PHP Wrapper to encapsulate the interface of our service, users can more easily migrate the program to the SAE platform.

3. How to write PHP Wrapper

To encapsulate a protocol through PHP Wrapper, first, we need to write a streamWrapper class. The class name can be customized. The format of the class is:

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

Description of each method in the class:

streamWrapper::__construct — constructor, only called before stream_open
streamWrapper::dir_closedir — Close the directory handle and respond to the closedir() function
streamWrapper::dir_opendir — Open the directory handle and respond to the opendir() function
streamWrapper::dir_readdir — Read entries from a directory handle, responding to the readdir() function
streamWrapper::dir_rewinddir — rewind directory handle, responds to the rewinddir() function
streamWrapper::mkdir — Create a directory and respond to the mkdir() function
streamWrapper::rename — Directory or file rename, responds to the rename() function
streamWrapper::rmdir — delete a directory and respond to the rmdir() function
streamWrapper::stream_cast — Retrieve basic resources and respond to the stream_select() function
streamWrapper::stream_close — close the resource and respond to the fclose() function
streamWrapper::stream_eof — Checks whether the file pointer is already at the end of the file, responding to the feof() function
streamWrapper::stream_flush — Clear the output cache and respond to the fflush() function
streamWrapper::stream_lock — consult file lock, respond to flock() function
streamWrapper::stream_open — Open a file or URL as a stream, responding to the fopen() function
streamWrapper::stream_read — Read content from the stream and respond to the fread(), fgets() functions
streamWrapper::stream_seek — Locate the pointer in the stream, responding to the fseek() function
streamWrapper::stream_set_option — Change stream settings
streamWrapper::stream_stat — Retrieve file resource information and respond to the fstat() function
streamWrapper::stream_tell — Retrieve the position of the pointer in the stream, responding to the ftell() function
streamWrapper::stream_write — writes content to the stream, responding to the fwrite(), fputs() functions
streamWrapper::unlink — delete files and respond to the unlink() function
streamWrapper::url_stat — Retrieve file information and respond to all stat() related functions, such as file_exists(), is_dir(), is_file(), filesize(), fileinode(), etc.

Please refer to the PHP manual for detailed instructions: http://cn2.php.net/manual/en/class.streamwrapper.php

After writing the streamWrapper class, use stream_wrapper_register () to register this class into the Wrapper and you can start using it. The function usage method is:

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

For example:

stream_wrapper_register("saemc", "SaeMemcacheWrapper");

Since the SAE platform does not support writing operations to local files, some open source projects such as Smarty that need to write files locally cannot be used directly on the SAE platform. With saemc Wrapper, users can use Smarty The compiled templates are saved in MC, making it easy to migrate Smarty to the SAE platform.

In the attachment, we provide you with the implementation code of Memcache Wrapper on SAE. You can download this attachment for testing.

Before testing, you need to start a Memcached service with port 22222 locally:

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

Then use the following code to test:

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

Output results of the test page:

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!

The Memcache Wrapper we provide does not implement some methods of directory operations and Memcache's Timeout. You can refer to the PHP manual to try to implement directory operations, or make this Wrapper support Memcache's Timeout through context.

In addition, you can go to the following address to view the source code of sae_include in SAE Stdlib, which also includes the implementation of the saestor Wrapper that we encapsulate for the Storage service and the http Wrapper that re-encapsulates the Fetchurl service:

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

4. Some things to note when writing Wrapper

1. Constructor

The streamWrapper class is special in that its constructor is not called every time. It will only be called when your operation triggers a stream_open related operation, such as if you use file_get_contents(). And when your operation triggers a function that has nothing to do with stream, such as file_exists will trigger the url_stat method, the constructor will not be called at this time.

2. Read implementation

There are concepts such as Position and Seek in Wrapper, but many services actually read all the data at once. This can be read back at once during stream_open and put into an attribute. Later, it can be directly used for seek and tell. Just operate the data stored in the attributes.

3. Additional write implementation

There are many services that write all data at once and do not support the append write function (such as Memcache). This requires us to implement append writes ourselves in Wrapper. You can read the entire value at once, append the data that needs to be written after the read content, and then write it back at once.

However, the performance of this append-write implementation will be relatively poor, especially when the content is large in size. Reading all the content at once will consume a lot of resources, so in some services we have to abandon support for append-write. .

4. Implementation of url_stat

In the implementation of the streamWrapper class, the implementation of url_stat is a difficult point. url_stat must be implemented correctly in order for functions such as is_writable and is_readable to query file metainformation to work properly.

And we need to fake these values ​​for our virtual device. Taking mc as an example, we will give you some reference data:

url_stat should return an array, divided into 13 items, with the following content:

dev device number - just write 0;
ino inode number - just write 0;
mode file mode - this is the permission control symbol of the file, which will be explained in detail later;
nlink link - just write 0;
uid uid - It can be obtained using posix_get_uid on Linux, and it is 0 on Windows;
gid gid - It can be obtained using posix_get_gid on Linux, and it is 0 on Windows;
rdev device type - has a value when it is an inode device;
size - file size;
atime - last read time format is unix timestamp;
mtime - last writing time;
ctime - Creation time;
blksize - blocksize of filesystem IO just write zero;
blocks - number of 512-byte blocks allocated just write zero;

The value of mode must be written correctly:

If it is a file, its value is:

0100000 file permissions, such as 0100000 0777.

If it is a directory, its value is:

040000 directory permissions, such as 0400000 0777.

5. About stat caching

PHP will cache the meta information of the file during the execution of the same page.
According to the description of the clearstatcache() method in the PHP documentation: when using stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link( ), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype(), or fileperms() method to query file information, PHP will cache to improve performance. The clearstatcache() method can be used to clear this cache. When unlink(), the stat cache will be automatically cleared.

In fact, PHP will only clear the stat cache when unlink, rename and rmdir operations are performed on local files, but will not clear the stat cache when unlink, rename and rmdir operations are performed through other wrappers. Therefore, when writing the wrapper, we have to clear the stat cache ourselves through clearstatcache() in unlink and other methods.

Click hereto download the attachment.

Readers who are interested in more PHP-related content can check out the special topics on this site: "php curl usage summary", "php socket usage summary", "PHP Summary of network programming skills ", "Introduction to PHP basic syntax tutorial ", "Summary of PHP operating office document skills (including word, excel, access, ppt) ", "php date and time usage summary", "php object-oriented programming introductory tutorial", "php string (string) usage summary", " PHP mysql database operation introductory tutorial " and " PHP common database operation skills summary "

I hope this article will be helpful to everyone in PHP programming.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn