是rename()和unlink()异步函数吗?

时间:2011-12-17 23:17:09

标签: php ajax asynchronous filesystems

我有充分的理由相信函数rename()和unlink()都是异步的,根据我的理解,这意味着当函数被调用时,它们下面的代码在它完成文件系统上的过程之前会继续。这是我将在下面解释的互联网应用程序的一个问题,因为后来的代码依赖于这些变化已经在一成不变。那么,有没有办法使两者同步,以便代码阅读器在遇到这些函数时冻结,直到它的所有任务都完全在文件系统上执行?

以下是delete-image.php中的代码,该代码由ajax从另一个admin-images.php调用(后者不会显示):

`

    foreach ($dirScan as $key => $value) {
        $fileParts = explode('.', $dirScan[$key]);
        if (isset($fileParts[1])) {
            if ((!($fileParts[1] == "gif") && !($fileParts[1] == "jpg")) && (!($fileParts[1] == "png") && !($fileParts[1] == "jpg"))) {
                unset($dirScan[$key]);
            }
        } else {
            unset($dirScan[$key]);
        }
    }
    $dirScan = array_values($dirScan);

    // for thumbnail
    $file = 'galleries/' . $currentGal . '/' . $currentDir . "/" . $dirScan[$imageNum - 1];
    unlink($file);      
    for ($i = ($imageNum - 1) + 1; $i < count($dirScan); $i++) {
        $thisFile = 'galleries/' . $currentGal . '/' . $currentDir . '/' . $dirScan[$i];
        $thisSplitFileName = explode('.', $dirScan[$i]);
        $newName = 'galleries/' . $currentGal . '/' . $currentDir . "/" . ($thisSplitFileName[0] - 1)  . "." . $thisSplitFileName[1];
        rename($thisFile, $newName);
    }

    // for large image
    $fileParts = explode('.', $dirScan[$imageNum - 1]);
    $file = 'galleries/' . $currentGal . '/' . $currentDir . "/large/" . $fileParts[0] . "Large." . $fileParts[1];
    unlink($file);
    for ($i = ($imageNum - 1) + 1; $i < count($dirScan); $i++) {
        $thisSplitFileName = explode('.', $dirScan[$i]);
        $thisFile = 'galleries/' . $currentGal . '/' . $currentDir . '/large/' . $thisSplitFileName[0] . "Large." . $thisSplitFileName[1];
        $newName = 'galleries/' . $currentGal . '/' . $currentDir . "/large/" . ($thisSplitFileName[0] - 1)  . "Large." . $thisSplitFileName[1];
        rename($thisFile, $newName);
    }

    sleep(1);
    echo 'deleted ' . $dirScan[$imageNum - 1] . " successfully!";

} else {
    echo "please set the post data";
} ?>`

此脚本返回完成的文本后,admin-images.php会触发一个新函数,该函数从这些重命名和修剪的文件中填充图像表。有时它显示旧的名称和假设要删除的文件,并且简单的页面刷新将其删除。这似乎表明上面的php脚本正在运行所有代码,并在完成文件系统操作之前将回显的文本吐出到主文件中(所有这些其他代码都很长且复杂,并且希望手头的讨论不必要)。

你会注意到,我已经尝试了一个sleep()函数来暂停php脚本,希望有时间完成。这是一种不愉快且有问题的做事方式,因为我必须花费大量时间来确保它每次都能正常工作,但我不希望用户等待的时间比她/他必须的要长。

4 个答案:

答案 0 :(得分:5)

请注意,文件系统通常使用缓存来减少负载。通常您不会注意到,但有时您需要清除缓存,如果您需要获取真实信息。如果您的问题与文件系统相关,请检查文件系统的配置。

PHP本身也使用缓存进行某些文件操作,所以也很清楚。

请参阅clearstatcache以清除PHP stat缓存。

请注意,这是一个“查看”问题,该文件实际上已在磁盘上删除,但PHP可能仍会将其返回(直到您清除缓存)。

答案 1 :(得分:2)

我认为他们异步,因为他们返回一个结果,告诉操作是否成功。

我认为问题的发生是因为在进行修改后运行scandir时,它可能正在使用内存中的“缓存”数据,而不是重新扫描文件系统。

答案 2 :(得分:0)

rename()不是,但unlink()在Windows上是异步的。

由于似乎无法等待挂起删除完成,this answer建议在删除文件之前重命名该文件。 PHP does not seem to do that,因此您可以假设它是异步的。

答案 3 :(得分:-1)

要使用任何文件操作,您需要使用$ _SERVER [“DOCUMENT_ROOT”]来完成这项工作。如果你不这样做..真正的操作不能正常工作。如果您使用的是Linux服务器,则需要为要执行文件操作的文件夹设置权限。

请注意,这两个操作都是同步的,它们不是异步的。它还取决于您使用的服务器类型或操作系统。