PHP - Работа с Файлове: Част 1
В тази първа част от статията ще видите едно идеално приложение на иначе сухата теория за работа с файлове. Ще си направите собствен модул за новини, който може да се използва на хостове без бази данни.
Примерните файлове можете да намерите на сайта на автора.
Преди време, когато започнах да се занимавам с PHP се намираха доста безплатни хостове. Но за съжаление не беше така и с достъпа до MySQL сървърите. Книгата за гости, която си бях подготвил за сайта ми беше
неизпозлваема. Зададох си въпроса – има ли рещение?
Решението е лесно fopen(), fread(), fwrite(), file() ... функции в PHP за работа с файлове.
В тази статия ще разгледаме два примера с използването на тези функции.
Първият може да се изпозлва за книга за гости, новини и не знам още какво изпозлвайте въображението си. Втория пример е за проста галерия за снимки.
Пример 1
Преди да започнем да правим каквото и да е трябва да решим какво точно искаме да съхраняваме във файлът. Ето нашата примерна структура на “полетата”:
1. номер - до скоро си мислех, че би трябвало да има, но сега се убеждавам че е излишно по-надолу ще разберем защо;
2. заглавие - хубаво е да има такова поле, все пак преди потребителя да седне да чете нещо трябва да знае за какво се отнася. Заглавие може да има както на мнение така и на новина;
3. дата - все пак трябва да знаем кога е било въведено мненито (новината);
4.текст - то и името си показва текст :)
След като вече сме определили какви данни ще съдържа файлът, време е да решим по какъв начин ще ги съхраняваме. Както се сещате от името на статията и от обясненията до сега ще ги съхраняваме във файл, но от значение е как ще разположим тези данни във файла и после откъде да разберем кое за какво е.
Аз избрах следното решение: номер{sep}заглавие{seр}дата{seр}текст.
{sep} – разделителя между полетата.
Попитахте ли се зашо точно така съм решил?
Тъй като този пример ще е универсален ще става за новини и за други разни неща ще трябва да дефинираме една константа sep define("sep", "|--|") с която да дефинираме този разделител. Избрал съм |--|, защото мисля, че тази поредица от знаци не може да се съдържа в текста на мнението(новината). Така че внимавайте какво ще дефинирате за да не се получи лека грешка.
Дойде време да напишем и първта функция, която ще се изпозлва и в този и следвашия пример.
Фунцкията ще проверява дали файлът е достъпен за четене или писане, защото няма смисъл потребителя да вижда съобшения, че функцията Х дава грешка на ред 34 :)
function checkf($filename, $action) {
if ($action == "write") {
if (is_writable(fdir.$filename.".".ext)) return true;
else return false;
}
else {
if (is_readable(fdir.$filename.".".ext)) return true;
else return false;
}
}
Фунцкията приема 2 параметара име на файла и действие, където дейстивето ако е write проверява дали файлът е достъпен за писане в противен случай проверява за четене.
Ако решите можете да зададете стойност по подразбиране за да направите скрипта по-”дуракоустойчив”.
Както забелязвате в примера има две константи, които не сме дефинирали досега: define("fdir", "./files/") и define("ext", "txt") първата константа: fdir указва пътя до файловете, които ще четем, а втората константа: ext разширенията на файловете. Функциите is_writable() и is_readable() са от PHP функциите за работа с файлове и с тяхна помощ определяме дали файла може да бъде отворен за писане или четене. Те приемат само един параметър името на файла и връщат резултат тип boolean.
След като вече сме определили дали файлът е достъпен можем да визуализираме данните от него. За тази цел ще създадем функция, която ще приема следните параметри:
1.име на файл;
2.начална позиция за четене;
3.брой прочетени резултати;
Параметри 2 и 3 са ни нужни за да страницираме записите си, все пак ако на една страница покажем на потребителя 100 записа малко би се затруднил с четенето. Ето и примерния код:
function readf($filename, $start, $max) {
if ( checkf($filename, "read")) {
$file = @file(fdir.$filename.".".ext);
for ($i = $start; $i < $max; $i++) {
$field = @explode(sep, $file[$i]);
$rdata .= "<a href=\\"".$field[0]."\\" target=\\"".$field[1]."\\">".trim($field[2])."</a><br />\\n";
}
}
else $rdata = "Не може да бъде отворен файлът.";
return $rdata;
}
Както и за предишната функция ще обърнем внимание само на тази част от кода, която има връзка с РНР и работата с файлове.
Първа част на, която ще се спрем е $file = @file(fdir.$filename.".".ext);
Функцията file() приема един параметър и това е пътят до файла, с който искаме да работим. Тази функция връща като резултат масив, чийто елементи са редовете от файла. Ако си спомняте в началото споменах, че няма смисъл от поле за номер, това е така защото тази функция връща масив с данните и няма смисъл да имаме повтарящи се данни. @ пред функцията се изпозлва за да не се показват грешките на екарана, които могат да възникнат(примерно сте въвели да отвори 10 резултата, а във файла има само 4) или както се нарича за подтискане на грешките. След като сме получили масива с данните с помоща на един цикъл for() го обхождаме и визуализираме резулататие.
Втората част е $field = @explode(sep, $file[$i]);
explode() - това не е функция за работа с файлове, но пък ще ни свърши добра работа. Тя разделя даден символен низ (в случая $file[$i]), като за разделител използва константата sep. Резултата от всичко това е нов масив, за който знаем броя елементи, както и кой елемент на какво отговаря (спомняте ли си началото на статията, където определихме номер{sep}заглавие ...). Функцията връща променливата $rdata, която е от тип string. Сигурно сте забелязали, че последния елемент от масива $field (в примера е 2) "минава" през trim() преди да го визуализираме. Това го правим с цел да премахнем \\n - краят на реда.
Последната функция, която ще разгледаме от този пример е функцията за запис на данни във файла. Тя приема 2 параметъра: името на файла и масив с форматирани по подходящият начин данни. Връща като резултат съобщения за успешно или неуспешно записване на данните.
function writef($filename, $arr) {
if ( checkf($filename, "write")) {
$fp = @fopen(fdir.$filename.".".ext, "a");
@fwrite($fp, "\\n".$arr);
@fclose(fdir.$filename.".".ext);
$wdata = "Записването е успешно.";
}
else $wdata = "Нямата право за писане във файлът.";
return $wdata;
}
С помоша на функцията fopen() отваряме файла за запис. Тя приема 2 параметъра: име на файл и метод на отваряне.
Методите са:
r/r+ - отваря файла за четене и позиционира указателя на файла в началото/ и за писане;
w/w+ - отваря файла за четене и позиционира указателя на файла в началото, като променя
големината на файла на 0, ако файла не съществува се опитва да го създаде/ и за писане;
a/a+ - отваря файла за писане и позиционира указателя на файла в края, ако файла не съществува
се опитва да го създаде/ и за четене;
x/x+ - създава и отваря файла за четене, позиционира указателя на файла в началото. ако файлът съществува функцията връща false;
Връща като резултат файлове маниполатор, който се подава като параметър на други функции за работа с файлове като:
fwrite(), fread(), fclose() ... След като сме отворили файла можем да пристипъл към следващата стъпка да запишем данните. Извикваме функцията fwrite(), която освен файлов манипулатор приема и още един параметър, който се записва във файла. Не остава нищо друго освен да затоврим файла като за тази цел изпозлваме fclose() - приема само един параметър файловия маниполатор върнат от функцията fopen().
Пример 2 очаквайте във следващата част на статията.
Примерният файл, който можете да изтеглите от връзката по-долу ще видите как функциите от пример 1 могат да се изпозлват и за друго освен книга за гости.
Малко за част 2: основно ще е сорс код на малка семпла галерия. Идеята ми дойде преди няколко часа, когато един колега се оплака, че отнемало много време да си направиш прост сайт за снимките от една лента.
Файлът със скриптовете можете да свалите ТУК.
Има специални програми за четене на оформени с HTML документи – броузери (browser). Най-популярните са Netscape Communicator и Microsoft Internet Explorer. (Да да)
Нещо тази статия е отпреди 3-4 години май
Мдам, много са стари нещата.
Teri
http://computer.organization/file.htm
не знаех, че има домейн .organization :)
Teri
Предполагам, че това също е неокончателен вариант, затова ще си позволя някои, съвсем добронамерени коментари, нали :)
За браузърите, вместо "Netscape comm" използвай съчетанието "Mozilla семейството", имайки в предвид най-вече Firefox. И не забравяй Opera :)
От редакторите/популярни програми, MS Word генерира ужасен код и никакво съответствие с уеб стандартите, може би по-добър пример?
В графичните файлови формати е просто задължително да се спомене и png, който по много неща превъзхожда gif и jpeg, изпозлва се незаслужено малко, но вече навлиза все-повече и IE го визуализира коректно.
Като цяло наистина добри неща пишеш, възприеми тия забележки като съвсем дружелюбни, подобряващи материала; само така :)
Марио Асенов