Поменять строку в файле php
И из него нужно достать текст, который находится между тегами и .
Проще всего это сделать с помощью регулярных выражений:
Функция preg_match_all() принимает 3 параметра: шаблон поиска, сам текст и переменную, в которую эта функция сохранит результаты поиска.
Поскольку функция возвращает количество найденных строк (или false в случае ошибки), мы можем сразу подставить её в оператор if.
Массив с результатами поиска (в нашем случае $result) состоит из двух частей: в $result[0] будут найденные строки вместе с открывающим и закрывающим тегами span, а в $result[1] будут те же строки без тега span, т.е. тот текст, что находится в круглых скобках.
Маска регулярного выражения находится между вертикальными чертами | . В шаблоне (.*) точка означает любой символ, звёздочка - любое количество символов (т.е. суммарно получаем "любое количество любых символов").
Скобки говорят, что найденный текст нам нужно получить отдельно. Без скобок мы получим только $result[0], а $result[1] не будет существовать.
Чтобы найти только не пустые теги, можно заменить .* на .+ . Плюсик означает любое количество символов, но не меньше одного.
Uis - модификаторы. U означает работу с UTF-8, i - регистронезависимый поиск, s - что символ точка включает в себя переносы строк, т.е. поиск будет по всем строкам, а не по одной.
Продвинутый BBCode с атрибутами
Иногда описанного выше функционала бывает недостаточно, например если нужно передать в функцию какие-либо параметры:
Вместо собственного велосипеда рекомендую использовать готовую библиотеку Shortcode.
В ней из коробки уже есть возможность использования атрибутов, а также события и куча других полезных фишек. Вот как может выглядеть пример обработки тега с атрибутами:
Только нужно учесть, что в Shortcode по-умолчанию парсятся атрибуты в квадратных скобках [] . Я и сам использую квадратные, но в примерах использовал фигурные, чтобы избежать возможных конфликтов тегов на этом сайте.
Функция идентична последовательным успешным вызовам функций fopen() , fwrite() и fclose() .
Если filename не существует, файл будет создан. Иначе, существующий файл будет перезаписан, за исключением случая, если указан флаг FILE_APPEND .
User Contributed Notes 37 notes
File put contents fails if you try to put a file in a directory that doesn't exist. This creates the directory.
function file_force_contents ( $dir , $contents ) $parts = explode ( '/' , $dir );
$file = array_pop ( $parts );
$dir = '' ;
foreach( $parts as $part )
if(! is_dir ( $dir .= "/ $part " )) mkdir ( $dir );
file_put_contents ( " $dir / $file " , $contents );
>
?>
It should be obvious that this should only be used if you're making one write, if you are writing multiple times to the same file you should handle it yourself with fopen and fwrite, the fclose when you are done writing.
file_put_contents() for 1,000,000 writes - average of 3 benchmarks:
real 0m3.932s
user 0m2.487s
sys 0m1.437s
fopen() fwrite() for 1,000,000 writes, fclose() - average of 3 benchmarks:
real 0m2.265s
user 0m1.819s
sys 0m0.445s
function file_force_contents ( $fullPath , $contents , $flags = 0 ) $parts = explode ( '/' , $fullPath );
array_pop ( $parts );
$dir = implode ( '/' , $parts );
if( ! is_dir ( $dir ) )
mkdir ( $dir , 0777 , true );
file_put_contents ( $fullPath , $contents , $flags );
>
file_force_contents ( ROOT . '/newpath/file.txt' , 'message' , LOCK_EX );
?>
Please note that when saving using an FTP host, an additional stream context must be passed through telling PHP to overwrite the file.
/* set the FTP hostname */
$user = "test" ;
$pass = "myFTP" ;
$host = "example.com" ;
$file = "test.txt" ;
$hostname = $user . ":" . $pass . "@" . $host . "/" . $file ;
/* the file content */
$content = "this is just a test." ;
/* create a stream context telling PHP to overwrite the file */
$options = array( 'ftp' => array( 'overwrite' => true ));
$stream = stream_context_create ( $options );
/* and finally, put the contents */
file_put_contents ( $hostname , $content , 0 , $stream );
?>
It's important to understand that LOCK_EX will not prevent reading the file unless you also explicitly acquire a read lock (shared locked) with the PHP 'flock' function.
i.e. in concurrent scenarios file_get_contents may return empty if you don't wrap it like this:
$myfile = fopen ( 'test.txt' , 'rt' );
flock ( $myfile , LOCK_SH );
$read = file_get_contents ( 'test.txt' );
fclose ( $myfile );
?>
If you have code that does a file_get_contents on a file, changes the string, then re-saves using file_put_contents, you better be sure to do this correctly or your file will randomly wipe itself out.
Make sure not to corrupt anything in case of failure.
function file_put_contents_atomically ( $filename , $data , $flags = 0 , $context = null ) if ( file_put_contents ( $filename . "~" , $data , $flags , $context ) === strlen ( $contents )) return rename ( $filename . "~" , $filename , $context );
>
@ unlink ( $filename . "~" , $context );
return FALSE ;
>
This functionality is now implemented in the PEAR package PHP_Compat.
More information about using this function without upgrading your version of PHP can be found on the below link:
It's worth noting that you must make sure to use the correct path when working with this function. I was using it to help with logging in an error handler and sometimes it would work - while other times it wouldn't. In the end it was because sometimes it was called from different paths resulting in a failure to write to the log file.
__DIR__ is your friend.
File put contents fails if you try to put a file in a directory that doesn't exist. This function creates the directory.
file_force_contents ( 'test1.txt' , 'test1 content' ); // test1.txt created
file_force_contents ( 'test2/test2.txt' , 'test2 content' );
// test2/test2.txt created "test2" folder.
file_force_contents ( '~/test3/test3.txt' , 'test3 content' );
// /path/to/user/directory/test3/test3.txt created "test3" folder in user directory (check on linux "ll ~/ | grep test3").
?>
In reply to the previous note:
If you want to emulate this function in PHP4, you need to return the bytes written as well as support for arrays, flags.
I can only figure out the FILE_APPEND flag and array support. If I could figure out "resource context" and the other flags, I would include those too.
define('FILE_APPEND', 1);
function file_put_contents($n, $d, $flag = false) $mode = ($flag == FILE_APPEND || strtoupper($flag) == 'FILE_APPEND') ? 'a' : 'w';
$f = @fopen($n, $mode);
if ($f === false) return 0;
> else if (is_array($d)) $d = implode($d);
$bytes_written = fwrite($f, $d);
fclose($f);
return $bytes_written;
>
>
A more simplified version of the method that creates subdirectories:
function path_put_contents($filePath, $contents, $flags = 0)
if (! is_dir($dir = implode('/', explode('/', $filePath, -1))))
mkdir($dir, 0777, true);
file_put_contents($filePath, $contents, $flags);
>
To upload file from your localhost to any FTP server.
pease note 'ftp_chdir' has been used instead of putting direct remote file path. in ftp_put . remoth file should be only file name
$host = '*****' ;
$usr = '*****' ;
$pwd = '**********' ;
$local_file = './orderXML/order200.xml' ;
$ftp_path = 'order200.xml' ;
$conn_id = ftp_connect ( $host , 21 ) or die ( "Cannot connect to host" );
ftp_pasv ( $resource , true );
ftp_login ( $conn_id , $usr , $pwd ) or die( "Cannot login" );
// perform file upload
ftp_chdir ( $conn_id , '/public_html/abc/' );
$upload = ftp_put ( $conn_id , $ftp_path , $local_file , FTP_ASCII );
if( $upload ) < $ftpsucc = 1 ; >else < $ftpsucc = 0 ; >
// check upload status:
print (! $upload ) ? 'Cannot upload' : 'Upload complete' ;
print "\n" ;
// close the FTP stream
ftp_close ( $conn_id );
?>
I'm updating a function that was posted, as it would fail if there was no directory. It also returns the final value so you can determine if the actual file was written.
public static function file_force_contents($dir, $contents) $parts = explode('/', $dir);
$file = array_pop($parts);
$dir = '';
foreach($parts as $part) if (! is_dir($dir .= "/")) mkdir($dir);
>
return file_put_contents("", $contents);
>
I suggest to expand file_force_contents() function of TrentTompkins at gmail dot com by adding verification if patch is like: "../foo/bar/file"
if (strpos($dir, "../") === 0)
$dir = str_replace("..", substr(__DIR__, 0, strrpos(__DIR__, "/")), $dir);
file_put_contents does not issue an error message if file name is incorrect(for example has improper symbols on the end of it /n,/t)
that is why use trim() for file name.
$name=trim($name);
file_put_contents($name,$content);
I had some troubles using file_put_contents with an absolute but no canonicalized path (eg. w:/htdocs/pri/../test/log.txt): on windows environment php was unable to create the file also using the realpath function .
I had to use fopen and frwite functions to write the data.
I wrote this script implementing the file_put_contents() and file_get_contents() functions to be compatible with both php4.* and php 5.*. It is a PHP Command line interface script which searches and replaces a specific word recursively through all files in the supplied directory hierarchy.
Usage from a Linux command line: ./scriptname specifieddirectory searchString replaceString
if( $argc != 4 )
echo "This command replaces a search string with a replacement string\n for the contents of all files in a directory hierachy\n" ;
echo "command usage: $argv [ 0 ] directory searchString replaceString\n" ;
echo "\n" ;
exit;
>
?>
if (! function_exists ( 'file_put_contents' )) function file_put_contents ( $filename , $data ) $f = @ fopen ( $filename , 'w' );
if (! $f ) return false ;
> else $bytes = fwrite ( $f , $data );
fclose ( $f );
return $bytes ;
>
>
>
function get_file_contents ( $filename )
/* Returns the contents of file name passed
*/
if (! function_exists ( 'file_get_contents' ))
$fhandle = fopen ( $filename , "r" );
$fcontents = fread ( $fhandle , filesize ( $filename ));
fclose ( $fhandle );
>
else
$fcontents = file_get_contents ( $filename );
>
return $fcontents ;
>
?>
function openFileSearchAndReplace ( $parentDirectory , $searchFor , $replaceWith )
//echo "debug here- line 1a\n";
//echo "$parentDirectory\n";
//echo "$searchFor\n";
//echo "$replaceWith\n";
if ( $handle = opendir ( " $parentDirectory " )) while ( false !== ( $file = readdir ( $handle ))) if (( $file != "." && $file != ".." ) && ! is_dir ( $file )) chdir ( " $parentDirectory " ); //to make sure you are always in right directory
// echo "$file\n";
$holdcontents = file_get_contents ( $file );
$holdcontents2 = str_replace ( $searchFor , $replaceWith , $holdcontents );
file_put_contents ( $file , $holdcontents2 );
// echo "debug here- line 1\n";
// echo "$file\n";
>
if( is_dir ( $file ) && ( $file != "." && $file != ".." ))
$holdpwd = getcwd ();
//echo "holdpwd = $holdpwd \n";
$newdir = " $holdpwd " . "/ $file " ;
//echo "newdir = $newdir \n"; //for recursive call
openFileSearchAndReplace ( $newdir , $searchFor , $replaceWith );
//echo "debug here- line 2\n";
//echo "$file\n";
>
>
closedir ( $handle );
>
>
$parentDirectory2 = $argv [ 1 ];
$searchFor2 = $argv [ 2 ];
$replaceWith2 = $argv [ 3 ];
//Please do not edit below to keep the rights to this script
//Free license, if contents below this line is not edited
echo "REPLACED\n' $searchFor2 ' with ' $replaceWith2 ' recursively through directory listed below\nFor all files that current user has write permissions for\nDIRECTORY: ' $parentDirectory2 '\n" ;
echo "command written by Kolapo Akande :) all rights reserved :)\n" ;
$holdpwd = getcwd ();
//echo "$holdpwd\n";
chdir ( $parentDirectory2 );
openFileSearchAndReplace ( $parentDirectory2 , $searchFor2 , $replaceWith2 );
exit;
?>
Как заменить определенную строку с помощью PHP. Я не знаю номера линии. Я хочу заменить строку, содержащую определенное слово.
один подход, который вы можете использовать для небольших файлов, которые могут поместиться в вашу память дважды:
краткое Примечание, PHP > 5.3.0 поддерживает лямбда-функции, поэтому вы можете удалить объявление именованной функции и сократить карту до:
теоретически вы можете сделать это одним (труднее следовать) PHP-заявлением:
другой (менее интенсивный) подход, который вы должны использовать для больших файлов:
вы должны перезаписать весь файл.
Итак, для относительно небольшого файла,чтение файла в массив, поиск слова, заменить найденную строку, написать все остальное на .
для большого файла алгоритм немного отличается, но в целом такой же.
вот почему мы предпочитаем базы данных.
вы также можете использовать многострочный режим с регулярными выражениями
это, конечно, предполагая, что это меньший документ, готовый и загруженный. В противном случае, другие ответы гораздо более "реальные" решения.
Теперь $newdata содержит содержимое файла в виде массива (используйте implode() Если вы не хотите array) со строкой, содержащей "replaceme", замененной на "withme".
если вы не знаете строку, вам придется искать по всем строкам.
если вы повторяете, просто используйте strpos и замените строку, как только она не вернет FALSE. Затем сохраните файл обратно на диск.
это хорошо, если вы ищете подстроку (ID) в строке и хотите заменить старую строку новой строкой.
код:
пример:
запуск кода изменит файл на:
ID, профессия
123,программист
124, слой кирпича
может это поможет:
вы можете превратить файл в массив, используя explode(); функция, редактировать любой элемент в массиве, используйте implode(); функция, чтобы превратить массив обратно в строку, то вы можете поместить строку обратно в файл с помощью . Это показано в следующей функции :
каков наилучший способ перезаписи определенной строки в файле? Я в основном хочу найти файл для строки "@parsethis " и перезаписать остальную часть этой строки чем-то другим.
Если файл не слишком большой, лучшим способом, вероятно, было бы прочитать файл в массив строк с file () поиск по массиву строк для строки и редактировать эту линию, затем implode () массив и fwrite() он возвращается в файл.
Если файл действительно большой (файлы журналов или что-то вроде этого), и вы готовы пожертвовать скоростью для потребления памяти, вы можете открыть два файла и по существу сделать трюк Джереми Рутен предложено использовать файлы вместо системной памяти.
ваша главная проблема заключается в том, что новая строка может быть не такой же длины, как старая. Если вам нужно изменить длину строки, нет никакого способа переписать хотя бы весь файл после измененной строки. Самый простой способ-создать новый, измененный файл, а затем переместить его поверх оригинала. Это есть полный файл доступен для читателей. Используйте блокировку, чтобы убедиться, что только один скрипт изменяет файл сразу, и так как вы собираетесь замените файл, сделайте блокировку на другом файле. Проверьте flock() .
если вы уверены, что новая строка будет такой же длины, как и старая, вы можете открыть файл в режиме чтения/записи (используйте r+ в качестве второго аргумента fopen() ) и вызов ftell() сохранить позицию линия начинается каждый раз перед вызовом fgets() читать линию. Как только вы найдете строку, которую хотите перезаписать, вы можете использовать fseek() вернуться к началу строки и fwrite() новые данные. Один из способов заставить линию всегда быть одинаковой длины-это разместить ее на максимально возможной длине.
или если ваш файл не слишком большой:
Я бы, скорее всего, сделал то, что предложил Джереми, но только для альтернативного способа сделать это здесь другое решение. Это не было протестировано или использовано и предназначено для систем *nix.
Эта функция возвращает строку или массив, в котором все вхождения search в subject заменены на replace .
Если не нужны сложные правила поиска/замены (например, регулярные выражения), использование этой функции предпочтительнее preg_replace() .
Замена текста собственной функцией (preg_replace_callback)
Самое вкусное. Допустим, мы хотим использовать на сайте что-то вроде BBCode, т.е. собственные теги, которые потом должны заменяться на обычный HTML код:
Заменить тег на обычный HTML тег можно так:
Функция preg_replace_callback передаёт каждую найденную строку в нашу безымянную функцию, затем заменяет найденный текст на то, что наша функция возвращает.
Не знаком с безымянными функциями? Тогда можно сделать так:
Вторым параметром передаём название нашей функции. Код отработает точно также, как и предыдущий.
Список параметров
Если search и replace - массивы, то str_replace() использует каждое значение из соответствующего массива для поиска и замены в subject . Если в массиве replace меньше элементов, чем в search , в качестве строки замены для оставшихся значений будет использована пустая строка. Если search - массив, а replace - строка, то эта строка замены будет использована для каждого элемента массива search . Обратный случай смысла не имеет.
Если search или replace являются массивами, их элементы будут обработаны от первого к последнему.
Искомое значение, также известное как needle (иголка). Для множества искомых значений можно использовать массив.
Значение замены, будет использовано для замены искомых значений search . Для множества значений можно использовать массив.
Строка или массив, в котором производится поиск и замена, также известный как haystack (стог сена).
Если subject является массивом, то поиск с заменой будет осуществляться над каждым элементом subject , а результатом функции также будет являться массив.
Если передан, то будет установлен в количество произведенных замен.
Примечания
Замечание: Эта функция безопасна для обработки данных в двоичной форме.
Так как str_replace() осуществляет замену слева направо, то при использовании множественных замен она может заменить ранее вставленное значение на другое. Смотрите также примеры на этой странице.
Замечание:
Эта функция чувствительна к регистру. Используйте str_ireplace() для замены, нечувствительной к регистру.
Примечания
Замечание: Эта функция безопасна для обработки данных в двоичной форме.
Для этой функции вы можете использовать URL в качестве имени файла, если была включена опция fopen wrappers. Смотрите более подробную информацию об определении имени файла в описании функции fopen() . Смотрите также список поддерживаемых обёрток URL, их возможности, замечания по использованию и список предопределённых констант в разделе Поддерживаемые протоколы и обёртки.
Вывод фрагментов исходного HTML и PHP кода
Частая проблема разработчиков, которым хочется вести свой блог. Есть HTML статья, внутри которой некоторые фрагменты кода нужно прогонять через htmlspecialchars() , чтобы они выводились как обычный текст:
Теперь в этом нет ничего сложного:
Возвращаемые значения
Эта функция возвращает строку или массив с замененными значениями.
Примеры
// присваивает: Hll Wrld f PHP
$vowels = array( "a" , "e" , "i" , "o" , "u" , "A" , "E" , "I" , "O" , "U" );
$onlyconsonants = str_replace ( $vowels , "" , "Hello World of PHP" );
// присваивает: You should eat pizza, beer, and ice cream every day
$phrase = "You should eat fruits, vegetables, and fiber every day." ;
$healthy = array( "fruits" , "vegetables" , "fiber" );
$yummy = array( "pizza" , "beer" , "ice cream" );
$newphrase = str_replace ( $healthy , $yummy , $phrase );
// присваивает: 2
$str = str_replace ( "ll" , "" , "good golly miss molly!" , $count );
echo $count ;
?>
// Порядок замены
$str = "Строка 1\nСтрока 2\rСтрока 3\r\nСтрока 4\n" ;
$order = array( "\r\n" , "\n" , "\r" );
$replace = '
' ;
// Обрабатывает сначала \r\n для избежания их повторной замены.
echo $newstr = str_replace ( $order , $replace , $str );
// Выводит F, т.к. A заменяется на B, затем B на C, и так далее.
// В итоге E будет заменено F, так как замена происходит слева направо.
$search = array( 'A' , 'B' , 'C' , 'D' , 'E' );
$replace = array( 'B' , 'C' , 'D' , 'E' , 'F' );
$subject = 'A' ;
echo str_replace ( $search , $replace , $subject );
// Выводит: яблорехкорех орех (по вышеуказанной причине)
$letters = array( 'я' , 'о' );
$fruit = array( 'яблоко' , 'орех' );
$text = 'я о' ;
$output = str_replace ( $letters , $fruit , $text );
echo $output ;
?>
Смотрите также
- fopen() - Открывает файл или URL
- fwrite() - Бинарно-безопасная запись в файл
- file_get_contents() - Читает содержимое файла в строку
- stream_context_create() - Создаёт контекст потока
Простая замена текста или тегов (preg_replace)
Заменить текст без замены тегов можно следующим образом:
$1 и $2 содержат открывающий и закрывающий теги соответственно, поскольку мы поместили их в скобки.
А в следующем примере меняются только теги, сам текст остаётся нетронутым:
Примеры
$file = 'people.txt' ;
// Открываем файл для получения существующего содержимого
$current = file_get_contents ( $file );
// Добавляем нового человека в файл
$current .= "John Smith\n" ;
// Пишем содержимое обратно в файл
file_put_contents ( $file , $current );
?>?php
$file = 'people.txt' ;
// Новый человек, которого нужно добавить в файл
$person = "John Smith\n" ;
// Пишем содержимое в файл,
// используя флаг FILE_APPEND для дописывания содержимого в конец файла
// и флаг LOCK_EX для предотвращения записи данного файла кем-нибудь другим в данное время
file_put_contents ( $file , $person , FILE_APPEND | LOCK_EX );
?>?php
Возвращаемые значения
Функция возвращает количество записанных байт в файл, или false в случае возникновения ошибки.
Эта функция может возвращать как логическое значение false , так и значение не типа boolean, которое приводится к false . За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.
Список параметров
Путь к записываемому файлу.
Записываемые данные. Может быть типа string , array или ресурсом потока.
Если data является потоковым ресурсом ( stream ), оставшийся буфер этого потока будет скопирован в указанный файл. Это похоже на использование функции stream_copy_to_stream() .
Также вы можете передать одномерный массив в качестве параметра data . Это будет эквивалентно вызову file_put_contents($filename, implode('', $array)) .
Значением параметра flags может быть любая комбинация следующих флагов, соединённых бинарным оператором ИЛИ ( | ).
Флаг | Описание |
---|---|
FILE_USE_INCLUDE_PATH | Ищет filename в подключаемых директориях. Подробнее смотрите директиву include_path. |
FILE_APPEND | Если файл filename уже существует, данные будут дописаны в конец файла вместо того, чтобы его перезаписать. |
LOCK_EX | Получить эксклюзивную блокировку на файл на время записи. Другими словами, между вызовами fopen() и fwrite() произойдёт вызов функции flock() . Это не одно и то же, что вызов fopen() с флагом "x". |
Корректный ресурс контекста, созданный с помощью функции stream_context_create() .
Читайте также: