Recherche…


Syntaxe

  • int readfile (chaîne $ filename [, bool $ use_include_path = false [, ressource $ context]])

Paramètres

Paramètre La description
nom de fichier Le nom de fichier en cours de lecture.
use_include_path Vous pouvez utiliser le second paramètre facultatif et le définir sur TRUE si vous souhaitez également rechercher le fichier dans le chemin include_path.
le contexte Une ressource de flux de contexte.

Remarques

Syntaxe du nom de fichier

La plupart des noms de fichiers transmis aux fonctions de cette rubrique sont les suivants:

  1. Cordes dans la nature
    • Les noms de fichiers peuvent être transmis directement. Si des valeurs d'autres types sont transmises, elles sont converties en chaîne. Ceci est particulièrement utile avec SplFileInfo , qui est la valeur dans l'itération de DirectoryIterator .
  2. Relatif ou absolu
    • Ils peuvent être absolus. Sur les systèmes de type Unix, les chemins absolus commencent par / , par exemple /home/user/file.txt , tandis que sous Windows, les chemins absolus commencent par le lecteur, par exemple C:/Users/user/file.txt
    • Ils peuvent aussi être relatifs, ce qui dépend de la valeur de getcwd et peut être modifié par chdir .
  3. Accepter les protocoles
    • Ils peuvent commencer par scheme:// pour spécifier l'encapsuleur de protocole à gérer. Par exemple, file_get_contents("http://example.com") extrait le contenu de http://example.com .
  4. Compatible Slash.
    • Bien que DIRECTORY_SEPARATOR sous Windows soit une barre oblique inverse et que le système renvoie par défaut des barres obliques inverses pour les chemins, le développeur peut toujours utiliser / comme séparateur de répertoire. Par conséquent, pour des raisons de compatibilité, les développeurs peuvent utiliser / comme séparateurs de répertoires sur tous les systèmes, mais sachez que les valeurs renvoyées par les fonctions (par exemple, realpath ) peuvent contenir des barres obliques inverses.

Suppression de fichiers et de répertoires

Suppression de fichiers

La fonction unlink supprime un seul fichier et indique si l'opération a réussi.

$filename = '/path/to/file.txt';

if (file_exists($filename)) {
    $success = unlink($filename);
    
    if (!$success) {
         throw new Exception("Cannot delete $filename");
    }
}

Suppression de répertoires avec suppression récursive

D'autre part, les répertoires doivent être supprimés avec rmdir . Cependant, cette fonction ne supprime que les répertoires vides. Pour supprimer un répertoire avec des fichiers, supprimez d'abord les fichiers dans les répertoires. Si le répertoire contient des sous-répertoires, la récursivité peut être nécessaire.

L'exemple suivant analyse les fichiers d'un répertoire, supprime les fichiers / répertoires membres de manière récursive et renvoie le nombre de fichiers (et non de répertoires) supprimés.

function recurse_delete_dir(string $dir) : int {
    $count = 0;

    // ensure that $dir ends with a slash so that we can concatenate it with the filenames directly
    $dir = rtrim($dir, "/\\") . "/";

    // use dir() to list files
    $list = dir($dir);

    // store the next file name to $file. if $file is false, that's all -- end the loop.
    while(($file = $list->read()) !== false) {
        if($file === "." || $file === "..") continue;
        if(is_file($dir . $file)) {
            unlink($dir . $file);
            $count++;
        } elseif(is_dir($dir . $file)) {
            $count += recurse_delete_dir($dir . $file);
        }
    }

    // finally, safe to delete directory!
    rmdir($dir);

    return $count;
}

Fonctions de commodité

IO directe brute

file_get_contents et file_put_contents offrent la possibilité de lire / écrire depuis / vers un fichier vers / depuis une chaîne PHP en un seul appel.

file_put_contents peut également être utilisé avec l' FILE_APPEND pour ajouter au fichier, au lieu de le tronquer et de l'écraser. Il peut être utilisé avec le LOCK_EX pour acquérir un verrou exclusif au fichier tout en procédant à l'écriture. Les indicateurs de masque de bits peuvent être joints au | Opérateur OR ou bitwise.

$path = "file.txt";
// reads contents in file.txt to $contents
$contents = file_get_contents($path);
// let's change something... for example, convert the CRLF to LF!
$contents = str_replace("\r\n", "\n", $contents);
// now write it back to file.txt, replacing the original contents
file_put_contents($path, $contents);

FILE_APPEND est pratique pour ajouter des fichiers journaux alors que LOCK_EX aide à empêcher les conditions de LOCK_EX à l'écriture de fichiers de plusieurs processus. Par exemple, pour écrire dans un fichier journal à propos de la session en cours:

