2012-02-13 8 views
6

Tengo un problema extraño con mi php. Cada vez que intento mover un archivo con rename(), no solo no se mueve el archivo, sino que también se elimina el directorio al que se debe copiar, junto con todos los archivos que contiene. El código original es:Comportamiento extraño de renombrar() en PHP

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

pero ya he probado otros delimitadores de ruta como

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

todo fue en vano. El código proviene de un módulo de terceros que se utiliza en el sistema en el que estoy trabajando.

Puntos así verificado:

  1. El archivo 'temp.odt' no existe en el directorio actual;
  2. El directorio 'tmp' existe y hay varios archivos en él. Además, no es de solo lectura.
  3. no existe el archivo de destino (el nombre real del archivo tiene una marca de tiempo, reduje aquí por simplicidad)

Después de ejecutar renombrar(), el archivo 'temp.odt' está intacto en su forma original ubicación, mientras que la carpeta 'tmp' es desaparecido, así como todo lo que hay dentro. Se emite la siguiente advertencia:

(!) Advertencia: cambiar el nombre (temp.odt, tmp \ report.odt) [función.nombre]: El sistema no pudo encontrar la ruta especificada *. (Código: 3) en C: \ wamp \ www \ Zaiko \ modules \ mod_deliver.php en la línea 192

* Traducido del portugués

de reproducción: Apache 2.2.17 con PHP 5.3.5 en Windows XP con NTFS


Edición:

Sólo se encontró la causa del problema. Resulta que el módulo utilizado por la aplicación utiliza, a su vez, una biblioteca de compresión; esta biblioteca utiliza una carpeta temporal con exactamente el mismo nombre que la utilizada por la aplicación.

Debe usar algún tipo de caché, lo que explicaría por qué el error no apareció el 100%.

Problema resuelto al cambiar el nombre de la carpeta 'tmp' a cualquier otra cosa.

Gracias a todos por su tiempo, y lo siento por molestarlo con una cosa tan estúpida que, como resultado, no tuvo absolutamente nada que ver con mi conjetura inicial y, en consecuencia, con la pregunta formulada.

+0

¿Qué sucede si copia el archivo en la nueva ubicación y luego elimina el original? – nickb

+0

¿Podría publicar el código del módulo en alguna parte? En cuanto a los comentarios en php.net, otros no tienen este problema. Bugtracker dice que 'rename' no sobrescribe los archivos existentes en WinXP, pero no es el mismo problema que usted describe. Tal vez, hay un código en alguna parte que limpia el directorio 'tmp'? –

+0

¿Podría ser que el manejador de archivo (para el archivo original) no se haya liberado cuando se llama a renombrar()? Dadas las características de la máquina en la que se ejecuta este proyecto, me inclino a pensar que ese es el problema. –

Respuesta

4

El ejemplo de PHP.net te dice exactamente qué hacer - utilizar la ruta de raíz al archivo - normalmente esto se puede conseguir mediante el uso de $_SERVER['DOCUMENT_ROOT'] (pero esto sólo sirve para el directorio htdocs/public_html - es necesario especificar el resto) o escribiendo manualmente la ruta de acceso (pero trate de evitar esto).

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

En una conjetura, lo siguiente debería funcionar (suponiendo que esto es su camino) - esto también comprueba que realmente existe el archivo por lo que puede cambiar el nombre - que necesita para asegurarse de que tmp/ existe realmente en el primer lugar , pero obtendrá un error haciendo estallar hacia fuera si no lo hizo:

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

en que se escapaban caracteres utilizando barras invertidas - utilizar siempre barras inclinadas (sé que esto está dentro de una única oferta, lo cual está bien, pero si utilizas una comilla doble, entonces te preguntarás qué ha ido mal).

+0

Las barras diagonales inversas en cadenas de comillas simples pueden escaparse únicamente de ellas mismas ('\\') o de una comilla simple '\ ''. Pero las barras diagonales son preferidas, sí. –

+0

Intenté todo. Con la configuración indicada, solo funciona algunas veces. –

+0

@AndrewD. Sí, buen punto! – MrJ