Рейтинг@Mail.ru
 
Новый урок

Ну, коль скоро мы проникли в админку - посмотрим, что есть там. Первая ссылка в меню - "добавить урок". Ну добавить, так добавить. Сейчас я это и сделаю.

И так, новый урок:

Инициализация переменных.

Есть разные способы инициализации переменных - тернарным оператором, простым условием, с собачкой и даже в цикле. Но вот это:
admin/add_lessons.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24

if (isset($_POST['title']))       
{
$title $_POST['title']; 

if (
$title == ''
{
unset(
$title);
}  

}

/* Если существует в глобальном массиве $_POST['title'] опр. ячейка, то мы создаем простую переменную из неё. Если переменная пустая, то уничтожаем пе
ременную.   */
if (isset($_POST['meta_d']))      {$meta_d $_POST['meta_d']; if ($meta_d == '') {unset($meta_d);}}
if (isset(
$_POST['meta_k']))      {$meta_k $_POST['meta_k']; if ($meta_k == '') {unset($meta_k);}}
if (isset(
$_POST['date']))        {$date $_POST['date']; if ($date == '') {unset($date);}}
if (isset(
$_POST['description'])) {$description $_POST['description']; if ($description == '') {unset($description);}}
if (isset(
$_POST['text']))        {$text $_POST['text']; if ($text == '') {unset($text);}}
if (isset(
$_POST['author']))      {$author $_POST['author']; if ($author == '') {unset($author);}}




просто верх сюреализма. Замечательно, когда для иллюстрации к уроку есть материалы из серии "так делать нельзя".

Разберемся, что же тут не так. Логика очевидна, к тому же прямо прописана в комментарии:
/* Если существует в глобальном массиве $_POST['title'] опр. ячейка, то мы создаем простую переменную из неё.
Если переменная пустая, то уничтожаем переменную. */


Так а зачем создавать, если тут же уничтожаем? Гораздо логичнее не создавать, если не существует в глобальном массиве $_POST['title'] опр. ячейка или она пуста. Это избавит код от избыточности, сделает его читабельным, а сервер освободит от лишних телодвижений.

Хотябы так (всё почище):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

    
if (isset($_POST['title']) && $_POST['title'] != '')       
    {
        
$title $_POST['title']; 
    }

    if (isset(
$_POST['description']) && $_POST['description'] != ''$description $_POST['description']; 
    if (isset(
$_POST['meta_d']) && $_POST['meta_d'] != ''$meta_d $_POST['meta_d']; 
    if (isset(
$_POST['meta_k']) && $_POST['meta_k'] != ''$meta_k $_POST['meta_k']; 
    if (isset(
$_POST['author']) && $_POST['author'] != ''$author $_POST['author'];  
    if (isset(
$_POST['date'])   && $_POST['date']   != ''$date   $_POST['date']; 
    if (isset(
$_POST['text'])   && $_POST['text']   != ''$text   $_POST['text'];


Кроме того, есть замечательная функция empty(), которая сразу проверяет пустоту переменной. Прелесть её в том, что она не вызывает ошибку при обращении к несуществующей переменной. По этому (если предположить, что ни одна из переменных не будет равняться нулю), этот код можно еще сократить, используя empty() с инверсией:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

    
if (!empty($_POST['title']))       
    {
        
$title $_POST['title']; 
    }

    if (!empty(
$_POST['description'])) $description $_POST['description']; 
    if (!empty(
$_POST['meta_d'])) $meta_d $_POST['meta_d']; 
    if (!empty(
$_POST['meta_k'])) $meta_k $_POST['meta_k']; 
    if (!empty(
$_POST['author'])) $author $_POST['author'];  
    if (!empty(
$_POST['date'])) $date   $_POST['date']; 
    if (!empty(
$_POST['text'])) $text   $_POST['text']; 


Хотя этот подход тоже верным назвать нельзя. Ну ладно тут, коду три строчки. А если скрипт будет посерьёзнее? Каждый раз, где потребуется обращение к переменной, придется проверять её наличие. По этому лучше определить её сразу, чтобы потом не беспокоиться. Тут это не критично, исправлять смысла вроде нет. Кому интересно, в наших курсах это описано.

Дальше, та самая проверка:
1
2
3
4
5
6

if (isset($title) && isset($meta_d) && isset($meta_k) && isset($date) && isset($description) && isset($text) && isset($author))
{


Не могу смотреть на такие веревки без умиления. Сразу представляется старательный кодер, который сопя и пыхтя, высунув язык, самозабвенно выводит эти каракули, вместо того, чтобы заглянуть в мануал. А там черным по белому -
1
2
If multiple parameters are supplied then isset() will return TRUE only if all of the parameters are set. 
Что в вольном переводе звучит как
1
2
Если параметрами передается несколько переменных, то isset () вернет TRUE только если все переменные определены.


И если сделать из этого определенные орг-выводы, то этот канат можно переписать так:
1
2
3
4
5
6
7

    
if (isset($title$meta_d$meta_k$date$description$text$author))
    {
/* Здесь пишем что можно заносить информацию в базу */


Урок окончен. По инициализации.

А по коду это далеко не все, причем это были семечки. Настоящие ляпы только начинаются.
Я опущу тот момент, что в базу вносится гипертекст (опираясь на это заявление: Введите полный текст урока с тэгами)
Это отдельная тема, тема безопасности. Фиг с ним, тут есть еще на что обратить внимание.
1
2
3

4
5


$result 
mysql_query ("INSERT INTO lessons (title,meta_d,meta_k,date,description,text,author) 
VALUES ('$title', '$meta_d','$meta_k','$date','$description','$text','$author')"
);


Шедеврально. Наверняка многие, кто собрал свой сайт по этим урокам, сталкивались с такой непонятной проблемой: почему то админка упрямо не хочет воспринимать текст, в котором присутствуют апострофы. Ради интереса попробуйте запостить такой текст урока:
1
2
3
4

Апостроф, это одинарная кавычка. Выглядит так - '. Находится на клавише с буквой "Э" в латинской раскладке.
при выключенных магических кавычках. Получите без объявления войны радостное сообщение с восклицательным знаком:
Ваш урок не добален!

Это зачатки SQL-инъекции. И можете сто раз повторить, что это админка и бояться некого, однако текст то не прошел. А это ляп.

Никогда, ни при каких обстоятельствах, нельзя совать в запрос неподготовленные данные. Как минимум это должно выглядеть так:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

/* Здесь пишем что можно заносить информацию в базу */
        
$result mysql_query ("INSERT INTO lessons 
                               (`title`, `meta_d`, `meta_k`, `date`, `description`, `text`, `author`)
                                VALUES 
                               ('"
mysql_real_escape_string($title) ."',
                                '"
mysql_real_escape_string($meta_d) ."',
                                '"
mysql_real_escape_string($meta_k) ."',
                                '"
mysql_real_escape_string($date) ."',
                                '"
mysql_real_escape_string($description) ."',
                                '"
mysql_real_escape_string($text) ."',
                                '"
mysql_real_escape_string($author) ."'
                                )"
                              
);

А в идеале нужно озаботиться этими самыми магическими кавычками и разграничить типы переменных. Тут на этом подробно останавливаться смысла нет. А вот на следующей строчке есть.
1
2
3
4
5
6

if ($result == 'true') {echo "<p>Ваш урок успешно добален!</p>";}
else {echo 
"<p>Ваш урок не добален!</p>";}


Во первых, с какого перепуга булево значение true превратилось в строку? Благо PHP прощает такую вольность, но до добра эта привычка не доведет.
Должно быть так:
1
2
3
4
5

if ($result === true
А можно проще:
1
2
3
4
5

if ($result


Дальше. По накатанной тропинке идем в мануал, ищем функцию mysql_query() и читаем:
1
2
3
4
5

Значение не равное FALSE говорит о том, что запрос был выполнен успешно. Он не говорит о количестве затронутых или возвращённых рядов. 
Вполне возможна ситуация, когда успешный запрос не затронет ни одного ряда.


А это значит, что однозначно заявлять с ликованием:
Ваш урок успешно добален!
нет никаких оснований. Есть основание констатировать факт, что функция вернула что то, отличное от false.
Проверяется внесение данных в базу другой функцией - mysql_affected_rows(), которая возвращает количество измененных рядов.

Вобщем вот, смотрите и сравнивайте сами:
admin/add_lessons.php
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
<?php
 
include ('./lock.php');
include (
'./blocks/db.php');

    if (!empty(
$_POST['title']))       
    {
        
$title $_POST['title']; 
    }

    if (!empty(
$_POST['description'])) $description $_POST['description']; 
    if (!empty(
$_POST['meta_d'])) $meta_d $_POST['meta_d']; 
    if (!empty(
$_POST['meta_k'])) $meta_k $_POST['meta_k']; 
    if (!empty(
$_POST['author'])) $author $_POST['author'];  
    if (!empty(
$_POST['date'])) $date   $_POST['date']; 
    if (!empty(
$_POST['text'])) $text   $_POST['text']; 


?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Обработчик</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<table width="690" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" class="main_border">
<!--Подключаем шапку сайта-->
<?php include './blocks/header.php';   ?> 
  <tr>
    <td><table width="690" border="0" cellspacing="0" cellpadding="0">
      <tr>
<!--Подключаем левый блок сайта-->
<?php include './blocks/lefttd.php';  ?>      
        <td valign="top">
      
<?php 
    
if (isset($title$meta_d$meta_k$date$description$text$author))
    {
/* Здесь пишем что можно заносить информацию в базу */
        
$result mysql_query ("INSERT INTO lessons 
                               (`title`, `meta_d`, `meta_k`, `date`, `description`, `text`, `author`)
                                VALUES 
                               ('"
mysql_real_escape_string($title) ."',
                                '"
mysql_real_escape_string($meta_d) ."',
                                '"
mysql_real_escape_string($meta_k) ."',
                                '"
mysql_real_escape_string($date) ."',
                                '"
mysql_real_escape_string($description) ."',
                                '"
mysql_real_escape_string($text) ."',
                                '"
mysql_real_escape_string($author) ."'
                                )"
                              
);

        if (
mysql_affected_rows() 0)
            echo 
"<p>Ваш урок успешно добален!</p>";
        else 
            echo 
"<p>Ваш урок не добален!</p>";


    }         
    else 
    {
        echo 
"<p>Вы ввели не всю информацию, поэтому урок в базу не может быть добален.</p>";
    }
     
?>
     </td>
      </tr>
    </table></td>
  </tr>
<!--Подключаем нижний графический элемент-->  
<?php  include './blocks/footer.php'?>  
</table>
</body>
</html> 


А мы продолжим вскрытие.