Foros del Web

Foros del Web (http://www.forosdelweb.com/)
-   PHP (http://www.forosdelweb.com/f18/)
-   -   [solucionado] Problema con fwrite (http://www.forosdelweb.com/f18/solucionado-problema-con-fwrite-725388/)

metacortex 07/08/2009 07:09

[solucionado] Problema con fwrite
 
Tengo ya buen rato con este problema y no logro dar con la solución. El objetivo es escribir una línea en un archivo externo, en una posición específica. Hasta ahí todo funciona bien.

El caso es que cada vez que actualizo la página que tiene el código, la otra también se actualiza. Quisiera que sólo escribiera la línea cuando ésta no se encuentre presente, en lugar de escribirla todo el tiempo. Aquí está el código:

Código PHP:

$texto 'mi texto';
$archivo 'mi-archivo.php');
$conteo 1;
$leer file($archivo);
$buscar $leer[$conteo];
for( 
$i $i count($leer) ; $i++ ) {
    
$leer[$i] = trim($leer[$i]);
    if( 
$i == $conteo $leer[$i] = $texto;
}

if(
$buscar == '') { // Aquí es donde debería funcionar, pero no
    
$nueva_linea implode"\n"$leer );
    
$abrir fopen$archivo 'w' );
    
fwrite$abrir $nueva_linea strlen($nueva_linea) );
    
fclose($abrir);


Le coloqué esa condicional (escribir la línea sólo si $buscar está vacío ) pero lo pasa por bola y sobrescribe de todas maneras ¿Cómo le hago para que -si la línea tuviera el mismo texto que $texto- la operación sólo llegue hasta file() y no ejecute fopen, fwrite y fclose?.

jonatanc 07/08/2009 07:29

Respuesta: Problema con fwrite
 
Estimado no puede leer el contenido de dicho fichero con file_get_contents y si el valor retornad es igual a vacio hace x cosa sino hace otra x cosa.

Saludos!

metacortex 07/08/2009 07:38

Respuesta: Problema con fwrite
 
Cuestión de probar. A ver si resulta con eso. Gracias :arriba:.

abimaelrc 07/08/2009 07:48

Verifica este aporte a ver si te ayuda
http://www.forosdelweb.com/f18/aport...equest-724214/

Verifica si esto es lo que deseas hacer. De verdad que me perdi con lo que quieres hacer pero verifica si esto te ayuda

Código PHP:
Ver original
  1. <?php
  2. $texto = 'mi texto';
  3. $archivo = 'c.php';
  4. $leer = file_get_contents($archivo);
  5. $exp = explode("\n",$leer);
  6. foreach($exp as $v){
  7.     if($texto == $v){
  8.         $bool = false;
  9.         break;
  10.     }else{
  11.         $bool = true;
  12.     }
  13. }
  14. if($bool){
  15.     $abrir = fopen( $archivo , 'a+' );
  16.     fwrite( $abrir , $texto."\n" );
  17.     fclose($abrir);
  18. }

jonatanc 07/08/2009 08:06

Respuesta: Problema con fwrite
 
Estimado aqui le coloco una solución a su problema , o eso pienso:

Código php:
Ver original
  1. <?php
  2.  
  3. /**
  4.  * Script Author: Jonatan Lucio Casagrande <[email protected]>
  5.  * Script Function:
  6.  * Script Info: -
  7.  */
  8.  
  9. $lineas=array();
  10.  
  11.  //-- Este bloque lee linea a linea e incluye en un array todos las lineas
  12. $fichero_txt=fopen('ficherotxt.txt','a+');
  13. if($fichero_txt){
  14. while($linea = fgets($fichero_txt,4096)){
  15. $linea=trim($linea);   
  16. array_push($lineas,$linea);
  17. }
  18. }else{
  19. die("Error: El fichero no pudo ser abierto");  
  20. }
  21. //
  22.  
  23. //-- Cuento la cantidad de lineas leidas
  24. $cantidad_lineas=count($lineas);
  25.  
  26. //-- Compruebo si el valor que deseo insertar esta en el array de lineas fuente si no esta lo grabo al archivo
  27. if(!in_array($_GET['lineas'],$lineas)){
  28. $i=0;  
  29. for($i=0;$i<=$cantidad_lineas;$i++){
  30. fwrite($fichero_txt,$fichero_txt[$i]."\r\n",strlen($fichero_txt[$i])); 
  31. }
  32. fwrite($fichero_txt,$_GET['lineas']."\r\n",strlen($_GET['lineas']));   
  33. }
  34. //
  35.  
  36. //-- Cierro el fichero
  37. fclose($fichero_txt);
  38.  
  39. ?>

Una sola cosa tiene defectuosa , no imprime una linea debajo de otra sino todo en una linea pero a los fines didacticos es util y funciona perfecto.

Saludos!

metacortex 07/08/2009 09:50

Respuesta: Problema con fwrite
 
Mil gracias por su ayuda muchachos :arriba:, aunque aún no encuentro manera de hacer funcionar el hijoep... código. Ya daré con la solución de un momento a otro.

abimaelrc 07/08/2009 09:52

Respuesta: Problema con fwrite
 
Lo que no entendi es si quieres ingresarlo en una linea en especifico lo quieres ingresar al final. Si es al final lo que te indique en el codigo te puede ayudar.

David 07/08/2009 09:55

Respuesta: Problema con fwrite
 
$buscar nunca será vacío ya que se incluye el final de línea en todos los elementos del array. Prueba usando el flag FILE_IGNORE_NEW_LINES al llamar a file()

metacortex 07/08/2009 18:30

Respuesta: Problema con fwrite
 
Cita:

Iniciado por David (Mensaje 3035959)
$buscar nunca será vacío ya que se incluye el final de línea en todos los elementos del array. Prueba usando el flag FILE_IGNORE_NEW_LINES al llamar a file()

Lo que pasa es que cuando borro la línea del archivo afectado y luego hago un echo a ambos ($buscar y $texto), $buscar aparece vacío en el primer refrescamiento. De ahí que lo haya utilizado como condición.

David 07/08/2009 20:57

Respuesta: Problema con fwrite
 
Tal vez sea porque al hacer echo parece estar vacío; debido a que no aparece un carácter sino sólo el salto de línea (PHP_EOL) contenido en $buscar.

P.S.: Además, si revisas el código, al no usar FILE_IGNORE_ NEW_LINES y unir el array usando un salto de línea estás repitiendo ese salto que está presente en todos los elementos.

abimaelrc 07/08/2009 21:04

Respuesta: Problema con fwrite
 
Ok corregi verifica si esto es lo que quieres. Lei de nuevo el principio y vi que habias hecho un cambio a lo que escribiste la primera vez y ahora como lo explicaste si entendi lo que quieres hacer :pensando: creo yo

Código PHP:
Ver original
  1. <?php
  2. $texto = 'mi texto';
  3. $archivo = 'mi-archivo.php';
  4. $bool=true;
  5. $conteo = 1;
  6. $leer = file($archivo);
  7. $buscar = $leer[$conteo];
  8. for( $i = 0 ; $i < count($leer) ; $i++ ) {
  9.     $leer[$i] = trim($leer[$i]);
  10.     if($i == $conteo){
  11.         if($leer[$i] == $texto){$bool=false;}
  12.         $leer[$i] = $texto;
  13.     }
  14. }
  15.  
  16. if($bool) {
  17.     $nueva_linea = implode( "\n", $leer );
  18.     $abrir = fopen( $archivo , 'w' );
  19.     fwrite( $abrir , $nueva_linea , strlen($nueva_linea) );
  20.     fclose($abrir);
  21. }

metacortex 07/08/2009 21:46

Respuesta: Problema con fwrite
 
Carajo funcionóooooooo!!! :arriba:

Hermano abimaelrc me quito el sombrero con usted. Tremenda jugada la que hiciste en el bucle... Uff y hace rato yo le había llegado cerca, sólo que le metí otro valor a la variable y no la predefiní antes del for. Pero esto que hiciste está más que genial. Gracias!

Todo el santo día buscándole la caída al problemita. A esta hora ya estaba buscando ejemplos sin bucles :golpeado: (no me culpen, fue producto de la desesperación).

En fin, para quienes quieran saber qué hace este código: éste agrega una nueva línea de un archivo a otro, teniendo nosotros la posibilidad de elegir - a través de la variable $conteo- en cuál número de línea deseamos colocar la frase ($texto). Abimaelrc le agregó el ingrediente que faltaba: que no escriba la línea cada vez que el archivo se refresque.

... Y aún hay quienes piensan que los "viernes de geeks" no son emocionantes :risa:.

Saludos!


PD: por si las moscas, también le agregué el flag FILE_IGNORE_ NEW_LINES que recomendó David (gracias panita). Es bastante razonable.

David 08/08/2009 05:38

Respuesta: [solucionado] Problema con fwrite
 
Me alegra que lo hayas solucionado :arriba:.

Sólo como recomendación final, es conveniente usar la constante PHP_EOL en lugar de \n, ya que la combinación para el fin de línea no siempre es el mismo en todos los sistemas operativos.

Saludos.

metacortex 08/08/2009 06:10

Respuesta: [solucionado] Problema con fwrite
 
Gracias. En cuanto a eso noté que ese implode("\n... me elimina todo el intentado y pega las líneas "a la pared". Por ese lado es una lástima ya que me gusta indentar el código, pero lo importante es que funciona al 100%.

abimaelrc 08/08/2009 06:29

Respuesta: [solucionado] Problema con fwrite
 
Bueno para el indentado el problema no creo que es el implode sino que tienes declarado un trim en la linea

Código php:
Ver original
  1. $leer[$i] = trim($leer[$i]);

Eso te esta borrando los espacios anteriores. Claro esta, lo estas haciendo porque quieres verificar la linea sino no hace el siguiente if o mejor dicho nunca va a encontrar la linea si esta indentada. Vas a tener que usar Expresiones regulares para verificar cuantos indentados tienes y guardarlos en una variable y despues que hagas el if vuelves a colocarle los indentados

David 08/08/2009 08:17

Respuesta: [solucionado] Problema con fwrite
 
En realidad probablemente no haga falta usar una expresión regular. Ya que el trim() puedes usarlo sólo en la comparación:
Código PHP:
Ver original
  1. if (trim($leer[$i]) == $texto) { /* Código */ }

abimaelrc 08/08/2009 08:54

Respuesta: [solucionado] Problema con fwrite
 
Hazle caso a David :borracho: es mejor hacerlo de esa forma. lol

okram 08/08/2009 18:50

Respuesta: Problema con fwrite
 
Estimados, no pude evitar meter mis narizotas en este hilo solucionado ya :borracho:.

Analizando el código que publicó abimaelrc, aplicando la última sugerencia de David el Grande ;-) (dos mensajes arriba), y evaluando el resultado final de dicho código en distintas situaciones, resulta que el bucle for que hay allí no tiene utilidad alguna, ya que no realiza ninguna modificación y sólo interviene en el elemento cuyo índice es $conteo. Por lo tanto, no tiene sentido ciclar el array entero cuando sólo queremos tocar uno de sus elementos.

@metacortex, el proceso en sí sólo requiere de una comprobación (if), y el uso de trim() por el tema de las tabulaciones:

Código php:
Ver original
  1. $texto = 'mi texto';
  2. $archivo = 'mi-archivo.php';
  3. $conteo = 2;
  4.  
  5. // Ignoramos los saltos de línea
  6. $leer = file($archivo, FILE_IGNORE_NEW_LINES);
  7.  
  8. // Adiós ciclo for ;-)
  9.  
  10. // Sólo queremos trabajar sobre la línea $conteo dentro del array $leer
  11. if(isset($leer[$conteo]) and $texto != trim($leer[$conteo])) {
  12.  
  13.     // $leer[$conteo] existe, y el valor del nuevo texto ($texto) es diferente del que existe ya en el archivo (trim($leer[$conteo]))
  14.  
  15.     $leer[$conteo] = $texto;
  16.     $nueva_linea = implode("\n", $leer );
  17.     $abrir = fopen( $archivo , 'w' );
  18.     fwrite( $abrir , $nueva_linea , strlen($nueva_linea) );
  19.     fclose($abrir);
  20.  
  21. }

Cero bucles. Este código tiene las mismas características (desde el punto de vista de resultado final) que el anterior. Hay algunos puntos a tomar en cuenta que quizás los estés pasando por alto (digo quizás):
  • La primera línea de tu archivo es 0. Si conteo vale 4, hace referencia entonces a la quinta línea
  • Si $conteo hace referencia a un número de línea muy alto, tanto que no existe en el archivo, no se hará nada. Es lo mismo que hace el script anterior, ya que cicla sólo sobre los elementos del array. Por lo tanto, $conteo = 20 en un archivo de 15 líneas no hará absolutamente nada.
  • Hablas de tabulaciones. Las líneas que no se modifican las van a conservar (igual que el código anterior), pero la línea que es reemplazada quedará "pegada a la pared", a menos que el texto nuevo incluya sus propias tabulaciones. A modo de tipearte (del verbo tip :borracho:), puedes agregar tabulaciones a un string usando la marca \t (Siempre en comillas dobles, igual que \n)
Cita:

Iniciado por metacortex (Mensaje 3036635)
Todo el santo día buscándole la caída al problemita. A esta hora ya estaba buscando ejemplos sin bucles :golpeado: (no me culpen, fue producto de la desesperación).

Resulta que la desesperación puede llegar en ocasiones a ser más productiva ;-)

