Когато работите с малки количества данни в PHP, понякога е по-лесно да ги съхранявате във файлове, отколкото да създавате база данни и да организирате взаимодействието на скриптове с нея. В такива случаи задачата за изтриване на определени редове от текстов файл не е необичайна. Нека разгледаме по-отблизо най-простия възможен начин за това.
Необходимо
Основни познания по PHP
Инструкции
Етап 1
Първоначални данни:
- имаме текстов файл allStrings.txt, който съдържа редица редове с данни
- изисква се изтриване на ред No 44 от файла
Алгоритъмът за решаване на проблема ще бъде следният: трябва да отворите файла, да прочетете съдържащите се в него редове в масив от низове и да презапишете съществуващия файл със съдържанието на масива, като пропуснете реда, предназначен за изтриване.
Стъпка 2
За да приложим този алгоритъм в скрипта, първо присвояваме стойности на променливи, които ще съдържат името на изходния файл и номера на реда, който трябва да бъде изтрит: $ fileName = "allStrings.txt";
$ lineToKill = 44; Тогава нека прочетем файла в масив от низове: $ stringsArray = файл ($ fileName); Нека проверим дали файлът съдържа реда, от който се нуждаем. Всички допълнителни кодове ще бъдат изпълнени само ако условието $ lineToKill не е повече от броя на редовете в масива $ stringsArray: if ($ lineToKill <= count ($ stringsArray)) {
// това ще бъде основният цикъл на програмата
} Ако условието не е изпълнено, няма какво да изтриваме. Нека скриптът отпечата информационно съобщение за това: else echo "Броят на редовете във файла е по-малък от". $ LineToKill. "!"; Ако условието е изпълнено, трябва да изчистите изходния файл за нов запис: $ fileHandle = fopen ($ fileName, "w"); Сега трябва да организираме цикъл, който да итерира върху всички елементи на масива от низове. Но тъй като индексирането на масива започва от нула и сме преброили номера на реда за изтриване от един, тогава още преди началото на цикъла ще намалим стойността на $ lineToKill с едно, за да не повтаряме тази операция на всяка стъпка: $ lineToKill -; За да организирате цикъл: foreach ($ stringsArray като $ key => $ value) {
// тук е кодът на всяка стъпка от цикъла
} Променливата $ key ще съдържа индекса на текущия ред в масива, а променливата $ value ще съдържа стойността на този ред. На всяка стъпка от цикъла ще сравняваме индекса на реда в масива с номера, който трябва да бъде изтрит, и ако те не съвпадат, тогава ще запишем стойността на този ред във файла: if ($ key! = $ LineToKill) fwrite ($ fileHandle, $ value); А ако те съвпадат, тогава няма да пишем във файла, а ще отпечатаме съобщение за успешно изтриване: else echo "Line". $ LineToKill. "Delete."; И в края на цикъла, когато записването във файла приключи, трябва учтиво да го затворите: fclose ($ fileHandle);
Стъпка 3
Пълният код ще изглежда така: <? Php $ fileName = "allStrings.txt";
$ lineToKill = 44; $ stringsArray = файл ($ fileName);
if ($ lineToKill <= count ($ stringsArray)) {
$ fileHandle = fopen ($ fileName, "w");
$ lineToKill--;
foreach ($ stringsArray като $ key => $ value) {
ако ($ ключ! = $ lineToKill) fwrite ($ fileHandle, $ стойност);
else echo "Line". $ lineToKill. "delete.";
}
fclose ($ fileHandle);
}?> Разбира се, това е най-простият код, в който няма защита срещу всички усложнения, които могат да възникнат по време на работата на скрипта в реални условия. Например, ако файлът съдържа огромен брой редове, след това четенето им в масив ще отхапи парче, което е недопустимо голямо за един скрипт от сървърните ресурси. Разбира се, работата с големи количества данни трябва да бъде организирана чрез бази данни, а не текстови файлове. Но все пак като образователен пример ще дадем код, който решава и този проблем. Тук алгоритъмът ще се различава от предишния: за да не съхранява огромен брой редове в масива, скриптът ще чете от изходния файл по един ред и ще ги записва един по един във временния файл. В края на този процес оригиналният файл ще бъде изтрит и временният файл ще бъде преместен на мястото му.
Стъпка 4
Този скрипт ще започне по същия начин като предишния:
$ fileName = "allStrings.txt";
$ lineToKill = 44;
След това трябва да създадете временен файл, който да работи. Нека го направим в папката "tmp" и да дадем същия префикс на временния файл: $ tempFile = tempnam ("/ tmp", "tmp"); Сега нека се опитаме да отворим изходния файл за четене: if ($ fileHandle = @fopen ($ fileName, "rb")) {
// този код ще бъде изпълнен в случай на нормално отваряне на изходния файл
} Ако това не успее - по-нататъшната работа на скрипта няма смисъл, ние убиваме процеса с издаването на съответното съобщение: else die ("Изходният файл не съществува!"); Ако файлът е отворен нормално, тогава ние ще отпечата известие за това и ще се опита да отвори създадения по-рано временен файл със съответно съобщение: echo "Изходният файл съществува";
if ($ tempHandle = fopen ($ tempFile, "w")) echo "Създаден е временен файл."; Сега е време да започнем цикъл от редове за четене от изходния файл, който ще продължи, докато достигне края на файлът: while (! feof ($ fileHandle)) {
// тук ще бъде кодът за работа с текущия ред
} На всяка стъпка от цикъла ще четем по един ред: $ lineToWrite = fgets ($ fileHandle); И ако това не е редът, който трябва да бъде изтрит, тогава го запишете във временен файл. Броячът на редове $ lineNum ще бъде увеличен директно в операцията за сравнение: if ($ lineToKill! = (++ $ lineNum)) fwrite ($ tempHandle, $ lineToWrite); Когато редовете изтекат, затворете файла: fclose ($ fileHandle);
fclose ($ tempHandle); И накрая, преименувайте временния файл на оригиналния. Ако тази операция е успешна, тогава ще издадем съответно съобщение: if (rename ($ tempFile, $ fileName)) echo "Редът $ lineToKill е изтрит";
Стъпка 5
Пълен код:
<? php $ fileName = "allStrings.txt";
$ lineToKill = 44; $ tempFile = tempnam ("/ tmp", "tmp");
if ($ fileHandle = @fopen ($ fileName, "rb")) {
echo "Изходният файл съществува";
ако ($ tempHandle = fopen ($ tempFile, "w")) echo "Временният файл е създаден.";
}
else die ("Изходният файл не съществува!"); while (! feof ($ fileHandle)) {
$ lineToWrite = fgets ($ fileHandle);
ако ($ lineToKill! = (++ $ lineNum)) fwrite ($ tempHandle, $ lineToWrite);
} fclose ($ fileHandle);
fclose ($ tempHandle);
if (rename ($ tempFile, $ fileName)) echo "Линията $ lineToKill е премахната";?>