file_put_contents("logins.log", "{$_SESSION["username"]} logged in", FILE_APPEND | LOCK_EX);

CSV IO

fgetcsv($file, $length, $separator)

Le fgetcsv analyse la ligne à partir de la vérification du fichier ouvert pour les champs csv. Il renvoie les champs CSV dans un tableau en cas de succès ou FALSE en cas d'échec.

Par défaut, il ne lit qu'une seule ligne du fichier CSV.

$file = fopen("contacts.csv","r");
print_r(fgetcsv($file));    
print_r(fgetcsv($file,5," "));
fclose($file); 

contacts.csv

Kai Jim, Refsnes, Stavanger, Norway
Hege, Refsnes, Stavanger, Norway

Sortie:

Array
(
    [0] => Kai Jim
    [1] => Refsnes
    [2] => Stavanger
    [3] => Norway
)
Array
(
    [0] => Hege,
)

Lire un fichier sur stdout directement

readfile copie un fichier dans le tampon de sortie. readfile () ne présentera aucun problème de mémoire, même lors de l'envoi de fichiers volumineux, seul.

$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

Ou d'un pointeur de fichier

Sinon, pour rechercher un point dans le fichier pour commencer à copier sur stdout, utilisez plutôt fpassthru . Dans l'exemple suivant, les 1024 derniers octets sont copiés dans stdout:

$fh = fopen("file.txt", "rb");
fseek($fh, -1024, SEEK_END); 
fpassthru($fh);

Lecture d'un fichier dans un tableau

file renvoie les lignes du fichier passé dans un tableau. Chaque élément du tableau correspond à une ligne dans le fichier, avec la nouvelle ligne toujours attachée.

print_r(file("test.txt"));

test.txt

Welcome to File handling
This is to test file handling

Sortie:

Array 
( 
    [0] => Welcome to File handling 
    [1] => This is to test file handling 
)

Obtenir des informations sur le fichier

Vérifier si un chemin est un répertoire ou un fichier

La fonction is_dir renvoie si l'argument est un répertoire, alors que is_file renvoie si l'argument est un fichier. Utilisez file_exists pour vérifier si c'est le cas.

$dir  = "/this/is/a/directory";
$file = "/this/is/a/file.txt";

echo is_dir($dir) ? "$dir is a directory" : "$dir is not a directory", PHP_EOL,
    is_file($dir) ? "$dir is a file" : "$dir is not a file", PHP_EOL,
    file_exists($dir) ? "$dir exists" : "$dir doesn't exist", PHP_EOL,
    is_dir($file) ? "$file is a directory" : "$file is not a directory", PHP_EOL,
    is_file($file) ? "$file is a file" : "$file is not a file", PHP_EOL,
    file_exists($file) ? "$file exists" : "$file doesn't exist", PHP_EOL;

Cela donne:

/this/is/a/directory is a directory
/this/is/a/directory is not a file
/this/is/a/directory exists
/this/is/a/file.txt is not a directory
/this/is/a/file.txt is a file
/this/is/a/file.txt exists

Vérification du type de fichier

Utilisez filetype pour vérifier le type d'un fichier, qui peut être:

  • fifo
  • char
  • dir
  • block
  • link
  • file
  • socket
  • unknown

En passant le nom du fichier à l' filetype directement:

echo filetype("~"); // dir

Notez que filetype renvoie false et déclenche un E_WARNING si le fichier n'existe pas.

Vérification de la lisibilité et de l'écriture

Passer le nom du fichier aux fonctions is_writable et is_readable vérifie si le fichier est accessible en écriture ou en lecture respectivement.

Les fonctions renvoient false si le fichier n'existe pas.

Vérification de l'accès au fichier / modification de l'heure

L'utilisation de filemtime et de fileatime renvoie l'horodatage de la dernière modification ou de l'accès au fichier. La valeur de retour est un horodatage Unix - voir Travailler avec les dates et l'heure pour plus de détails.

echo "File was last modified on " . date("Y-m-d", filemtime("file.txt"));
echo "File was last accessed on " . date("Y-m-d", fileatime("file.txt"));

Obtenir des parties de chemin avec fileinfo

$fileToAnalyze = ('/var/www/image.png');

$filePathParts = pathinfo($fileToAnalyze);

echo '<pre>';
   print_r($filePathParts);
echo '</pre>';

Cet exemple affichera:

Array
(
    [dirname] => /var/www
    [basename] => image.png
    [extension] => png
    [filename] => image
)

Qui peut être utilisé comme:

