【问题标题】:Weird behaviour of rename() in PHPPHP 中 rename() 的奇怪行为
【发布时间】:2012-03-04 15:42:36
【问题描述】:

我的 php.ini 有一个奇怪的问题。每当我尝试使用 rename() 移动文件时,不仅文件没有移动,而且应该复制到的目录以及其中的所有文件都被删除。原代码为:

rename('temp.odt', 'tmp/report.odt');

但我已经尝试过其他路径分隔符,例如

rename('temp.odt', 'tmp\report.odt');

rename('temp.odt', 'tmp\\report.odt');

rename('temp.odt', 'tmp' . DIRECTORY_SEPARATOR . 'report.odt');

rename('C:\wamp\www\zaiko\temp.odt', 'C:\wamp\www\zaiko\tmp\report.odt');

一切都无济于事。代码来自我正在开发的系统中使用的第 3 方模块。

检查点很好:

  1. 当前目录中确实存在文件“temp.odt”;
  2. 目录“tmp”确实存在,并且其中有几个文件。而且它不是只读的。
  3. 目标文件尚不存在(实际文件名有时间戳,为简单起见,我在这里缩小了)

运行 rename() 后,'temp.odt' 文件在其原始位置完好无损,而文件夹 'tmp' 以及其中的所有内容都消失。发出以下警告:

( ! ) 警告:rename(temp.odt,tmp\report.odt) [function.rename]:系统找不到指定的路径*。 (代码:3)在 C:\wamp\www\zaiko\modules\mod_deliver.php 第 192 行

*翻译自葡萄牙语

运行:Apache 2.2.17 和 PHP 5.3.5 在 Windows XP 和 NTFS 上


编辑:

刚刚找到问题的原因。事实证明,应用程序使用的模块反过来又使用了一个压缩库;此库使用与应用程序使用的名称完全相同的临时文件夹。

它必须使用某种缓存,这可以解释为什么错误没有出现 100% 次。

通过将“tmp”文件夹的名称更改为其他名称解决了问题。

感谢大家的宝贵时间,也很抱歉用这么愚蠢的事情打扰你们,事实证明,这与我最初的猜测完全无关,因此也与提出的问题无关。

【问题讨论】:

  • 如果将文件复制到新位置然后删除原始文件会怎样?
  • 你能把模块的代码贴在某个地方吗?至于php.net上的cmets,其他人没有这个问题。 Bugtracker 告诉 rename 不会覆盖 WinXP 上的现有文件,但这与您描述的问题不同。也许,某处有清理“tmp”目录的代码?
  • 可能是调用 rename() 时文件句柄(用于原始文件)尚未释放?鉴于该项目运行所在机器的特性,我倾向于认为这是问题所在。
  • 您是否尝试过使用realpath()
  • @SérgioDomingues 嗯,这可能是可能的。所以is_writable 在这里会有所帮助,我想。

标签: php windows file rename


【解决方案1】:

PHP.net 上的示例告诉您确切的操作 - 使用文件的根路径 - 通常可以通过使用 $_SERVER['DOCUMENT_ROOT'] 来获得(但这只会进入 htdocs/public_html 目录 - 您需要指定其余的)或手动输入路径(但尽量避免这种情况)。

<?php
rename("/tmp/tmp_file.txt", "/home/user/login/docs/my_file.txt");
?>

猜测一下,以下应该可以工作(假设这是您的路径)- 这还检查您的文件是否确实存在以便可以重命名- 您需要首先确保 tmp/ 确实存在,但是如果没有,你会弹出一个错误:

<?php

$root = getcwd().DIRECTORY_SEPARATOR; // Obtain the current working dir
$srcpath = $root."temp.odt";          // The file you want to rename
$destpath = $root."tmp/report.odt";   // Where you want to rename the file to

// make sure file exists and its movable
if(is_writable($srcpath)){
    // if it exists, rename it
    rename($srcpath, $dstpath);
    echo "File was renamed!";
} else {
    echo "It seems that the specified file doesn't exist!";
}
?>

您使用反斜杠转义字符 - 始终使用正斜杠(我知道这是在单引号内,这没关系,但如果您使用双引号,那么您会想知道出了什么问题)!

【讨论】:

  • 单引号字符串中的反斜杠只能自行转义 (\\ ) 或单引号 \'。但是正斜杠是首选,是的。
  • 我什么都试过了。使用指示的配置,它仅在某些时候有效。
  • @SérgioDomingues 它怎么只能“有时”工作?也许您需要先检查文件是否确实存在 - 请稍后查看我的编辑...
  • 我知道,这很奇怪。只包括一个检查,当 rename() 被调用时文件确实存在。
  • 我现在的猜测是,在调用 rename() 或 copy() 之前,其他东西可能正在擦除目录。现在要仔细检查模块中的代码——我确信我自己的代码除了这个函数调用之外不会触及那个目录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
  • 2013-08-09
  • 2021-11-21
  • 2018-05-20
  • 2012-01-07
  • 1970-01-01
相关资源
最近更新 更多