2012-02-13 6 views
6

Ho un problema strano con il mio php. Ogni volta che provo a spostare un file con rename(), non solo il file non viene spostato, ma anche la directory in cui deve essere copiato viene cancellata, insieme a tutti i file al suo interno. Il codice originale è:Comportamento strano di rinomina() in PHP

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

ma ho già provato altri delimitatori di percorso come

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'); 

tutto inutile. Il codice proviene da un modulo di terze parti che viene utilizzato nel sistema su cui sto lavorando.

Punti ben controllati:

  1. Il file 'temp.odt' esiste nella directory corrente;
  2. La directory "tmp" esiste e ci sono diversi file al suo interno. Inoltre non è di sola lettura.
  3. Il file di destinazione non esiste già (il nome del file effettivo ha un timestamp, ho ridotto qui per semplicità)

Dopo l'esecuzione di rinominare(), il file 'temp.odt' è intatto nel suo originale posizione, mentre la cartella 'tmp' è svanita così come tutto al suo interno. Viene emesso il seguente avviso:

(!) Avviso: rinomina (temp.odt, tmp \ report.odt) [function.rename]: il sistema non è riuscito a trovare il percorso specificato *. (Codice: 3) in C: \ wamp \ www \ Zaiko \ moduli \ mod_deliver.php on line 192

* tradotto dal portoghese

Esecuzione: Apache 2.2.17 con PHP 5.3.5 su Windows XP con NTFS


Montaggio:

Appena trovato la causa del problema. Risulta che il modulo utilizzato dall'applicazione utilizza, a sua volta, una libreria di compressione; questa libreria utilizza una cartella temporanea con esattamente lo stesso nome di quella utilizzata dall'applicazione.

È necessario utilizzare una sorta di cache, che spiegherebbe perché l'errore non è apparso 100% volte.

Problema risolto cambiando il nome della cartella 'tmp' in qualsiasi altra cosa.

Grazie a tutti per il vostro tempo, e mi dispiace per averti disturbato con una cosa così stupida che, come risulta, non aveva assolutamente nulla a che fare con la mia ipotesi iniziale e, di conseguenza, con la domanda formulata.

+0

Cosa succede se si copia il file nella nuova posizione, quindi si elimina l'originale? – nickb

+0

Potresti postare il codice del modulo da qualche parte? Per quanto riguarda i commenti su php.net, altri non hanno questo problema. Bugtracker dice che 'rename' non sovrascrive i file esistenti su WinXP, ma non è lo stesso problema che descrivi. Forse, c'è un codice da qualche parte che ripulisce la directory 'tmp'? –

+0

Potrebbe essere che l'handle del file (per il file originale) non sia stato rilasciato quando viene chiamato rename()? Viste le caratteristiche della macchina su cui è in esecuzione questo progetto, sono propenso a pensare che sia questo il problema. –

risposta

4

L'esempio su PHP.net indica esattamente cosa fare: utilizzare il ROOT PERCORSO per il file - normalmente questo può essere ottenuto utilizzando $_SERVER['DOCUMENT_ROOT'] (ma questo va solo alla directory htdocs/public_html - è necessario specificare il resto) oppure digitando manualmente il percorso in (ma cerca di evitarlo).

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

A occhio e croce, il seguente dovrebbe funzionare (assumendo questo è il vostro percorso) - questo controlla anche che il file esiste effettivamente in modo che possa essere rinominato - è necessario fare in modo che tmp/ esiste in realtà in primo luogo , ma si otterrà un errore saltar fuori se così non fosse:

<?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!"; 
} 
?> 

eravate Sfuggire i caratteri utilizzando i backslash - sempre utilizzare le barre (so che questo è all'interno di una singola citazione, che è ok, ma se usi la doppia citazione quindi ti starai chiedendo che cosa è andato storto)!

+0

Le barre rovesciate nelle stringhe con quotatura singola possono sfuggire solo a se stessi ('\\') o una virgoletta singola '\ ''. Ma i tagli in avanti sono preferibili, sì. –

+0

Ho provato di tutto. Con la configurazione indicata funziona solo a volte. –

+0

@AndrewD. Sì, buon punto! – MrJ