$filePathParts['dirname']
$filePathParts['basename']
$filePathParts['extension']
$filePathParts['filename']
Paramètre Détails
$ path Le chemin complet du fichier à analyser
option $ Une des quatre options disponibles [PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION ou PATHINFO_FILENAME]
  • Si une option (le second paramètre) n'est pas transmise, un tableau associatif est renvoyé, sinon une chaîne est renvoyée.
  • Ne valide pas que le fichier existe.
  • Simplement analyse la chaîne en parties. Aucune validation n'est faite sur le fichier (pas de vérification de type mime, etc.)
  • L'extension est simplement la dernière extension de $path Le chemin du fichier image.jpg.png serait .png même s'il s'agit techniquement d'un fichier .jpg . Un fichier sans extension ne renverra pas d'élément d'extension dans le tableau.

Réduisez l'utilisation de la mémoire lorsque vous traitez de gros fichiers

Si nous avons besoin d’analyser un fichier volumineux, par exemple un fichier CSV de plus de 10 Mo contenant des millions de lignes, certaines fonctions d’utilisation de file ou de file file_get_contents aboutir à memory_limit paramètre memory_limit avec

Taille de la mémoire autorisée de XXXXX octets épuisés

Erreur. Considérez la source suivante (top-1m.csv a exactement 1 million de lignes et environ 22 Mo de taille)

var_dump(memory_get_usage(true));
$arr = file('top-1m.csv');
var_dump(memory_get_usage(true));

Cela produit:

int(262144)
int(210501632) 

parce que l'interpréteur devait contenir toutes les lignes du tableau $arr , il consommait donc environ 200 Mo de RAM. Notez que nous n'avons même rien fait avec le contenu du tableau.

Considérons maintenant le code suivant:

var_dump(memory_get_usage(true));
$index = 1;
if (($handle = fopen("top-1m.csv", "r")) !== FALSE) {
    while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
        file_put_contents('top-1m-reversed.csv',$index . ',' . strrev($row[1]) . PHP_EOL, FILE_APPEND);
        $index++;
    }
    fclose($handle);
}
var_dump(memory_get_usage(true));

quelles sorties

int(262144)
int(262144)

donc nous n'utilisons pas un seul octet supplémentaire de mémoire, mais nous analysons le CSV entier et le sauvegardons dans un autre fichier en inversant la valeur de la 2ème colonne. C'est parce que fgetcsv ne lit qu'une ligne et que $row est écrasé dans chaque boucle.

Fichier basé sur flux

Ouvrir un flux

fopen ouvre un handle de flux de fichiers, qui peut être utilisé avec différentes fonctions pour la lecture, l'écriture, la recherche et d'autres fonctions. Cette valeur est du type resource et ne peut pas être transmise aux autres threads persistants.

$f = fopen("errors.log", "a"); // Will try to open errors.log for writing

Le deuxième paramètre est le mode du flux de fichiers:

Mode La description
r Ouvrir en mode lecture seule, commençant au début du fichier
r+ Ouvert à la lecture et à l'écriture, à partir du début du fichier
w ouvert uniquement pour l'écriture, commençant au début du fichier. Si le fichier existe, il videra le fichier. S'il n'existe pas, il tentera de le créer.
w+ ouvert pour la lecture et l'écriture, en commençant par le début du fichier. Si le fichier existe, il videra le fichier. S'il n'existe pas, il tentera de le créer.
a ouvrir un fichier pour l'écriture seulement, à partir de la fin du fichier. Si le fichier n'existe pas, il essaiera de le créer
a+ ouvrir un fichier pour la lecture et l'écriture, à partir de la fin du fichier. Si le fichier n'existe pas, il essaiera de le créer
x créer et ouvrir un fichier pour l'écriture uniquement. Si le fichier existe, l'appel fopen échouera
x+ créer et ouvrir un fichier pour la lecture et l'écriture. Si le fichier existe, l'appel fopen échouera
c Ouvrez le fichier pour l'écriture seulement. Si le fichier n'existe pas, il essaiera de le créer. Il commencera à écrire au début du fichier, mais ne videra pas le fichier avant l'écriture
c+ Ouvrez le fichier pour la lecture et l'écriture. Si le fichier n'existe pas, il essaiera de le créer. Il commencera à écrire au début du fichier, mais ne videra pas le fichier avant l'écriture

L'ajout d'un t derrière le mode (par exemple a+b , wt , etc.) dans Windows traduira "\n" fins de ligne en "\r\n" lorsque vous travaillez avec le fichier. Ajoutez b derrière le mode si cela n'est pas prévu, surtout s'il s'agit d'un fichier binaire.

