Tractament de fitxers
La gestió de fitxers a nivell de lectura i escriptura a PHP es realitza a través d'un model de recurs de fitxer o punta de fitxer (file pointer). Aquest model garanteix un control precís sobre el fitxer durant el procés, essent crucial per a l'eficiència i la integritat de les dades.
Model fitxers: Obrir, processar i tancar
El procés estàndard i segur per manipular fitxers a PHP es basa en aquest cicle de tres passos:
Obrir el fitxer: fopen()
Aquesta és la funció inicial i la més crítica. fopen() crea un recurs de fitxer (una referència) al sistema operatiu, que s'emmagatzema en una variable PHP (p. ex., $myfile).
-
Sintaxi:
fopen("nom_del_fitxer", "mode") -
Gestió d'Errors: És una bona pràctica afegir
or die(...)per gestionar el cas en què el fitxer no existeixi o l'script no tingui els permisos necessaris.
Processar fitxer (Lectura / Escriptura)
Un cop el fitxer està obert, el mode especificat a fopen() determina quines operacions són possibles i on es posiciona el punta de fitxer (la posició des d'on es començarà a llegir o escriure).
| Funció | Propòsit | Ús Típic |
fread() |
Llegeix el contingut sencer o un nombre específic de bytes. Requereix el filesize() si es vol llegir tot el contingut. |
Llegir el contingut d'un fitxer de configuració petit. |
fgets() |
Llegeix una sola línia de text i mou el punta a la línia següent. | Recórrer fitxers grans (logs, CSV) de forma eficient línia per línia. |
fgetc() |
Llegeix un sol caràcter i mou el punta al caràcter següent. | Anàlisi de fitxers de text caràcter per caràcter. |
fwrite() (No inclòs, però clau) |
Escriu dades al fitxer. La posició depèn del mode (w sobreescriu, a afegeix). |
Guardar logs, desar dades, generar arxius. |
Tancar fitxer: fclose()
Utilitzar fclose($myfile) és obligatori. Tancar el fitxer allibera el recurs del sistema operatiu que estava utilitzant.
-
Motiu: Si no es tanca, altres scripts o processos podrien tenir problemes per accedir al fitxer, o les dades en escriptura podrien no ser desades correctament (no s'efectua el flush complet).
Modes d'obertura
El segon paràmetre de fopen() defineix la capacitat de l'script sobre el fitxer i la gestió del contingut existent.
| Mode | Descripció | Impacte en Dades Existents | Ús Recomendat |
r (Read) |
Només lectura. | Cap (Només llegeix). | Lectura segura i senzilla de fitxers. |
w (Write) |
Només escriptura. | EL CONTINGUT S'ESBORRA (es trunca a mida zero) al obrir. | Crear un fitxer nou o sobreescriure un d'existent. |
a (Append) |
Només escriptura (afegir). | El contingut existent es manté. El punta es mou al final del fitxer. | Guardar logs, afegir registres sense esborrar l'anterior. |
r+ |
Lectura i escriptura. | Cap. Permet llegir, moure el punta i escriure al mig del fitxer. | Modificar dades dins del fitxer sense esborrar-lo sencer. |
w+ |
Lectura i escriptura. | EL CONTINGUT S'ESBORRA (truncat a mida zero) al obrir. | Reescriure un fitxer completament i poder llegir-lo immediatament després. |
x (Exclusive Write) |
Només escriptura. | Crea el fitxer només si no existeix. Falla si ja existeix. | Implementar bloqueig de fitxers o assegurar-se que s'està creant un fitxer nou. |
Lectura línia per línia amb feof()
El mode més eficient per llegir fitxers grans amb PHP és utilitzar un bucle que combina fgets() i feof().
-
feof($myfile)retornaTRUEquan el punta de fitxer ha arribat al final (End Of File). -
En lloc de carregar tot l'arxiu a la memòria amb
fread(..., filesize(...)), el bucle llegeix només una línia a la vegada. Això redueix dràsticament l'ús de memòria del servidor, essent vital per a fitxers de grans dimensions (diversos GB).
Exemple escriptura
Per escriure dades de forma segura, utilitzem el mode w o a:
<?php
$fitxer = 'registre.log';
$text_nou = date('Y-m-d H:i:s') . " - Nou usuari registrat.\n";
// Obrim en mode 'a' (append) per afegir al final
$recurs = fopen($fitxer, "a") or die("No es pot obrir el fitxer.");
// Escrivim el contingut
fwrite($recurs, $text_nou);
// Tanquem el recurs
fclose($recurs);
echo "El registre s'ha guardat correctament.";
?>
Les funcions file_get_contents() i file_put_contents() són els mètodes més ràpids i senzills de PHP per llegir i escriure fitxers complets, ja que gestionen l'obertura, la lectura/escriptura, i el tancament del fitxer de manera automàtica, sense necessitat de fopen(), fread(), i fclose().
Aquestes funcions es coneixen com a eines de processament "atòmic" o d'un sol pas.
Exemple lectura: file_get_contents()
Aquesta funció llegeix el contingut sencer d'un fitxer o una URL i el retorna com una única cadena de caràcters.
Escenari: Llegir un fitxer de configuració JSON
Assumim que tens un fitxer anomenat config.json amb el següent contingut:
{
"db_host": "localhost",
"db_user": "root"
}
<?php
$file_path = 'config.json';
// Comprovem si el fitxer existeix abans de llegir
if (file_exists($file_path)) {
// Llegim tot el contingut del fitxer en una sola variable
$json_string = file_get_contents($file_path);
// Descodifiquem el JSON per utilitzar-lo com un array PHP
$config_data = json_decode($json_string, true);
if ($config_data !== null) {
echo " Configuració carregada amb èxit.<br>";
echo "Host de la base de dades: **" . $config_data['db_host'] . "**<br>";
echo "Usuari de la base de dades: **" . $config_data['db_user'] . "**";
} else {
echo " Error al descodificar el fitxer JSON.";
}
} else {
echo " El fitxer de configuració no existeix.";
}
?>
Exemple escriptura: file_put_contents()
Aquesta funció escriu una cadena de caràcters a un fitxer. Si el fitxer no existeix, el crea. Si ja existeix, per defecte, sobreescriu el contingut existent.
Escenari: Guardar un registre (log)
En aquest exemple, fem servir la flag FILE_APPEND per evitar sobreescriure el contingut i afegir el nou registre al final.
<?php
$log_file = 'activity.log';
// Dades a registrar
$activity = date('Y-m-d H:i:s') . " - El procés s'ha completat correctament.\n";
// Escrivim el contingut al fitxer
// FILE_APPEND: Afegeix el text al final del fitxer en lloc de sobreescriure'l
$result = file_put_contents($log_file, $activity, FILE_APPEND);
if ($result !== false) {
echo " Registre d'activitat guardat amb èxit. S'han escrit **$result** bytes.";
} else {
echo " Error en escriure al fitxer de registre. Revisa els permisos del directori.";
}
// Després d'executar-se, el fitxer 'activity.log' contindrà:
// 2025-10-10 13:20:53 - El procés s'ha completat correctament.
// ... i qualsevol registre anterior
?>
ATENCIÓ: Per a la majoria de tasques de lectura i escriptura de dades simples (logs, JSON, text), file_get_contents() i file_put_contents() són l'opció preferida per la seva simplicitat i eficiència. No obstant això, per a fitxers extremadament grans (GB) o quan calen bloquejos avançats o lectures/escriptures a posicions concretes, les funcions basades en recursos com fopen() són més adequades.
Exemples de lectura clàssics
A continuació, tens tres exemples clàssics de lectura de fitxers en PHP utilitzant el model de recurs (fopen, fread/fgets/fgetc, fclose).
Assumirem que el fitxer dades.txt existeix i conté:
Línia 1: PHP és potent.
Línia 2: L'eficiència és clau.
Línia 3: Final del fitxer.
1. Lectura completa amb fread()
La funció fread() s'utilitza per llegir un bloc de bytes. Per llegir tot el fitxer, es combina amb filesize() per especificar la mida total del fitxer en bytes. Aquest mètode carrega tot el contingut a la memòria RAM.
<?php
$fitxer = 'dades.txt';
// Obrir el fitxer en mode de només lectura ('r')
$recurs = fopen($fitxer, "r") or die("No es pot obrir el fitxer: $fitxer");
// Llegeix TOTS els bytes del fitxer.
// IMPORTANT: filesiz() necessita el nom del fitxer, no el recurs.
$contingut_sencer = fread($recurs, filesize($fitxer));
// Mostrar el contingut
echo "<h2>Lectura Completa amb fread()</h2>";
echo "<pre>" . htmlspecialchars($contingut_sencer) . "</pre>";
// Tancar el recurs
fclose($recurs);
?>
2. Lectura línia a línia amb fgets() i feof()
Aquest és el mètode més recomanat per llegir fitxers de text grans, ja que utilitza menys memòria. fgets() llegeix una sola línia i mou el punter de fitxer. El bucle while(!feof()) s'encarrega d'iterar fins que s'arriba al final del fitxer (EOF).
<?php
$fitxer = 'dades.txt';
// Obrir el fitxer en mode de només lectura ('r')
$recurs = fopen($fitxer, "r") or die("No es pot obrir el fitxer: $fitxer");
echo "<h2>Lectura Línia per Línia amb fgets()</h2>";
// Bucle fins que s'arriba al final del fitxer (EOF)
$linia_num = 1;
while(!feof($recurs)) {
// Llegeix una línia de text
$linea = fgets($recurs);
// Mostrar la línia i el número (amb un salt de línia HTML)
echo "Línia $linia_num: " . htmlspecialchars($linea) . "<br>";
$linia_num++;
}
// Tancar el recurs
fclose($recurs);
?>
3. Lectura caràcter a caràcter amb fgetc()
La funció fgetc() llegeix només el següent caràcter del fitxer i mou el punter una posició. És rarament utilitzada en producció tret que s'estiguin analitzant formats de dades molt específics, ja que és la més lenta de les tres.
<?php
$fitxer = 'dades.txt';
// Obrir el fitxer en mode de només lectura ('r')
$recurs = fopen($fitxer, "r") or die("No es pot obrir el fitxer: $fitxer");
echo "<h2>Lectura Caràcter per Caràcter amb fgetc()</h2>";
echo "<p style='font-family: monospace;'>";
// Bucle fins que s'arriba al final del fitxer (EOF)
while(!feof($recurs)) {
// Llegeix un sol caràcter
$char = fgetc($recurs);
// Si el caràcter és un salt de línia, afegir <br>
if ($char === "\n") {
echo "<br>";
} else {
echo htmlspecialchars($char);
}
}
echo "</p>";
// Tancar el recurs
fclose($recurs);
?>