2012-02-27 10 views
6

Estoy tratando de escribir una gran cantidad de datos en un archivo que se abre a través de fopen() en php. El contenedor de protocolo que estoy usando es ftp, por lo que el archivo es remoto para el servidor que ejecuta el código php. El archivo que estoy escribiendo está en un servidor de Windows.php fwrite() no termina de escribir datos de cadena en un archivo, ¿por qué?

Comprobé que el archivo, de hecho, es creado por mi código php, pero el problema es que los datos dentro del archivo son inexistentes (0KB) o la escritura en el archivo se detiene prematuramente. No estoy seguro de por qué este es el caso.

Aquí está el código que estoy utilizando para el manejo de la operación:

$file_handle = fopen($node['ftp'].$path_to_lut, "wb", 0, $node['ftp_context']); 
include_once($file); 

if ($file_handle) 
{ 
    fwrite($file_handle, $string); //$string is inside included $file 
    fclose($file_handle); 
} else { 
    die('There was a problem opening the file.'); 
} 

Este código funciona bien cuando el anfitrión en mi máquina local, pero cuando subo a mi servicio de hosting (Rackspace Nube), se falla Esto me lleva a pensar que es un problema relacionado con la configuración de mi servidor en Rackspace, pero quiero saber si hay algo que pueda hacer con mi código php para hacerlo más robusto.

¿Alguna idea para asegurar que fwrite realmente termine de escribir la cadena en la máquina remota?

Gracias!

bien, he cambiado el código que escribe en el archivo de este modo:

if ($file_handle) 
{ 
    if ($bytesWritten = fwrite($file_handle, $string)) { 
     echo "There were " . $bytesWritten . " bytes written to the text file."; 
    } 

    if (!fflush($file_handle)) { 
     die("There was a problem outputting all the data to the text file."); 
    } 

    if (!fclose($file_handle)) { 
     die("There was a problem closing the text file."); 
    } 

} else { 

    die("No file to write data to. Sorry."); 

} 

Lo que es extraño es que la declaración de eco muestra lo siguiente:

Hubo 10330 bytes escritos en el Archivo de texto.

Y, sin embargo, cuando verifico el tamaño del archivo de texto a través de FTP, muestra que es 0K y, de hecho, los datos dentro del archivo se truncan. No me puedo imaginar que tenga que ver con el servidor FTP en sí, porque funciona si el PHP está alojado en una máquina distinta a la de Rackspace Cloud.

** ACTUALIZACIÓN ** Hablé con un representante de Rackspace Cloud que mencionó que requieren ftp pasivo si va a ftp desde sus servidores. Configuré el servidor remoto para manejar las conexiones ftp pasivas, y he verificado que el ftp pasivo ahora funciona en el servidor remoto a través del cliente ftp de transmisión de OSX. Añadí:

ftp_pasv($file_handle, true); 

Justo después de las fopen() declaración, pero me da un error de PHP diciendo que el que no proporcionan un recurso válido para ftp_pasv(). ¿Cómo puedo asegurarme de que la conexión al sitio ftp que hace PHP sea PASV y no ACTIVE y aún use fwrite()? Por cierto, me he dado cuenta de que la máquina de Windows informa que el archivo que está siendo escrito por mi código PHP es de 4096 bytes en el disco. Nunca supera esa cantidad. Esto me llevó a cambiar el valor de php de output_buffering a 65536 solo para solucionar problemas, pero eso tampoco solucionó el problema. . .

** ACTUALIZACIÓN ** PARTE Duex

la solución del problema en el que mi servidor virtual en la nube Rackspace Sitios producto estaba resultando demasiado difícil, ya que no ofrecen suficientes derechos de administrador. Creé un servidor en la nube muy pequeño en el producto Cloud Server de Rackspace y configuré todo hasta el punto en que sigo viendo el mismo error con fwrite(). Para asegurarme de poder escribir un archivo desde ese servidor a un servidor remoto, utilicé comandos ftp básicos dentro de mi shell bash en el servidor de la nube. Funcionó bien Entonces, supongo que hay un error dentro de la implementación php de fwrite(), y que probablemente se deba a algún tipo de problema de regulación de datos.Cuando escribo en el servidor remoto desde mi entorno local, que tiene una velocidad de subida lenta en comparación con lo que se ofrece en el servidor de Rackspace Cloud, funciona bien. ¿Hay alguna manera de reducir la velocidad de escritura de manera efectiva? Sólo Askin' :)

** ACTUALIZACIÓN PARTE III *

Por lo tanto, tomé la sugerencia de @ un tipo triste e implementado una función que podría ayudar a alguien que intenta escribir en un nuevo archivo y enviarlo apagado en su totalidad a través de ftp:

function writeFileAndFTP($filename=null, $data=null, $node=null, $local_path=null, $remote_path=null) 
{ 

    // !Determin the path and the file to upload from the webserver 
    $file = $local_path.'/'.$filename; 


    // !Open a new file to write to on the local machine 
    if (!($file_handle = fopen($file, "wb", 0))) { 
     die("There was a problem opening ".$file." for writing!"); 
    } 


    // !Write the file to local disk 
    if ($bytesWritten = fwrite($file_handle, $data)) { 
     //echo "There were " . $bytesWritten . " bytes written to " . $file; 
    } 

    // !Close the file from writing 
    if (!fclose($file_handle)) { 
     die("There was a problem closing " . $file); 
    } 

    // !Create connection to remote FTP server 
    $ftp_cxn = ftp_connect($node['addr'], $node['ftp_port']) or die("Couldn't connect to the ftp server."); 

    // !Login to the remote server 
    ftp_login($ftp_cxn, $node['user'], getPwd($node['ID'])) or die("Couldn't login to the ftp server."); 

    // !Set PASV or ACTIVE FTP 
    ftp_pasv($ftp_cxn, true); 


    // !Upload the file 
    if (!ftp_put($ftp_cxn, $remote_path.'/'.$filename, $file, FTP_ASCII)) { 
     die("There was an issue ftp'ing the file to ".$node['addr'].$remote_path); 
    } 

    // !Close the ftp connection 
    ftp_close($ftp_cxn); 

} 
+0

'include_once ($ archivo);' - ¿dónde está ese código? – hakre

+0

se ve como la siguiente: cadena '$ = "una cadena alrededor de 20 líneas de largo";' '¿Qué – ariestav

+0

var_dump ($ nodo [ 'ftp_context']);' salida? (eliminar nombre de usuario/contraseña). – hakre

Respuesta

4

la longitud de la cadena fwrite puede escribir de una sola vez se limita en algunas plataformas (por lo que devuelve el número de bytes por escrito). Puede intentar ejecutarlo en un bucle, pero una mejor idea es simplemente usar file_put_contents, lo que garantiza que se escribirá toda la cadena.

http://www.php.net/manual/en/function.file-put-contents.php

+0

Interesante, gracias por el puntero. Por curiosidad, ¿hay alguna directiva apache que pueda establecer en un archivo .htaccess para cambiar el límite de datos de fwrite()? – ariestav

+0

Dudoso) además, si está utilizando ftp, se trata más de la red, supongo. ¿Funcionó file_put_contents? –

+0

comprobando ahora. . . – ariestav

Cuestiones relacionadas