:adios:

abimaelrc 08/08/2009 22:23

Respuesta: [solucionado] Problema con fwrite
 
Añadiendo lo que indica okram, si no quieres declarar las tabulaciones puedes encontrarlas antes de añadir la linea. Me refiero a esto

Código PHP:
Ver original
  1. $texto = 'mi texto';
  2. $archivo = 'c.php';
  3. $conteo = 3;
  4.  
  5. // Ignoramos los saltos de línea
  6. $leer = file($archivo, FILE_IGNORE_NEW_LINES);
  7.  
  8. // Adiós ciclo for ;-)
  9.  
  10. // Sólo queremos trabajar sobre la línea $conteo dentro del array $leer
  11. if(isset($leer[$conteo]) and $texto != trim($leer[$conteo])) {
  12.     // $leer[$conteo] existe, y el valor del nuevo texto ($texto) es diferente del que existe ya en el archivo (trim($leer[$conteo]))
  13.     preg_match("|^[\t\s]*|",$leer[$conteo],$m);
  14.     $leer[$conteo] = $m[0].$texto;
  15.     $nueva_linea = implode("\n", $leer );
  16.     $abrir = fopen( $archivo , 'w' );
  17.     fwrite( $abrir , $nueva_linea , strlen($nueva_linea) );
  18.     fclose($abrir);
  19. }

