Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll

Уроки PHP - урок 2 - Работа с файлами: открытие, запись, чтение.

08/12/2019, by Ivan

В прошлом уроке мы сделали каркас для нашей гостевой книги, блога или чата. Теперь остается лишь добавлять функционал. В этом уроке мы будем записывать наши записи в файлы и выводить записи из файлов.

В PHP есть много функций для работы с файлами, мы рассмотрим некоторые из них, скорее всего ваш сайт будет записывать данные в базу данных (в этом я уверен), а не в файлы, поэтому рассмотрим только некоторые из них, чтобы вы поняли суть. А работу с базой данных мы рассмотрим позже.

Итак, если у вас нет файлов, которые мы делали на прошлом уроке, вернитесь на урок назад и скачайте эти файлы.

Давайте перейдем на форму добавления записи:

/index.php?admin=1

С этой формы мы будем добавлять свои записи. Чтобы обрабатывать эти записи, нам нужно проверять на странице index.php (на эту страницу отправляют данные с формы) есть ли значения в переменной $_POST. А проверяется это очень просто:

if($_POST){

}

Не правда ли просто? Теперь внутри фигурных скобок нужно поместить обработку массива $_POST. Мы не будем писать код обработки прямо в фигурных скобках, а вынесем его в наш класс, а саму обработку будем вызывать через метод объекта. В файле index.php вызываем метод:

if($_POST){
 $obj->write($_POST);
}

А в файле simpleCMS.php у нас будет реализация метода write():

  public function write($p) { // метод записи сообщения
  
  }  

Зачем мы это делаем? Затем чтобы сократить код в файле index.php. Файл index.php нужен только для управления, а обработка массивов и вывод данных должен проводиться из другого файла, например файла нашего класса simpleCMS. Это разгранечение позволяет повысить эффективность кода. Если кто-то другой посмотрит на наш код, то он сразу разберется где у нас что лежит. Да и вам самим будет проще разбираться в коде, когда все лежит по полочкам.

Начнем писать обработку с простого, распечатаем наш массив $_POST передаваемый с формы. Для этого нужно вставить этот код:

  public function write($p) { // метод записи сообщения
     print_r($p);
  }  

Как видите мы обращаемся к локальной переменной $p, хотя передается в параметры метода write() суперглобальная переменная. Мы не обращаемся к суперглобальной переменной напрямую, потому что в других случаях мы можем захотеть сделать запись в блоге не через форму, а с помощью получения данных из XML файла. Использование локальной переменной позволяет нам унифицировать использование этого метода, сделать его общим для многих случаев.

Итак, заполняем форму и отправляем ее. У меня получились такие данные:

Array ( [title] => Иван [bodytext] => Привет, Мир! ) 

Если вы заполнили по другому, то и массив у вас будет другой. Мы вывели массив чтобы посмотреть какие ключи мы можем использовать. У нас это $p['title'] и $p['bodytext']. Теперь мы знаем какие у нас будут данные, осталось их записывать в файл. Итак, начинаем с записи в файл.

PHP запись в файл

Прежде, чем записать что-то в файл необходимо его "открыть на запись". Открыть на запись значит связать файл с переменной PHP. Вся работа над файлом в PHP сводится с действиями над переменной типа resource. Сейчас я покажу что это значит:

  public function write($p) { // метод записи сообщения
	$message = fopen("messages/file.txt","w"); 
	print_r($message);
  }  

Для этого я создал файл file.txt в папке messages. И теперь если мы заполним форму и отправим ее, то получим:

Resource id #4

Resource - это тип переменной $message, а 4 это порядковый номер, id нашей переменной среди других переменных resource. И теперь если мы производим действия с перменной $message, то это автоматически отобразится и в файле. Записывать в файл мы будем построчно, чтобы потом также построчно читать из файла:

  public function write($p) { // метод записи сообщения
	$message = fopen("messages/file.txt","w"); 
	fputs ($message, $p['title']. "\r\n");
	fputs ($message, $p['bodytext']);
  }  

Символы \r\n в двойных ковычках (в одинарных может не работать), означают переход на новую строку, в результате в файле file.txt будет такой текст:

Иван
Привет, Мир!

После того как мы произвели все действия с файлом, надо удалить переменную файла, чтобы она не занимала место в оперативной памяти.

  public function write($p) { // метод записи сообщения
	$message = fopen("messages/file.txt","w");  // открываем файл
	fputs ($message, $p['title']. "\r\n");
	fputs ($message, $p['bodytext']);
	fclose ($message); //закрываем файл
  } 

