2011-03-01 466 views
12

作为应用程序日志记录的一部分,我试图打开本地文件,如果该文件尚不存在,要创建一个新文件。下面是我有:PHP fopen()不创建文件,如果它不存在

$path = '/home/www/phpapp/logs/myawesome_logfile.txt'; 
$f = (file_exists($path))? fopen($path, "a+") : fopen($path, "w+"); 
fwrite($f, $msg); 
fclose($f); 
chmod($path, 0777); 

我再次检查,而/logs目录chmod为0777,而我还跟它chown'ing到Apache的额外步骤:apache的好措施。尽管如此,当脚本打开文件时,它给了我一个警告,即文件不存在并且弹出。没有文件被创建。

我是否需要禁止fopen()警告才能让它创建文件?

+0

注意:如果'a +'无论出于何种原因追上我,我都会用'file_exists()'添加逻辑。 – 2011-03-01 21:10:28

+2

你真的想让你的路径从根开始吗?这不会是你的应用的根目录,那将是你系统的根目录。 – 2011-03-01 21:11:14

+0

为什么你认为错误抑制会帮助你打开一个文件? – 2011-03-01 21:28:57

回答

16

当您在PHP中使用路径时,上下文可能很重要。如果您在重定向上下文中使用urls - 那么根目录('/')引用您的域的根目录。链接文件或图像的路径以及include和require指令也是如此。

但是,当您处理文件系统命令(如fopen)时,根目录('/')是系统根目录。不是你的域根。

要解决此问题,请尝试给出要从系统根目录打开的日志文件的完整路径。例如:/var/www/phpapplication/logs/myLogFile.txt

或者您可以使用$_SERVER['DOCUMENT_ROOT'],如其他答案中所建议的那样访问服务器存储的文件根目录路径的值。 /var/www部分。

编辑澄清。

+0

“当你处理文件处理命令如fopen()时,php从根目录,而不是应用程序的根目录。”呃...不,当你在路径的开头加上一个'/'就是从根目录开始的。如果他把“phpapp/logs/myawesome_logfile.txt”从工作目录中检查,从上下文判断这也是错误的。 – Powerlord 2011-03-01 21:31:02

+0

某些时候,将/ in放在前面会引导您访问域的根目录 - 例如使用url重定向。上下文决定我们是在讨论根目录还是根域。但是,由于路径看起来相似,所以很容易混淆它们。 – 2011-03-01 21:33:56

+0

它正在获得完整路径。 (为了简洁起见,我在我的文章中删除了/ home/www /部分路径)。 – 2011-03-01 21:35:54

15

你试过吗?

$msg = "I'm a line that is a message.\n"; 
$path = $_SERVER['DOCUMENT_ROOT'] . '/logs/myawesome_logfile.txt'; 
$f = fopen($path, "a+"); 
fwrite($f, $msg); 
fclose($f); 
chmod($path, 0777); 

您正在使用的服务器可能让您只能在phpapp的目录及其子目录中工作。

+0

+1:DOCUMENT_ROOT几乎肯定是这里需要的修复程序。 – Powerlord 2011-03-01 21:30:37

1

您可以随时打开文件,只需要"a",它也会创建一个新文件。
无需做出条件。

但是,你的代码的主要问题是理解物理文件系统和虚拟网络服务器之间的差异,这已经完全解释了。

请注意,您应该提供您的问题与错误消息的确切副本。它包含了大量非常有用的信息,它不是一个誓言“我不会创建你的文件,走开!”但它是通过解释什么和为什么会出错。如果你自己不关心这些有用的信息,你必须提供给那些寻求帮助的人。

+0

没有涉及虚拟服务器,并且该脚本正在获取该文件的完整路径。我没有这个方便的错误,但是当我能得到它时我会发布它。 – 2011-03-01 21:41:22

+0

@b。即hollenbeck,那么错误信息会变得更加重要。 – 2011-03-01 21:43:50

0

文件的路径必须在服务器根目录下。我可以使用我想知道的文档中的 phpinfo() 方法来实现此目的。所以当你使用phpinfo()时你会看到一个信息文档。如果您发现 _SERVER [“SCRIPT_FILENAME”],您将看到文件的绝对路径。

我希望这可以帮助别人。

0

不要忘记确保SELinux不会阻止你。

[根@ yourbox]#audit2allow < /var/log/audit/audit.log
#============= httpd_t ========= =====
#!!!!这avc可以允许使用布尔'httpd_unified' 允许httpd_t httpd_sys_content_t:dir {写入add_name};
#!!!!这avc可以允许使用布尔'httpd_unified' 允许httpd_t httpd_sys_content_t:file {write create}; [根@ yourbox]#audit2allow -a -M my_httpd

注:

为了使这一揽子政策积极,执行:

semodule -i my_httpd.pp

[root @ yourbox]#semodule -i my_httpd.pp
[root @ yourbox]#systemctl restart httpd

2

我在UBUNTU 14.04中解决了这个问题的一种方法是右键单击文件所在的目录并将“其他”权限更改为“创建和删除文件”。

相关问题