路径和权限问题导致fopen() 创建和写入文件失败

本人一直使用的是asp和.net环境,php比较少使用。如果用asp或asp.net来进行文件操作,我还是比较有经验的。今天由于需要,我得在php环境下做一次文件的读写操作,这对于我来说还是第一次。

虽然在写程序时信心十足,但是当运行起来时却发现没那么简单。

路径问题导致fopen() 创建和写入文件失败

首先是在本地测试程序,程序如下:

<?php
$fileDir = ‘/phpDemo/fopen.txt’;
$str =’testing’;
$h = fopen($fileDir,’w+’);
 if(fwrite($h,$str))
 {
  echo ‘文件写入成功’;
 }
 fclose($h);
?>

但却没有执行成功,提示“failed to open stream: No such file or directory ”,即是文件路径不对,问题应该是这句

$fileDir = ‘/phpDemo/fopen.txt’;

我改为

$fileDir = ‘../phpDemo/fopen.txt’;

终于成功了。

不过,上述的相对路径的写法,不是我的习惯,我比较喜欢用绝对路径。查了下,我发现可以用如下方式来写文件的路径:

$RootDir = $_SERVER[‘DOCUMENT_ROOT’];
$fileDir = $RootDir.’\phpDemo\fopen.txt’;

这个方法是首先定义了根目录,再写出文件的绝对路径,更通用,也方便管理。

不可忽视的权限问题

本地测试通过,原以为上传到空间后会很顺利,谁知竟然不成功!是什么新的问题又出现了?

根据提示,是没有权限。

原来,空间里的目录写权限没有打开。这个已经不是php的问题了。

知识扩充

fopen

fopen — 打开文件或者URL。

格式:

fopen(string $filename , string $mode)

fopen() 将 filename 指定的名字资源绑定到一个流上。

filename可以是一个本地文件,也可以是一个URL。

如果filename 指定的是一个本地文件,该文件必须是 PHP 可以访问的,并且文件访问权限允许该访问。

如果filename 指定的是一个URL,PHP 将检查并确认 allow_url_fopen 已被激活。如果关闭了,PHP 将发出一个警告,而 fopen 的调用则失败。(fopen()和file_get_contents()打开URL获得网页内容的用法区别

fopen() 中 mode 的可能值列表

mode 说明
‘r’ 只读方式打开,将文件指针指向文件头。
‘r+’ 读写方式打开,将文件指针指向文件头。
‘a’ 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
‘a+’ 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
‘w’ 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
‘w+’ 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。

返回值

成功时返回文件指针资源(如何调用fopen()打开的资源),如果打开失败,本函数返回 FALSE。

错误/异常

如果打开失败,会产生一个 E_WARNING 错误。可以通过 @ 来屏蔽错误

有时我们会看到,fopen中mode值包含一个“b”字符,例如“wb”,这是怎么回事呢?

这是因为:

不同的操作系统家族具有不同的行结束习惯。当写入一个文本文件并想插入一个新行时,需要使用符合操作系统的行结束符号。基于 Unix 的系统使用 \n 作为行结束字符,基于 Windows 的系统使用 \r\n 作为行结束字符,基于 Macintosh 的系统使用 \r 作为行结束字符。

如果写入文件时使用了错误的行结束符号,则其它应用程序打开这些文件时可能会表现得很怪异。

Windows 下提供了一个文本转换标记(’t’)可以透明地将 \n 转换为 \r\n。与此对应还可以使用 ‘b’ 来强制使用二进制模式,这样就不会转换数据。要使用这些标记,要么用 ‘b’ 或者用 ‘t’ 作为 mode 参数的最后一个字符。

默认的转换模式依赖于 SAPI 和所使用的 PHP 版本,因此为了便于移植鼓励总是指定恰当的标记。如果是操作纯文本文件并在脚本中使用了 \n 作为行结束符,但还要期望这些文件可以被其它应用程序例如 Notepad 读取,则在 mode 中使用 ‘t’。在所有其它情况下使用 ‘b’。

在操作二进制文件时如果没有指定 ‘b’ 标记,可能会碰到一些奇怪的问题,包括坏掉的图片文件以及关于 \r\n 字符的奇怪问题。

为移植性考虑,强烈建议在用 fopen() 打开文件时总是使用 ‘b’ 标记。