:pensando: ya mismo hacemos un sistema operativo con este codigo

metacortex 09/08/2009 03:09

Respuesta: [solucionado] Problema con fwrite
 
Grande okram!!! Qué solución!!

Sí, anoche precisamente me preguntaba acerca de la necesidad del bucle, ya que todo era cuestión de entrar, revisar/comparar una línea específica y escribir lo que había en la variable. Es decir, Sólo que los ejemplos que encontré incluían algún tipo de bucle y desistí por embotamiento.

Este giro que le diste al asunto es sencillamente increíble. También quedó vigente el FILE_IGNORE_NEW_LINES de David (ahora más que esencial para el script) y la condicional de abimaelrc (variada) para impedir la escritura constante. Ahora sí estoy más feliz que Julie Andrews en la colina.

Explicando de qué viene esto:

A manera de información, lo que se ha hecho aquí viene resolviendo un importante problema relacionado a la activación automática de funciones de Wordpress a cualquier tipo de archivos, un proceso que hasta ahora se venía haciendo de forma estática, en especial por parte de los desarrolladores de plugins y plantillas.

Específicamente requiero de este código para aplicar funciones Ajax en mi plugin, lo cual involucra un archivo externo que debe tener activadas las funciones nativas de Wordpress; para ello es necesario hacer -desde éste- un require_once a cierto archivo del sistema (wp-load.php, ubicado en la raiz del sitio) o de lo contrario devolvería error de función indefinida.

