php - 'unlink',执行函数时权限被拒绝错误[exec]

标签 php

这是文件test1.php:

 <?php    
    set_time_limit(0);
    for($i= 1;$i<5000 ;$i++){

        $comm_sjis = "echo 'test'";
        $result = exec($comm_sjis);

    }
    unset($result);
    echo 'ok';

这是文件test2.php:

<?php

set_time_limit(0);

function write_txt($str)
{
    $filepath = 'E:/temp/test.xml';
    if (($fp = @fopen($filepath, "a")) === false) {
        return;
    }

    if (!flock($fp, LOCK_EX)) {
        @fclose($fp);
        return;
    }

    if (fwrite($fp, $str . "\n") === false) {
        @flock($fp, LOCK_UN);
        @fclose($fp);
        return;
    }

    if (!fflush($fp)) {
        @flock($fp, LOCK_UN);
        @fclose($fp);
        return;
    }

    if (!flock($fp, LOCK_UN)) {
        @fclose($fp);
        return;
    }

    if (!fclose($fp)) {
        return;
    }
}

for($i= 1;$i<100 ;$i++){

    write_txt('test');  
    unlink('E:/temp/test.xml');
}
echo 'ok';

如果我在 test1.php 运行时运行文件 test2.php,将会发生错误:

Warning: unlink(E:/temp/test.xml): Permission denied in C:\xampp\htdocs\test2.php on line 45

当我只运行test2.php,而没有运行test1.php时,不会出现这个错误。 为什么 unlink 在执行函数时会出现Permission denied 错误?

我在 Windows 7 上使用 XAMPP 3.2 与 php 5.6。

最佳答案

您正在消除 fopen 中的错误,这意味着如果在任何时候文件无法打开(例如,可能是因为 XAMPP 中达到了内存限制),您将在你的脚本中无法知道(你可以在你的日志中查看)。

来自PHP Manual :

bool unlink ( string $filename [, resource $context ] )

Deletes filename. Similar to the Unix C unlink() function. An E_WARNING level error will be generated on failure.

unlink 删除文件。这意味着如果您的文件无法使用 fopen 打开,并且您还没有创建它,那么它很可能不存在。尝试取消链接一个不存在的文件将导致错误。

一个简单的解决方案是同时消除 unlink 上的错误。

@unlink('E:/temp/test.xml');

这样,如果您的函数无法写入文件,它将优雅地失败。另一种选择是在尝试取消链接之前检查文件是否存在。

$file = 'E:/temp/test.xml';
if (file_exists($file)) {
    error_log(‘could not write file’);
    unlink($file);
}

在这种情况下,我最喜欢的选择可能是使用 Exceptions。当您无法打开或解锁文件时,抛出一个Exception。您可以在尝试 unlink 之前捕获它、记录问题并打破循环。

这应该可以帮助您调试正在发生的事情。

例子: 命名空间测试;

class FileException extends \Exception { }
class UnlockFailedException extends FileException { }

function write_txt($str)
{
    $filepath = 'E:/temp/test.xml';
    if (($fp = @fopen($filepath, "a")) === false) {
        throw new FileException('Could not open file');
    }

    if (!flock($fp, LOCK_EX)) {
        @fclose($fp);
        return;
    }

    if (fwrite($fp, $str . "\n") === false) {
        @flock($fp, LOCK_UN);
        @fclose($fp);
        return;
    }

    if (!fflush($fp)) {
        @flock($fp, LOCK_UN);
        @fclose($fp);
        return;
    }

    if (!flock($fp, LOCK_UN)) {
        @fclose($fp);
        throw new UnlockFailedException('Unable to unlock file.');
    }
    /** 
     * This doesn't do anything
     * if (!fclose($fp)) {
     *     return;
     * }
     */
    fclose($fp);
}

然后:

$msg = 'ok';
for($i= 1;$i<100 ;$i++){
    try {
        write_txt('test');  
        unlink('E:/temp/test.xml');
    } catch (FileException $e) {
        error_log($e->getMessage());
        $msg = 'errors detected';
    }
}
echo $msg;

通过添加异常处理,您可以自行调试此类行为并找到问题的根本原因。

一些最后的说明:

我运行的是 Linux,所以在 Windows 7 XAMPP 机器上测试这个行为对我来说并不容易。但是,我怀疑这是因为系统由于 I/O 资源有限而锁定。请注意,根据手册,Windows 对该文件放置了一个强制 锁(而在 Linux 中该锁是建议性的)。在有限资源系统上以大规模循环运行 flock 并在大规模循环中运行 echo 可能会导致资源失败。如果你打算在生产中运行这样的东西,你不会经常遇到它,但你仍然需要考虑它。异常处理和错误日志记录可以确保当文件不起作用时您将有足够的数据进行调试。

假设 unlink 是问题所在根本不是一个安全的假设。

如前所述,取消链接或检查文件是否存在将使此错误消失。

关于php - 'unlink',执行函数时权限被拒绝错误[exec],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47524016/

相关文章:

PHP奇怪的按位运算符对字符串的影响

php - 如何在 Laravel 中求和嵌套关系属性?

javascript - 如何使用多个验证码获取验证码值?

php - 在Moodle中使用rest api创建测验

php - 多个图像上传到不同的列php mysql

php - MySQL和PHP高级产品销售: check multiple fields

php - SSO - 使用 Apache 获取 AD 用户名

php - 那么如何使用 mysqli $driver->report_mode 呢?

php - CodeIgniter - 从 n-2-n 关系表中获取并显示数据

php - 如果变量的语句错误