1

我正在运行一个示例脚本并解决了这个特定问题。

脚本通过设置开始

 $docroot=$_SERVER['DOCUMENT_ROOT'];

对于写入文件,

@$fp = fopen("$docroot/../parts/partsorders.txt",'ab');

用来。但无论如何,这都无法写入文件。

经过一段时间的修补后,我将命令设置为

@$fp = fopen('$docroot/../parts/partsorders.txt','ab');

使用单引号而不是双引号,效果很好!

我的问题是,以前的双引号格式不是应该工作而不是单引号。这里发生了什么?

这是精简的代码,伙计们(假设该文件存在于服务器中):

    <?php
    $docroot=$_SERVER['DOCUMENT_ROOT'];
    $outputstring = "herpderp";
    ?>
    <html>
    <head>
    <title>Quotes</title>
    </head>
    <body>
    <?php
    @$fp=fopen("$docroot/../parts/partsorders.txt","ab");
    flock($fp, LOCK_EX);
    if(!$fp) {
        echo "<p><strong>Failed.</strong></p></body></html>";
        exit;
    }
    fwrite($fp,$outputstring,strlen($outputstring));
    flock($fp,LOCK_UN);
    fclose($fp);
    echo "<p>Order written.</p>";
    ?>
    </body>
    </html>
4

4 回答 4

2

PHP 中的单引号和双引号字符串之间存在差异。单引号字符串不会导致变量名的扩展,而双引号字符串会。见这里。为什么当你使用带有单引号字符串的变量名时你的代码工作对我来说没有意义。此外,在 fopen 命令前面使用是个坏主意@,它会阻止您看到错误输出。

于 2011-05-25T16:21:22.863 回答
2

双引号是应该$docroot为您评估的。单引号应该做的是尝试打开一个实际上$docroot在其路径中具有字符串的文件。做

@$fp = fopen($docroot . '/../parts/partsorders.txt','ab');

产生相同的结果?

你用@什么来抑制错误?在那种情况下,它应该在我认为的功能之前

$fp = @fopen($docroot . '/../parts/partsorders.txt','ab');

但是,当您试图在您的应用程序中查找错误时,请不要这样做。问题是您很可能会收到一个错误,即找不到文件而您只是没有注意到。

于 2011-05-25T16:22:34.503 回答
0

在我发表评论之后,我睡了一夜,并意识到fopen()可能实际上并没有使用/像realpath()(它期望设置所有段,即使是与最终规范化路径无关的段)。

它没有。

因此,打开文件的原因实际上相当简单:

'$docroot/../parts/partsorders.txt'

...读作“ 'parts'文件夹中的Pastorders.txt,该文件夹是在当前工作目录中的'$docroot'文件夹上方的文件夹中找到的文件夹”折叠到...

'parts/partsorders.txt'

...因为在不检查存在的情况下fopen()简单地消失了。(像做检查这样的功能,这让我很失望。)$docroot/..$docrootrealpath()

所以,你的文件实际上是在<current working directory>/parts/partsorders.txt. (由于您打开带有a标志的文件,如果它以前不存在,那么它肯定是在那里创建的。)

无论您$_SERVER['DOCUMENT_ROOT']包含什么,似乎都不是您想要的。此外,在某些设置中,你不能合理地..高于$_SERVER['DOCUMENT_ROOT']- 权限实际上不会让你。

如果没有完全设置该环境变量(如果有可能的话;但我认为即使没有设置也可以说明问题),那么路径就完全不同了:

"$docroot/../parts/partsorders.txt"

...变成:

"/../parts/partsorders.txt"

...它试图在根点 ( /) 之上建立层次结构,这当然是行不通的。

我建议回显或记录$_SERVER['DOCUMENT_ROOT']并查看它实际包含的内容,以及它是否是您所期望的。

可能值得寻找的是__DIR__(或在较旧的 PHP 版本中dirname(__FILE__)),它采用文件. 只要文件知道它在哪里,您就可以读出相对于其位置的文件。

于 2011-05-26T08:18:09.723 回答
0

更新 感谢 pinkgothic 的评论,首先是为了提供正确的术语,其次是为了指出这个答案是错误的。
我实验了shell试图扩展环境变量的理论,$docroot发现shell扩展在fopen().
我尝试了以下代码并收到此错误(我的主目录中有一个名为 test.txt 的文件)

$fp = fopen( '$HOME/test.txt', 'rb' );
//PHP Warning:  fopen($HOME/test.txt): failed to open stream: No such file or directory in php shell code on line 1

因此,除非 OP 有一些允许 shell 扩展的配置,否则fopen()我的回答是,正如我所说,不正确。


该字符串$docroot/../parts/partsorders.txt被直接发送到操作系统外壳。由于没有$docroot设置变量,它被一个空字符串替换,所以它与使用相同

@$fp = fopen('/../parts/partsorders.txt','ab');

/这是从文档根目录开始的绝对路径。

#run from shell (bash)
~$ echo $docroot/../parts/partsorders.txt
/../parts/partsorders.txt
于 2011-05-25T16:29:29.330 回答