Foros del Web » Programando para Internet » PHP »

Borrar/Actualizar un fila de un fichero

Estas en el tema de Borrar/Actualizar un fila de un fichero en el foro de PHP en Foros del Web. Buenas, tengo q hacer un carrito con ficheros y me está produciendo dolores de cabeza. Resulta q cuando un usuario agrega un producto al carro, ...
  #1 (permalink)  
Antiguo 29/07/2003, 02:28
 
Fecha de Ingreso: julio-2003
Ubicación: Elche
Mensajes: 15
Antigüedad: 20 años, 9 meses
Puntos: 0
Borrar/Actualizar un fila de un fichero

Buenas, tengo q hacer un carrito con ficheros y me está produciendo dolores de cabeza. Resulta q cuando un usuario agrega un producto al carro, éste se incorpora como una linea y las unidades que desea a un fichero temporal.
Si aumenta las unidades o selecciona el mismo producto tengo q leer el fichero y actualizar ese valor a las unidades que el usuario desea.
Les pongo una muestra de ejemplo:

antes:
{E3:Sin micro:Sin memoria:Sin disco duro:CD-ROM:Negro},1,300
{E7:Sin micro:Sin memoria:Sin disco duro:CD-ROM:Negro},1,400

y selecciona {E3:Sin micro:Sin memoria:Sin disco duro:CD-ROM:Negro}

después
{E3:Sin micro:Sin memoria:Sin disco duro:CD-ROM:Negro},2,300
{E7:Sin micro:Sin memoria:Sin disco duro:CD-ROM:Negro},1,400

Sin tener que leer todo el fichero entero y luego volcarlo, etc, sencillamente cambiar ese 1 por un 2.

Gracias y un saludo.
  #2 (permalink)  
Antiguo 29/07/2003, 09:59
 
Fecha de Ingreso: julio-2003
Mensajes: 165
Antigüedad: 20 años, 9 meses
Puntos: 1
Hola,

Es interesante el problema que describes, aunque me temo que no existe una solución trivial que cumpla con los requisitos que buscas (que no deba leerse el archivo entero o volcarlo).

La solución más natural es quizás usar un archivo temporal para almacenar allí el contenido actualizado del archivo y luego reemplazar el archivo original con el recién generado. Claro está que ese tipo de solución requiere precisamente leer por completo el contenido del archivo original (para volcarlo en el temporal):

Código:
<?php

// "Elemento" que se desea buscar
$item = '{E3:Sin micro:Sin memoria:Sin disco duro:CD-ROM:Negro}';

// Nuevo valor que se piensa guardar en el archivo (nos referimos al
// segundo elemento de una linea separada por comas)
$nuevo_valor = 2;


// Nombres de los archivos sobre los que se opera
$nombre_archivo = 'carrito.txt';  // Archivo con los datos originales
$nombre_tmp     = 'temp.txt';     // Nombre para un archivo temporal


// Nota: recuerde asegurarse de establecer los permisos adecuados para
// los archivos y directorios involucrados (si trabaja sobre un
// sistema operativo en el que los permisos tienen sentido)

$archivo = fopen ($nombre_archivo, 'r');
$tmp     = fopen ($nombre_tmp, 'w');


// Leer el archivo, linea por linea (considerando lineas de maximo 4kb
// de longitud)

while ($linea = fgets ($archivo, 4096)) {
    // Se asume que el separador de lexemas es la coma (`,')
    $lexemas = explode (',', $linea);

    if ($lexemas[0] == $item) {
        fwrite ($tmp, $lexemas[0] . ',' . $nuevo_valor . ',' . $lexemas[2]);
    } else
        fwrite ($tmp, $linea);
}

fclose ($tmp);
fclose ($archivo);

rename ($nombre_tmp, $nombre_archivo);

?>

Ahora bien, es posible hacer un procesamiento más eficiente si el contenido del archivo está organizado en bloques de tamaños fijos (lo que, como ocurre frecuentemente en otros lenguajes de programación, se podría conocer como "archivo de registros secuenciales"). En tal caso podría ser suficiente con seguir un algoritmo de este estilo:

a) Abrir el archivo de datos para lectura/escritura.
b) (mientras no se haya llegado al fin del archivo) Leer un bloque de N bytes del archivo.
c) Revisar si el bloque que se acaba de leer es el que queremos actualizar.
d) Si es así, actualizar el registro, y terminar el procesamiento del archivo. Cerrar el archivo.
e) De lo contrario, volver al paso b).

Una implementación en PHP podría ser algo como:

Código:
<?php

// "Elemento" que se desea buscar
$item = '{E3:Sin micro:Sin memoria:Sin disco duro:CD-ROM:Negro}';

// Nuevo valor que se piensa guardar en el archivo (nos referimos al
// segundo elemento de una linea separada por comas)
$nuevo_valor = 2;


$nombre_archivo = 'carrito.txt';  // Nombre del archivo con los datos
                                  // originales


$archivo = fopen ($nombre_archivo, 'r+');


// Leer el archivo, linea por linea (considerando lineas de maximo 4kb
// de longitud). Importante! Aqui asumimos que las lineas se van a
// conservar del mismo tamanyo, sin importar los datos que actualicemos.

$pos = 0;  // Posicion del apuntador en el archivo

while ($linea = fgets ($archivo, 4096)) {
    // Se asume que el separador de lexemas es la coma (`,')
    $lexemas = explode (',', $linea);

    if ($lexemas[0] == $item) {
        fseek ($archivo, $pos, SEEK_SET);
        fwrite ($archivo, $lexemas[0] . ',' .
                $nuevo_valor . ',' . $lexemas[2]);

        break;  // Si solo se espera encontrar una ocurrencia de
                // $item, se puede salir del ciclo inmediatamente
    }

    $pos = ftell ($archivo);
}

fclose ($archivo);

?>
Espero que te sea útil en la construcción de tu programa.

Un cordial saludo
  #3 (permalink)  
Antiguo 29/07/2003, 10:19
 
Fecha de Ingreso: julio-2003
Ubicación: Elche
Mensajes: 15
Antigüedad: 20 años, 9 meses
Puntos: 0
Sonrisa

Agradezco tu respuesta, al final he desistido y la estoy haciendo con objetos. De todas formas, muchas gracias....
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 01:03.