// 两个特殊函数
popen()
// 说明: popen() 只向一个程序提供单向的 IO,可以只用 w 活 r 作为打开模式。当为一个程序打开流时,也可以叫做一个 管道,可以使用所有常规的文件函数来从该管道读取或者写入,并且使用 feof() 来检测文件是否还有为读取的数据
<?php
$fp = popen('ls -l /', 'r');
while( ! feof( $fp)){
echo fgets( $fp);
}
pclose( $fp);
// 读取根目录文件列表
?>
// popen() 有很大的限制,不能与打开的进程进行任何交互,这点可以用 proc_open() 来代替
// 通过 proc_open(),可以连接所有进程的输入和输出句柄到一个可以读取的管道,或者是可以在脚本中写入管道,或是一个文件。管道被当作文件句柄来处理,只不过不能同时针对读取和写入打开一个文件句柄。
proc_open()
resource proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd [, array $env [, array $other_options ]]] )
// 对函数声明的参数作下说明:
// $cmd: 要执行的命令(在 php 脚本中启动一个子进程)
// $descriptorspec: 索引数组,数组键表示描述符(描述针对输入或输出的一个文件处理器),键值代表 PHP 怎么传递这个文件处理器给子进程,0 代表标准输入,1 标准输出,2 标准错误
// 数组的每个元素可以是:
// * 一个描述管道的 数组 , 这个数组的第一个元素的管道的类型,第二个是给定管道的选项,有效的管道类型是: pipe{这时数组的第二个元素是 'r' 或 'w'}, file{这时数组的第二个元素是文件名字}
// * 一个代表文件处理器的流{eg, 打开的文件,socket, STDIN}
// 以上这几中情况在下面的例子中都包括了
<?php
$fin = fopen( 'readfrom', 'rb');
$fout = fopen( 'writeto', 'wb');
$desc = array( 0 => $fin, 1 => $fout);
$res = proc_open( 'php', $desc, $pipes);
if( $res){
proc_close( $res);
}
// 脚本为 php 启动一个解释器--一个子进程,子进程从 $fin 中读取数据交给 php 解释器处理,结果输出到 $fou
// readfrom 内容
// <?php
// echo 'hello world';
// ?>
// 程序运行后 writeto 的内容
// hello world
?>
<?php
$desc = array(
0 => array( 'pipe', 'r'),
1 => array( 'pipe', 'w'),
);
$res = proc_open( 'php', $desc, $pipes);
if( is_resource( $res)){
fputs( $pipes[0], '<?php echo "hello world" ?>');
fclose( $pipes[0]);
while( !feof( $pipes[1] )){
$line = fgets( $pipes[1]);
echo $line;
}
}
?>
<?php
$desc = array(
0 => array( 'pipe', 'r'),
1 => array( 'file', 'out.dat', 'w'),
2 => array( 'file', 'error.dat', 'w')
);
$res = proc_open( 'php', $desc, $pipes);
if( is_resource( $res)){
fputs( $pipes[0], '<?php echo "hello world"; ?>');
fclose( $pipes[0]);
proc_close( $res);
}
// 输入输出流
// 通过 php,可以把 stdin,stdout,stderr 作为文件来处理,可以使用 fopen() 调用的协议指定符来访问。对于程序的输入输出,这个指定符就是 php:// .
// 另外两个可用的 IO 流是 php://input 和 php://output
// 通过 php://input 可以读取原始的 POST 数据
<?php
$fout = fopen('php://stdout', 'w');
$fin = fopen( 'php://stdin', 'r');
echo "hello sir/n";
fputs( $fout, "please input your name:/n");
$name = fread( $fin, 2000);
echo "hello sir, your name is $name./n";
?>
// php://stdin php://input 是只读的
// php://stdout php://stderr php://output 是只写的
// 压缩流
// PHP 提供了一些于眼所函数相关的封装处理层,使用这些库的流支持,读取和写入一个 gzipped 的或 bzipped 的文件就像读取和写入一个常规文件一样。
// 协议指定符
// compress.zlib://filename.gz
// compress.bzip2://filename.bz2
// gzip 流比标准的 r, w, a, b , + 支持更多的模式指定符。这些附加的修饰符包括从 1 到 9 的压缩级别并且压缩方法 f 表示过滤或者 h 表示只是 huffman 压缩
<?php
set_include_path( get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/misc');
$bz_file = 'compress.bzip2://from.bz2';
$gz_file = 'compress.zlib://./misc/to.gz';
$fr = fopen( $bz_file, 'rb', TRUE);
$fw = fopen( $gz_file, 'wb1');
if( is_resource( $fr) && is_resource( $fw) ){
while( !feof( $fr) ){
$data = fread( $fr, 1024);
fwrite( $fw, $data);
}
fclose( $fr);
fclose( $fw);
}
?>