Странное поведение rename () в PHP - PullRequest
6 голосов
/ 13 февраля 2012

У меня странная проблема с моим php. Всякий раз, когда я пытаюсь переместить файл с помощью 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');

все безрезультатно. Код взят из стороннего модуля, который используется в системе, над которой я работаю.

Очки хорошо проверены:

  1. Файл 'temp.odt' существует в текущем каталоге;
  2. Каталог 'tmp' существует, и в нем есть несколько файлов. Также это не только для чтения.
  3. Целевой файл еще не существует (фактическое имя файла имеет временную метку, я уменьшил его здесь для простоты)

После запуска rename () файл 'temp.odt' не поврежден в своем первоначальном расположении, в то время как папка 'tmp' исчезла , а также все внутри него. Выдается следующее предупреждение:

(!) Предупреждение: переименовать (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' на любое другое.

Спасибо всем за потраченное время и извините за то, что беспокою вас такой глупостью, которая, как оказалось, не имеет абсолютно никакого отношения к моему первоначальному предположению и, следовательно, к сформулированному вопросу.

1 Ответ

4 голосов
/ 13 февраля 2012

Пример на PHP.net говорит вам точно, что делать - используйте ROOT PATH для файла - обычно это можно получить с помощью $_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!";
}
?>

Вы экранировали символы, используя обратную косую черту - всегда используйте прямую косую черту (я знаю, что это в одинарной кавычке, что нормально, но если вы используете двойную кавычку, вам будет интересно, что пошло не так)!

...