El asunto radica en que Wordpress sólo reconoce como "suyo" a un archivo del directorio del plugin: el principal -que se declara mediante una cabecera especial- y activa todas sus funciones sólo a éste, pero "abandona" a los demás. Hasta ahora la forma que se usaba para traer el conjunto de funciones nativas era:

Código PHP:

require_once(../../wp-load.php

Esto resultaba muy bien hasta cierta versión de Wordpress, a partir de la cual fue posible mover el directorio /wp-content/ a cualquier ubicación... Pero junto a esta nueva característica surgieron algunos reveses, entre ellos precisamente que muchas configuraciones estáticas (entre ellas las rutas) se iban al diablo, siendo necesario reescribirlas manualmente.

Entonces me pregunté por qué no hacer que el mismo WP escriba automáticamente esa línea en otros archivos desde el archivo principal (el que Wordpress sí reconoce) y comencé a buscar documentación hasta completar el código inicial, que terminó funcionando, pero tenía el problemita de la reescritura constante, lo cual aún lo hacía inviable porque los plugins no sólo son consultados en el backend sino cada vez que una web es visitada.

El desarrollo (y sus culpables :borracho:) quedaron debidamente documentados en el presente tópico. Y con este último tubazo fulminante de okram finalmente obtuvimos un código optimizado y usable que cumple con su función cabalmente, el cual sin duda alguna será parte esencial para todo plugin de Wordpress desde ahora, eso gracias a ustedes compadres.

El código terminado: (Para usarlo debe modificarse los nombres de los archivos)

Código PHP:

if ( !defined('WP_PLUGIN_DIR') ) $plugin_dir str_replaceABSPATH''dirname(__FILE__) );
else 
$plugin_dir dirnameplugin_basename(__FILE__) );
$texto 'require_once(\''ABSPATH 'wp-load.php\');';
$texto_error '';
$archivo ABSPATH '/' PLUGINDIR '/' $plugin_dir .'/wpsi-data.php';
$conteo 1;
$leer file($archivoFILE_IGNORE_NEW_LINES);

