PHP Cookbook读书笔记 – 第23章文件

概述

文件是在web应用中经常会碰到的一个部分,本章主要包括如何在PHP中打开、关闭和操纵文件,以及在打开文件后能够对文件做哪些处理等内容。

创建或打开一个本地文件

可以用fopen()函数打开/创建一个本地文件

<?php
$fh = fopen('file.txt','rb') or die("can't open file.txt: $php_errormsg");
?>

fopen函数的第二个参数指定了打开该流的访问类型:

模式可读?可写?文件指针截断?创建?说明
r 开始 只读打开
r+ 开始 读写方式打开
w 开始 写入方式打开
w+ 开始 读写方式打开
a 结尾 写入方式打开,追加
a+ 结尾 读写方式打开,追加
x 开始 写入方式打开,如果文件存在返回false,并产生一个警告信息
x+ 开始 创建并以读写方式打开,同上存在返回false,并产生一个警告信息

文件操作需要考虑其操作系统,在不同的操作系统下的某些文件操作是不一样的,例如:在Unix系统中新行用\n,Windows中是\r\n,而Macintosh中则是\r。

除上面这些外,还有b表示以二进制方式打开文件(默认是ASCII形式),以二进制形式打开文件可以在不同操作系统中具有很好的移植性,故官方手册中强烈建议使用二进制模式打开文件。

另外windows下还提供了一个t用来透明转换\n为\r\n。官方有一次强烈建议为移植性考虑,重写那些依赖于t模式的代码,改为正确的结束符并改成b模式

打开远程文件

打开远程文件也可以用fopen()函数,操作方法和本地文件差不多,但有需要注意的一点是操纵远程文件需要php.ini中的allow_url_fopen设置为on。下面分别列举了打开ftp和http打开一个远程txt文件:

<?php
$fh = fopen('ftp://username:password@ftp.example.com/pub/Index','r');
$fh = fopen('http://username:password@www.example.com/robots.txt','r');
?>

读取整个文件内容到字符串

使用file_get_contents()方法可以一次将一整个文件的内容加载到一个变量中去。但如果是要将整个文件内容输出可以选择fpassthru()或者readfile()函数。(对于图片文件的显示等也适用)

按行读取文件

可以使用fgets()函数按行读取文件

$lines = 0;

if ($fh = fopen('orders.txt','r')) {
  while (! feof($fh)) {
    if (fgets($fh)) {
      $lines++;
    }
  }
  fclose($fh);
}
print $lines;

按指定字节数读取文件

可以使用fread()函数按指定字节数读取文件

$handle = fopen ("http://www.example.com/", "rb");
$contents = "";
while (!feof($handle)) {
  $contents .= fread($handle, 1024);
}
fclose($handle);

例子中每次按1M字节大小读取文件远程文件

随机化处理文件中的所有行

$lines = file('quotes-of-the-day.txt');
$lines = shuffle($lines);

读取配置文件

可以用parse_ini_file()函数来读取类似php.ini格式的文件,例如

<?php
$config = parse_ini_file('/etc/example.ini');
?>

example.ini配置文件内容如下:

; PHYSICAL FEATURES

eyes=brown

hair=brown

glasses=yes

; OTHER FEATURES

name=Susannah

likes=monkeys,ice cream,reading

返回的数组如下

<?php
Array
(
	[eyes] => brown
	[hair] => brown
	[glasses] => 1
	[name] => Susannah
	[likes] => monkeys,ice cream,reading
)
?>

如果给parse_ini_file()增加个参数,将得到不同的结果数组

<?php
$config = parse_ini_file('/etc/example.ini',1);
?>

得到的$conf如下:

Array
(
    [physical] => Array
        (
            [eyes] => brown
            [hair] => brown
            [glasses] => 1
        )

    [other] => Array
        (
            [name] => Susannah
            [likes] => monkeys,ice cream,reading
        )

)

不通过临时文件来修改文件

通过file_get_contents()来读取文件内容,修改后,通过file_put_contents()函数回写到文件中去

$contents = file_get_contents('pickles.txt');
$contents = strtoupper($contents);
file_put_contents('pickles.txt', $contents);

同时写入到多个文件句柄

function pc_multi_fwrite($fhs,$s,$length=NULL) {
  if (is_array($fhs)) {
    if (is_null($length)) {
      foreach($fhs as $fh) {
        fwrite($fh,$s);
      }
    } else {
      foreach($fhs as $fh) {
        fwrite($fh,$s,$length);
      }
    }
  }
}

$fhs['file'] = fopen('log.txt','w') or die($php_errormsg);
$fhs['screen'] = fopen('php://stdout','w') or die($php_errormsg);

pc_multi_fwrite($fhs,'The space shuttle has landed.');

调用shell命令

如果想通过PHP调用shell命令并获取输出可以通过popen()函数实现,代码如下:

$ph = popen('/sbin/route','r') or die($php_errormsg);
while (! feof($ph)) {
    $s = fgets($ph)            or die($php_errormsg);
}
pclose($ph)                    or die($php_errormsg);

锁定文件

通过flock()对文件执行劝告式锁定,可选择排他锁或共享锁,排他锁意味着每次只能由一个进程控制。共享锁意味着文件每次可能由多个进程控制。根据其特性可知,在写入文件之前应使用排他锁,在读取文件前应使用共享锁。

读写压缩文件

使用compress.zlibcompress.bzip2扩展流封装程序和标准文件函数可以读写gzip或zip文件。

//读取本地的gzip文件
$fh = fopen('compress.zlib://lots-of-data.gz','r') or die("can't open: $php_errormsg");
while ($line = fgets($fh)) {
    // $line is the next line of uncompressed data
}
fclose($fh) or die("can't close: $php_errormsg");

//读取远程的bzip2压缩文件
$fp = fopen('http://www.example.com/something-compressed.bz2','r');
stream_filter_append($fp, 'bzip2.uncompress');
while (! feof($fp)) {
    $data = fread($fp);
    // do something with $data;
}
fclose($fp);
posted @ 2011-11-19 11:11  涂文瀚  阅读(618)  评论(0编辑  收藏  举报
foot