J'ai besoin d'une fonction comme preg_replace mais au lieu de chaînes j'ai besoin pour travailler avec des fichiers/fichiers.Remplacement de contenu de fichier dans PHP
Répondre
Vous pouvez faire:
$file = 'filename';
file_put_contents($file,str_replace('find','replace',file_get_contents($file)));
@ La réponse de codaddict est tout à fait sufficent pour les petits fichiers (et serait comment j'implémenteriez si la taille du fichier était sous MiB). Cependant, il va manger une tonne de mémoire, et en tant que tel, vous devriez être prudent lors de la lecture de gros fichiers.
Si vous voulez une version beaucoup plus conviviale mémoire, vous pouvez utiliser stream filters ...
class ReplaceText_filter extends php_user_filter {
protected $search = '';
protected $replace = '';
public function filter($in, $out, &$consumed, $closing) {
while ($bucket = stream_bucket_make_writable($in)) {
$bucket->data = str_replace(
$this->search,
$this->replace,
$bucket->data
);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
public function onCreate() {
if (strpos($this->filtername, '.') === false) return false;
list ($name, $arguments) = explode('.', $this->filtername, 2);
$replace = '';
$search = $arguments;
if (strpos($arguments, '|') !== false) {
list ($search, $replace) = explode('|', $arguments, 2);
}
if (strpos($search, ',') !== false) {
$search = explode(',', $search);
}
if (strpos($replace, ',') !== false) {
$search = explode(',', $replace);
}
$this->search = $search;
$this->replace = $replace;
}
}
stream_filter_register('replacetext.*', 'ReplaceText_Filter');
Ainsi, vous pouvez ajouter un filtre de flux arbitraire. le nom détermine les arguments du filtre:
$search = 'foo';
$replace = 'bar';
$name = 'replacetext.'.$search.'|'.$replace;
stream_filter_append($stream, $name);
ou pour les tableaux,
$search = array('foo', 'bar');
$replace = array('bar', 'baz');
$name = 'replacetext.'.implode(',', $search).'|'.implode(',', $replace);
stream_filter_append($stream, $name);
Évidemment, cela est un exemple très simple (et ne fait pas beaucoup d'erreurs de vérification), mais il vous permet de faire quelque chose comme ceci:
$f1 = fopen('mysourcefile', 'r');
$f2 = fopen('mytmpfile', 'w');
$search = array('foo', 'bar');
$replace = array('bar', 'baz');
$name = 'replacetext.'.implode(',', $search).'|'.implode(',', $replace);
stream_filter_append($f1, $name);
stream_copy_to_stream($f1, $f2);
fclose($f1);
fclose($f2);
rename('mytmpfile', 'mysourcefile');
et qui gardera utilisation de la mémoire très faible lors du traitement de fichiers potentiellement énormes (GIB) ... TiB
Oh, et l'autre chose sympa, c'est qu'il peut modifier différents types de flux. Ce que je veux dire par là, c'est que vous pouvez lire à partir d'un flux HTTP, éditer en ligne, et écrire dans un flux de fichier. C'est assez puissant (comme vous pouvez enchaîner ces filtres) ...
Le seul problème avec cette réponse est lorsque les termes de recherche sont situés dans des compartiments, en particulier lorsqu'il s'agit de fichiers de plus de 8 KiB. – bit2shift
Vous pouvez tirer le contenu du fichier dans une variable en le bouclant à l'aide de fread, puis travailler avec preg_replace comme vous le feriez avec une chaîne de texte? – Chris
Oui, mais le contenu mis à jour doit être écrit dans les fichiers d'où il provient. –
Alors, quel est le problème pour écrire le contenu dans le fichier? –