L'application PHP devrait fermer les flux en utilisant fclose lorsqu'ils ne sont plus utilisés pour éviter l'erreur Too many open files . Ceci est particulièrement important dans les programmes CLI, car les flux ne sont fermés que lorsque le runtime est arrêté - cela signifie que dans les serveurs Web, il peut ne pas être nécessaire (mais devrait toujours éviter les fuites de ressources) pour fermer les flux. Si vous ne vous attendez pas à ce que le processus s'exécute pendant une longue période et n'ouvre pas beaucoup de flux.

En train de lire

L'utilisation de fread lira le nombre d'octets donné à partir du pointeur de fichier ou jusqu'à ce qu'un EOF soit atteint.

Lignes de lecture

Utiliser fgets lira le fichier jusqu'à ce qu'une fin de ligne soit atteinte ou que la longueur donnée soit lue.

Les deux fread et fgets se déplace le pointeur de fichier lors de la lecture.

Lire tout ce qui reste

En utilisant stream_get_contents , tous les octets restants dans le flux se retrouveront dans une chaîne et la stream_get_contents .

Réglage de la position du pointeur de fichier

Après avoir ouvert le flux, le pointeur de fichier se trouve au début du fichier (ou à la fin, si le mode a est utilisé). L'utilisation de la fonction fseek déplacera le pointeur de fichier vers une nouvelle position, par rapport à l'une des trois valeurs suivantes:

  • SEEK_SET : c'est la valeur par défaut; le décalage de la position du fichier sera relatif au début du fichier.
  • SEEK_CUR : Le décalage de la position du fichier sera relatif à la position actuelle.
  • SEEK_END : Le décalage de la position du fichier sera relatif à la fin du fichier. Passer un décalage négatif est l'utilisation la plus courante pour cette valeur; il déplacera la position du fichier sur le nombre d'octets spécifié avant la fin du fichier.

rewind est un raccourci pratique de fseek($fh, 0, SEEK_SET) .

Utiliser ftell affichera la position absolue du pointeur de fichier.

Par exemple, le script suivant lit les 10 premiers octets, lit les 10 octets suivants, ignore 10 octets, lit les 10 octets suivants, puis les 10 derniers octets dans file.txt:

$fh = fopen("file.txt", "rb");
fseek($fh, 10); // start at offset 10
echo fread($fh, 10); // reads 10 bytes
fseek($fh, 10, SEEK_CUR); // skip 10 bytes
echo fread($fh, 10); // read 10 bytes
fseek($fh, -10, SEEK_END); // skip to 10 bytes before EOF
echo fread($fh, 10); // read 10 bytes
fclose($fh);

L'écriture

Utiliser fwrite écrit la chaîne fournie dans le fichier en commençant par le pointeur de fichier actuel.

fwrite($fh, "Some text here\n");

Déplacement et copie de fichiers et de répertoires

Copier des fichiers

copy copie le fichier source dans le premier argument à la destination dans le second argument. La destination résolue doit se trouver dans un répertoire déjà créé.

if (copy('test.txt', 'dest.txt')) {
    echo 'File has been copied successfully';
} else {
    echo 'Failed to copy file to destination given.'
}

Copie de répertoires, avec récursivité

La copie de répertoires est assez similaire à la suppression de répertoires, sauf que pour les fichiers, la copy au lieu de la unlink est utilisée, tandis que pour les répertoires, mkdir au lieu de rmdir est utilisé au début au lieu d'être à la fin de la fonction.

function recurse_delete_dir(string $src, string $dest) : int {
    $count = 0;

    // ensure that $src and $dest end with a slash so that we can concatenate it with the filenames directly
    $src = rtrim($dest, "/\\") . "/";
    $dest = rtrim($dest, "/\\") . "/";

    // use dir() to list files
    $list = dir($src);

    // create $dest if it does not already exist
    @mkdir($dest);

    // store the next file name to $file. if $file is false, that's all -- end the loop.
    while(($file = $list->read()) !== false) {
        if($file === "." || $file === "..") continue;
        if(is_file($src . $file)) {
            copy($src . $file, $dest . $file);
            $count++;
        } elseif(is_dir($src . $file)) {
            $count += recurse_copy_dir($src . $file, $dest . $file);
        }
    }

    return $count;
}

Renommer / Déplacer

Renommer / Déplacer des fichiers et des répertoires est beaucoup plus simple. Les répertoires entiers peuvent être déplacés ou renommés en un seul appel, en utilisant la fonction rename .

  • rename("~/file.txt", "~/file.html");

  • rename("~/dir", "~/old_dir");

  • rename("~/dir/file.txt", "~/dir2/file.txt");



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow