Рейтинг@Mail.ru
 

Шаг 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 
         
}  
    }
Тут нужно отметить один нюансик. Дело в том, что с момента, когда мы считаем файл, до момента, когда перезапишем, пройдет некоторое время. И хотя оно исчисляется микросекундами, существует вероятность так называемого совместного доступа. То есть если в этот момент другой пользователь успеет записать свое сообщение, оно будет перезаписано. И Вы не дождетесь вожделенной благодарности. Можно конечно принять меры, заблокировать файл или вывести нумерацию в отдельный...

Но вероятность совместного доступа в гостевой книге ничтожно мала и мы не будем делать из мухи слона, а то так можно до сервера баз данных досочиняться. К тому же мы чуть позже будем делать более другую книгу, как раз с БД. Там такая оплошность исключена полностью.

Ну вот, уже что то похожее на гостевую книжку. Но это еще далеко не все, слишком просто было бы так от меня отделаться.