2013-03-14 68 views
2

使用file_put_contents在相对定位的文件夹中创建并填充文件。为什么使用include路径时file_put_contents和fopen无法创建?

注意到一些与包含路径和文件创建有关的奇怪怪癖。

简短版:查看迭代2和迭代3.为什么后者在前者失败时工作?

迭代1

file_put_contents('../../public/remixes/screenshots/test.txt', $data); 

这一切正常。

迭代2

但是,我在这个模块的“根”的公共目录,并希望更直接地引用它使用预先设定的include路径。例如:

echo(get_include_path()); // this outputs "../../" 
file_put_contents('public/remixes/screenshots/test.txt', $data, FILE_USE_INCLUDE_PATH); 

错误:“未能打开流:没有这样的文件或目录”

迭代3

精细,PHP包括路径是靠不住的,所以让我们做奇怪的事情,走着瞧吧。我会尝试使用fopen来实际创建文件。

fopen('../../public/remixes/screenshots/test.txt', 'w'); 
file_put_contents('public/remixes/screenshots/test.txt', $data, FILE_USE_INCLUDE_PATH); 

这又起作用了...... WAT?

迭代4

有趣;我有做一个的fopen第一次OK,但我想它使用include路径也:

fopen('public/remixes/screenshots/test.txt', 'w', 1); 
file_put_contents('public/remixes/screenshots/test.txt', $data, FILE_USE_INCLUDE_PATH); 

这产生了两个“未能打开流”的错误。情况越来越糟糕。

迭代5

我就饶了我自己的包含路径“神奇”和它直接建立路径

file_put_contents(get_include_path().'public/remixes/screenshots/test.txt', $data); 

这个工作,而且是最好的,我可以得到。

结论

我在想为什么迭代2迭代时成功3失败。

迭代4意味着它是一个的fopen问题(因为file_put_contents显然只是一个包装了的fopen/FWRITE/FCLOSE)

的思考?

+0

而不是使用标志,如果你只使用1会发生什么?可能是因为国旗没有设置。 – kennypu 2013-03-14 04:53:25

+0

唉 - 没有区别;尽管请注意迭代4在没有标志的情况下在fopen上失败。 – slifty 2013-03-14 05:00:42

+1

看看[这个评论](http://www.php.net/manual/en/function.file-put-contents.php#62641)。另外,在PHP官方文档中,它指出当指定use_inlude_path时,它会在include_path中搜索文件**,所以它看起来像文档是相当准确的... – Passerby 2013-03-14 05:16:48

回答

0

刚花了一些时间检查the PHP source

的fopen解析为/main/streams/streams.c

2007线饶你到达该点的堆栈。

代码(行2026)的以下部分处理FILE_USE_INCLUDE_PATH参数:

if (options & USE_PATH) { 
    resolved_path = zend_resolve_path(path, strlen(path) TSRMLS_CC); 
    if (resolved_path) { 
     path = resolved_path; 
     /* we've found this file, don't re-check include_path or run realpath */ 
     options |= STREAM_ASSUME_REALPATH; 
     options &= ~USE_PATH; 
    } 
} 

事实上,如路人在他的评论中指出的这个逻辑将试图解析路径。如果路径正确解析(到现有文件),则原始路径字符串将替换为“包含”路径。

如果包含路径不指向现有文件,则原始路径不会被替换,并且include_path被完全忽略。

文档并没有说明这是预期的行为,但正如在这个答案的评论中指出的那样,这并不是那么疯狂。

神秘解决了。

+0

我认为这听起来“正确”,因为在include_path(尤其是'.')中可能有多条路径,所以如果use_include_path指向一个不存在的文件,PHP将不得不猜测哪条路径你更喜欢(如此创建文件),或完全否认你。我认为这里的否认可能听起来更合适。 – Passerby 2013-03-14 08:03:43

+0

周围的伟大点;我的声明应该修改为说“文档没有说明这应该是预期的行为” – slifty 2013-03-14 17:31:40

相关问题