Наверно вы заметили что каждый раз когда мы заново пишем файл, то файл перезаписывается. Это все зависит от параметра в функции fopen. Мы можем также и дозаписывать файл или просто открывать его для чтения. Например так:

$message = fopen("messages/file.txt","r");  // открываем файл только для чтения
  1. r – открытие файла только для чтения.
  2. r+ - открытие файла одновременно на чтение и запись.
  3. w – создание нового пустого файла. Если на момент вызова уже существует такой файл, то он уничтожается.
  4. w+ - аналогичен r+, только если на момент вызова такой файл существует, его содержимое удаляется.
  5. a – открывает существующий файл в  режиме записи, при этом указатель сдвигается на  последний байт файла (на конец файла).
  6. a+ - открывает файл в режиме чтения и записи при этом указатель сдвигается на последний байт файла (на конец файла). Содержимое файла не удаляется.

 

Как написано выше, если мы открываем файл с помощью параметра w, то создается новый файл, имя которого берется из первого параметра. Давайте будем создавать имя файла соответвующее времени, получаемому с помощью функции time().

Функция time() возвращает количество секунд начиная с 1 января 1970 года.

У вас должно получится следующее:

  public function write($p) { // метод записи сообщения
	$message = fopen('messages/'.time(),"w");  // открываем файл
	fputs ($message, $p['title']. "\r\n");
	fputs ($message, $p['bodytext']. "\r\n");
	fputs ($message, time());
	fclose ($message); //закрываем файл
  }  

Таким образом каждую секунду функцией time() будет возращаться все большее количество секунд и имена файлов будут иметь все больше число. Можете попробовать добавить новые записи и новые файлы появятся в папке messages. Теперь осталось читать файлы и выводить наши записи.

PHP чтение файла

Для того чтобы читать из файла, нужно открыть файл на чтение, для этого в функции fopen() мы будем использовать параметр r. Все необходимые нам файлы лежат в папке messages, для того чтобы прочитать все файлы мы будем использовать цикл while (пока файлы не закончатся).

Просматривать файлы в папке мы будем с помощью функции opendir(), которая открывает папку на чтение:

	if (is_dir('messages')) { // проверяем наличие папки
		if ($dh = opendir('messages')) { // открываем папку на чтение
			while (($file = readdir($dh)) !== false) { // пока файлы существуют читаем их
				// выполняем нужные операции
			}
			closedir($dh); //закрываем директорию
		}
	} 

Имена файлов мы получаем с помощью функции readdir(), то есть имена будут храниться в переменной $file. После окончания работы цикла закрываем папку, чтобы освободить место в оперативной памяти.

Теперь когда мы можем прочитать файлы, давайте будет дорабатывать метод display_public():

  public function display_public() { // метод вывода сообщений
    $content = '';
	if (is_dir('messages')) { // проверяем наличие папки
		if ($dh = opendir('messages')) { // открываем папку на чтение
			while (($file = readdir($dh)) !== false) { // пока файлы существуют читаем их
			  if(substr($file, -4) == '.txt'){ // берем только .txt файлы
				$filename = 'messages/' . $file; // полное имя файла
			    $message = fopen($filename, 'r'); // открываем файл
				$title = fgets($message); // читаем первую строку
				$body = fgets($message);  // читаем вторую строку
				$time = fgets($message);  // читаем третью строку
				print '<div class="post">'; // div оборачивающий запись
				print '<span class="time">' . date('d-m-Y', $time) . '</span><h2>' . $title . '</h2>'; 	// выводим время и заголовок
			    print '<p>' . $body . '</p>'; // выводим текст сообщения
				print '</div>'; // конец оборачивающего div'a
				fclose($message); // закрываем файл
			  }	
			}
			closedir($dh); //закрываем директорию
		}
	}   	
	$content .= '<p><a href="/index.php?admin=1">Добавить сообщение</a></p>';
    return $content;
  }

Я прокомментировал каждую строчку, если что-то не понятно, то пишите в комментариях, разъясню.

Не думаю что вам понадобится на практике построчное чтение из файла, но для понимания принципов работы php функций, работы с файлами и папками подобные уроки очень полезны.

Ниже исходных код промежуточного сайта.