2012-02-13 16 views
6

私のPHPには奇妙な問題があります。 rename()でファイルを移動しようとするたびに、ファイルが移動されるだけでなく、コピーするディレクトリもその中のすべてのファイルとともに削除されます。元のコードは次のとおりです。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. 対象のファイルが既に存在していない(実際のファイル名にはタイムスタンプを持って、私は簡単にするため、ここでそれを削減)

、「temp.odt」ファイルは元に無傷ですフォルダ 'tmp'はが消滅したとその中のすべてのものです。

(!)警告:名前の変更(temp.odt、tmp \ report.odt)[function.rename]:指定されたパス*が見つかりませんでした。 (コード:3)はC:\ WAMP \ WWW \ ZAIKO \モジュール\ mod_deliver.phpライン192

上*ポルトガル

実行中から翻訳:WindowsのXP上のPHP 5.3.5でのApache 2.2.17とNTFS


編集:

ただ、問題の原因を発見しました。アプリケーションが使用するモジュールは圧縮ライブラリを使用することが判明しました。このライブラリは、アプリケーションで使用されているものとまったく同じ名前の一時フォルダを使用します。

何らかのキャッシュを使用する必要があります。これは、エラーが100%表示されなかった理由を説明します。

問題は 'tmp'フォルダの名前を他のものに変更することで解決します。

ありがとう、私の最初の推測とはまったく関係がありませんでしたので、定式化された質問では、まったくそのような愚かなものであなたを気にして、ごめんね。

+0

ファイルを新しい場所にコピーして元のファイルを削除するとどうなりますか? – nickb

+0

モジュールのコードをどこかに投稿できますか? php.netのコメントに関しては、他の人にはこの問題はありません。 Bugtrackerは、 'rename'はWinXP上の既存のファイルを上書きしないと言いますが、あなたが記述したのと同じ問題ではありません。たぶん、どこかに 'tmp'ディレクトリを整理するコードがありますか? –

+0

rename()が呼び出されたときにファイルハンドル(元のファイル用)が解放されていない可能性がありますか?このプロジェクトが実行されているマシンの特性を考えると、それが問題だと思う傾向があります。 –

答えて

4

PHP.netの例では、ファイルにROOT PATHを使用しています。通常は$_SERVER['DOCUMENT_ROOT']を使用して取得できます(ただし、これはhtdocs/public_htmlディレクトリにのみあります。残りを指定する必要があります)手動でパスを入力して(ただし、これを避けるようにしてください)。推測で

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

、以下の作業をする必要があります(これはあなたの道であると仮定) - あなたはtmp/が実際に最初の場所に存在することを確認する必要があります - これはまた、名前を変更することができるように、ファイルが実際に存在することを確認いつも私は、これはokです、単一引用符内にある知っている(スラッシュを使用しますが、もし -

<?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!"; 
} 
?> 
あなたはバックスラッシュを使用して文字をエスケープして

は:しかし、あなたがエラーを取得することはしなかった場合飛び出ます二重引用符を使用すると、何が間違っているのだろうか)。

+0

一重引用符で囲まれた文字列のバックスラッシュは、それ自身( '\\')または一重引用符 '\ ''のみをエスケープできます。しかし、フォワードスラッシュが好きです。 –

+0

私はすべてを試しました。指示された構成では、時々だけ動作します。 @AndrewD。 –

+0

はい - 良い点! – MrJ