if( isset(
$leer[$conteo]) and $texto != trim($leer[$conteo]) ) {
  
$leer[$conteo] = $texto;
  if (
is_writable($archivo)) {
    
$nueva_linea implode"\n" $leer );
    
$abrir fopen$archivo 'w' );
    
fwrite$abrir $nueva_linea strlen($nueva_linea) );
    
fclose($abrir);
  } else {
    
$texto_error .='
    <div id="message" class="updated fade">
      <p>'
.__('WP Smart Image can\'t write your file. Please open your "wpsi-data.php" file located in /wp-smart-image/ directory and paste the following string into the second line of that file:''wp-smart-image').':</p>
      <pre>'
.$archivo.'</pre>
    </div>'
;
  }


Qué es lo que hace el script (o eso espero):

- Imprime la ruta absoluta completa al archivo wp-load.php (el que activa las funciones de Wordpress en archivos estáticos) independientemente del lugar donde se encuentre el directorio del plugin. Si posteriormente la carpeta es movida, el script localizará automáticamente al archivo.

- Si el archivo a modificar no es escribible, el script lanzará una advertencia en el panel de que es necesario incluir el código, proporcionando la ruta correcta del mismo en una etiqueta <pre>.

- Si el código está correctamente en su lugar, el anuncio no saldrá (aunque el archivo no sea escribible).


La zona horaria es GMT -6. Ahora son las 06:26.

Desarrollado por vBulletin® Versión 3.8.7
Derechos de Autor ©2000 - 2026, Jelsoft Enterprises Ltd.