Шаг 5
Сериализация.
Ну а как же быть с логином, про него вроде как забыли...
А для этого используем те же возможности php для работы с массивами. А за одно добавим дату сообщения.
В PHP есть одна замечательная функция -
serialize().Она способна упаковать массив так, что его можно будет записать в файл как обычную строку.
Еще там есть не менее замечательная функция -
unserialize(), которая производит обратное действие.
Вот и
воспользуемся оказией.
Сформируем многомерный массив. Первым уровнем у нас пойдут посты, вторым - содержание. Вот такой будет массив:
1
2
3
4
5
6
7
8
9
10
11
|
Array ( [1] => Array ( [date] => 18-02-2010 [name] => Ваша тётя [mess] => Здравствуйте. Не ждали? )
)
|
Тут у нас и дата и имя и текст сообщения - все по полочкам. Теперь нужно такой массив сформировать, упаковать и записать в файл.
А при выводе - распаковать.
Делается это так:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
<?php
/** * The guest book * Гостевая книга * @author IT studio IRBIS-team * @copyright © 2009 IRBIS-team */ ///////////////////////////////////////////////////////// /** * We establish the charset and level of errors * Устанавливаем кодировку и уровень ошибок */ header("Content-Type: text/html; charset=utf-8"); error_reporting(E_ALL); ///////////////////////////////////////////////////////////////// // VARIABLES // ПЕРЕМЕННЫЕ ///////////////////////////////////////////////////////////////// $text1 = !empty($_POST['text1']) ? $_POST['text1'] : null; $text2 = !empty($_POST['text2']) ? $_POST['text2'] : null; $info = array();
///////////////////////////////////////////////////////////////// // SCRIPT // СКРИПТ /////////////////////////////////////////////////////////////////
if(!empty($_POST['ok'])) { if(!$text1) $info[] = 'Текстовое поле не заполнено.'; if(!$text2) $info[] = 'Текстовая область не заполнена.'; if(count($info) == 0) { // Формируем массив поста $posts[1]['date'] = date('d-m-Y'); $posts[1]['name'] = $text1; $posts[1]['mess'] = $text2; // Записываем в файл массив, преобразованный в строку file_put_contents('text.txt', serialize($posts));
header('location: http://'. $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']); exit(); } } else $info[] = 'Напишите что-нибудь'; ///////////////////////////////////////////////////////////////// // VIEW // ОТОБРАЖЕНИЕ ///////////////////////////////////////////////////////////////// ?> <form action="" method="post"> Логин:<br /> <input name="text1" type="text" value="<?php echo htmlspecialchars($text1) ?>"/><br /> Сообщение:<br /> <textarea name="text2" cols="40" rows="10"><?php echo htmlspecialchars($text2);?></textarea><br /> <input name="ok" type="submit" /> </form> <?php
echo implode('<br>', $info) .'<br>';
if(file_exists('text.txt')) { // Читаем файл $array = file_get_contents('text.txt'); // Десереализуем массив $array = unserialize($array); // Берем первый элемент, то есть массив второго уровня $post = $array[1]; // Пишем все в переменные, они пригодятся для форматирования вывода $date = $post['date']; $name = htmlspecialchars($post['name']); $mess = nl2br(htmlspecialchars($post['mess'])); // Ну и сам вывод, что бы красивенько. ?> <div style="border:1px solid; width:70%; background-color:#66FFFF; min-height:100px; margin:5px; padding:5px"> <?php echo $date; ?> / <strong><?php echo $name; ?></strong> <hr width="30%" align="left" /> <?php echo $mess; ?> </div> <?php }
|
Заметьте, мы тут убрали флаг
FILE_APPEND у функции
file_put_contents()
, так как два массива в файл записать нельзя. Вернее, как говорится - съесть то он съесть... только кто ж ему дасть? Записать то можно, а вот прочитать уже не выйдет.
А как же быть с кучей жалоб и предложений, у нас же записывается только одно...
Обратите внимание, что у вложенного массива есть ключ. Это будет идентификатором, своего рода автоинкрементным id. Если увеличивать его с каждой новой записью, внутренний массив не будет перезаписываться, а будет добавляться с новым ключом. По этому он называется "автоинкрементный", то есть "самоувеличивающийся"
Для этого нужно сначала массив считать, вытащить из него все ключи, достать самый большой и увеличить на 1.
А на выводе пройтись по нему циклом
foreach(), доставая по очереди все элементы.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
<?php
/** * The guest book * Гостевая книга * @author IT studio IRBIS-team * @copyright © 2009 IRBIS-team */ ///////////////////////////////////////////////////////// /** * We establish the charset and level of errors * Устанавливаем кодировку и уровень ошибок */ header("Content-Type: text/html; charset=utf-8"); error_reporting(E_ALL); ///////////////////////////////////////////////////////////////// // VARIABLES // ПЕРЕМЕННЫЕ ///////////////////////////////////////////////////////////////// $text1 = !empty($_POST['text1']) ? $_POST['text1'] : null; $text2 = !empty($_POST['text2']) ? $_POST['text2'] : null; $info = array();
///////////////////////////////////////////////////////////////// // SCRIPT // СКРИПТ /////////////////////////////////////////////////////////////////
if(!empty($_POST['ok'])) { if(!$text1) $info[] = 'Текстовое поле не заполнено.'; if(!$text2) $info[] = 'Текстовая область не заполнена.'; if(count($info) == 0) { // Если файл существует if(file_exists('text.txt')) { // Читаем файл и десериализуем массив $posts = unserialize(file_get_contents('text.txt')); // Достаем все ключи в другой массив $keys = array_keys($posts); // Вытаскиваем самый большой элемент и увеличиваем на 1 $id = max($keys) + 1; } // Если файла нет, значит запись № 1 else $id = 1; // Устанавливаем новый ключ $posts[$id]['date'] = date('d-m-Y'); $posts[$id]['name'] = $text1; $posts[$id]['mess'] = $text2; file_put_contents('text.txt', serialize($posts));
header('location: http://'. $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']); exit(); } } else $info[] = 'Напишите что-нибудь'; ///////////////////////////////////////////////////////////////// // VIEW // ОТОБРАЖЕНИЕ ///////////////////////////////////////////////////////////////// ?> <form action="" method="post"> Логин:<br /> <input name="text1" type="text" value="<?php echo htmlspecialchars($text1) ?>"/><br /> Сообщение:<br /> <textarea name="text2" cols="40" rows="10"><?php echo htmlspecialchars($text2);?></textarea><br /> <input name="ok" type="submit" /> </form> <?php
echo implode('<br>', $info) .'<br>'; // Если файл существует if(file_exists('text.txt')) { // Читаем файл и десериализуем массив $array = unserialize(file_get_contents('text.txt')); // Проходим по массиву циклом, вынимая с каждым витком пару ключ => значение foreach($array as $id => $post) { // Тут уже проходили $date = $post['date']; $name = htmlspecialchars($post['name']); $mess = nl2br(htmlspecialchars($post['mess'])); ?> <div style="border:1px solid; width:70%; background-color:#66FFFF; min-height:100px; margin:5px; padding:5px"> <?php echo $date; ?> / <strong><?php echo $name; ?></strong> <hr width="30%" align="left" /> <?php echo $mess; ?> </div> <?php } }
|
Тут нужно отметить один нюансик. Дело в том, что с момента, когда мы считаем файл, до момента, когда перезапишем, пройдет некоторое время. И хотя оно исчисляется микросекундами, существует вероятность так называемого совместного доступа. То есть если в этот момент другой пользователь успеет записать свое сообщение, оно будет перезаписано. И Вы не дождетесь вожделенной благодарности. Можно конечно принять меры, заблокировать файл или вывести нумерацию в отдельный...
Но вероятность совместного доступа в гостевой книге ничтожно мала и мы не будем делать из мухи слона, а то так можно до сервера баз данных досочиняться. К тому же мы чуть позже будем делать более другую книгу, как раз с БД. Там такая оплошность исключена полностью.
Ну вот, уже что то похожее на гостевую книжку. Но это еще далеко не все, слишком просто было бы так от меня отделаться.