Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Другие темы раздела
PHP Методы гет и пост https://www.cyberforum.ru/php-beginners/thread648092.html
Какой смысл передавать данные методом гет? Какие плюсы этого метода?
PHP Создание файла через FTP Соединение
Есть скрипт: $fp = fopen("ftp://$user:$password@$ftp_server/$file", 'w'); fwrite($fp,'new_text'); fclose($fp); Проблема стоит в том что файл создается пустой... Не могу понять...
PHP Ошибка "Cannot modify header information"
Привет, недавно и совершенно неожиданно для себя (так как я никогда раньше не редактировал index.php, functions.php или что-нибудь ещё, т.к. это не мой уровень) получил эту достаточно...
PHP Задание определенного цвета прозрачным Имею изображение, как мне у него определенному цвету (ну допустим #ссс) назначить прозрачный цвет, ну естественно нужно чтобы поняли все браузеры. Вот у меня выводится изображение <img... https://www.cyberforum.ru/php-beginners/thread647917.html
PHP Генерация страниц https://www.cyberforum.ru/php-beginners/thread647912.html
Всем привет! Ребят, подскажите кто знает, как лучше. Делаю сайт, встал вопрос, в корневой каждую страницу создавать отдельно или лучше генерить из админки. Страниц будет порядка сотни. Если второй...
PHP+AJax PHP
Ребята, помогите пожалуйста, нужно создать таблицу, что бы обновлялась при добавлении информации в базу данных, тоисть я добавляю строку в базу а на странице онлайн добавляется строка... короче в...
PHP php и Crop изображения 1:1
И снова здрасти :) Нужна маленькая помощь, есть скрипт, который методом "post" получает Картинку, обрезает ее и создает миниатюру. Все после этого сохраняет. Нужна помощь. Как сделать ровную...
PHP Преобразование времени как время полученное функцией time() в виде 1231231231 преобразовать в 00:00:00 ?? Добавлено через 17 минут разорбрался, не актуально https://www.cyberforum.ru/php-beginners/thread647790.html
PHP Ограничить число запросов к серверу https://www.cyberforum.ru/php-beginners/thread647781.html
Существует ли надежный способ как-то идентифицировать клиентскую машину, чтобы ограничить количество запросов этого клиента за определенное время? Без использования сессий. Кроме попытки определить...
PHP Сортировка массива Имеется массив вида $users_meta (array( => => "1" => "02" => "09" => "1960" => => "2" https://www.cyberforum.ru/php-beginners/thread647677.html
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16807 / 6687 / 877
Регистрация: 12.06.2012
Сообщений: 19,959
Завершенные тесты: 1
17.09.2012, 13:08  [ТС] 0

FAQ по распространенным ошибкам

17.09.2012, 13:08. Просмотров 40332. Ответов 8
Метки (Все метки)

Ответ

Несколько слов об ошибках Попова.
В сети, среди web-программистов, хорошо известен некий Евгений Попов, автор серии видеоуроков, любимец новичков и противоположность для программистов со стажем..
Итак, начнем.
Вот код регистрации на его сайте.
Кликните здесь для просмотра всего текста
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
<?php
    if (isset($_POST['login'])) { $login = $_POST['login']; if ($login == '') { unset($login);} } //заносим введенный пользователем логин в переменную $login, если он пустой, то уничтожаем переменную
    if (isset($_POST['password'])) { $password=$_POST['password']; if ($password =='') { unset($password);} }
    //заносим введенный пользователем пароль в переменную $password, если он пустой, то уничтожаем переменную
 if (empty($login) or empty($password)) //если пользователь не ввел логин или пароль, то выдаем ошибку и останавливаем скрипт
    {
    exit ("Вы ввели не всю информацию, вернитесь назад и заполните все поля!");
    }
    //если логин и пароль введены,то обрабатываем их, чтобы теги и скрипты не работали, мало ли что люди могут ввести
    $login = stripslashes($login);
    $login = htmlspecialchars($login);
 $password = stripslashes($password);
    $password = htmlspecialchars($password);
 //удаляем лишние пробелы
    $login = trim($login);
    $password = trim($password);
 // подключаемся к базе
    include ("bd.php");// файл bd.php должен быть в той же папке, что и все остальные, если это не так, то просто измените путь 
 // проверка на существование пользователя с таким же логином
    $result = mysql_query("SELECT id FROM users WHERE login='$login'",$db);
    $myrow = mysql_fetch_array($result);
    if (!empty($myrow['id'])) {
    exit ("Извините, введённый вами логин уже зарегистрирован. Введите другой логин.");
    }
 // если такого нет, то сохраняем данные
    $result2 = mysql_query ("INSERT INTO users (login,password) VALUES('$login','$password')");
    // Проверяем, есть ли ошибки
    if ($result2=='TRUE')
    {
    echo "Вы успешно зарегистрированы! Теперь вы можете зайти на сайт. <a href='index.php'>Главная страница</a>";
    }
 else {
    echo "Ошибка! Вы не зарегистрированы.";
    }
    ?>

Пойдем по порядку.
PHP
1
2
if (isset($_POST['login'])) { $login = $_POST['login']; if ($login == '') { unset($login);} } //заносим введенный пользователем логин в переменную $login, если он пустой, то уничтожаем переменную
    if (isset($_POST['password'])) { $password=$_POST['password']; if ($password =='') { unset($password);} }
Что здесь неправильно. Во-первых, сама форма записи. isset() поддерживает передачу нескольких переменных на проверку, так почему бы не сделать так? И вообще, весь код необходимо заключать в проверку нажатия клавиши формы (или проверять метод отправки формы)
т.е. вот так
PHP
1
2
3
if(isset($_POST['кнопка_формы'])) {
#здесь код
}
либо
PHP
1
2
3
if($_SERVER['REQUEST_METHOD'] == 'POST') {
#здесь код
}
Вообще, если не использовали никакие подмены или что еще - то этого вполне хватает.
При необходимости, можно проверять существование нужных данных, но не таким способом. Как я уже говорил, в isset можно передавать несколько аргументов. Давайте посмотрим, как это можно делать.
PHP
1
2
3
4
5
6
7
if(isset($_POST['кнопка_формы'])) {
if(isset($_POST['login'],$_POST['password'])) {
#все данные существуют, можно работать
}
else 
   echo 'Вы заполнили не все данные';
}
Идем далее.
присваиваем переменные, попутно сразу очищая их от пробелов (можно и другие очистки сразу добавить - нечего расписывать код на десять строк вместо одной)
PHP
1
2
$login = trim($_POST['login']);
$password = trim($_POST['password']);
И уже только после того, как мы очистили от пробелов переменные, можно проверять на пустоту! Так как если не очистить, то обычный пробел в поле ввода спокойно пройдет эту проверку Попова. Теперь же проверим, пустая она или нет.
PHP
1
2
if(empty($login) || empty($password))
    echo 'Вы заполнили не все поля!';
Немного не в тему. Если у вас в теле цикла только одно действие - то не нужно заключать его в фигурные скобки. Тем более не нужно это делать в одну строку, это просто-напросто нечитабельно. Подумайте о себе и других в дальнейшем, форматируйте код так, чтобы было легко его читать.
Итак, совместив все это у нас получается такая запись:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(isset($_POST['кнопка_формы'])) {
 
    if(isset($_POST['login'],$_POST['password'])) {
 
        #все данные существуют, можно работать
        $login = trim($_POST['login']);
        $password = trim($_POST['password']);
 
        #проверяем на пустоту
        if(empty($login) || empty($password))
            echo 'Вы заполнили не все поля!';
        else { #поля не пустые, идем дальше
            #здесь еще что то делаем
        }
 
    }
    else 
       echo 'Вы заполнили не все данные';
 
}
уже получше, проверяем дальше.
В php есть такая вещь как так называемые "магические (волшебные) кавычки". Они добавляют экранирование к ряду символов в отправляемые данные. Но, т.к. мы будем использовать mysql_real_escape_string() перед запросом, то нам нужно очистить от этих слэшей. В принципе, при авторизации можно убирать слэши по любому, если они не должны быть в логине или пароли (а обычно это так).
Проверить, включены кавычки или нет можно с помощью функции get_magic_quotes_gpc(). Я проверять не буду, а просто сразу очищу
PHP
1
2
$login = stripslashes($login);
$password = stripslashes($password);
Далее, необходимо подключиться к БД - т.е. подключить файл с подключением к БД
PHP
1
require_once './db.php'; #используйте путь от корневой директории, а не просто так пишите
Проверка наличия пользователя:

Код Попова.
PHP
1
2
$result = mysql_query("SELECT id FROM users WHERE login='$login'",$db);
    $myrow = mysql_fetch_array($result);
Неверно. По двум причинам. Во-первых, зачем что то извлекать, если можно просто подсчитать число таких пользователей. Во-вторых, данные не проэкранированы и подвержены к SQL-инъекциям. Исправим это.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
#экранирование
$login = mysql_real_escape_string($login);
$password = mysql_real_escape_string($password);
#выполняем сам запрос
$result = mysql_query('SELECT COUNT(1) FROM `users` WHERE `login`="'.$login.'"');
if($result)
    $data = mysql_fetch_array($result,MYSQL_NUM);
if(!empty($data[0]))
    echo 'Пользователь с таким логином уже существует!';
else {
#пользователь не найден, регистрируем
}
Далее
PHP
1
2
3
$result2 = mysql_query ("INSERT INTO users (login,password) VALUES('$login','$password')");
    // Проверяем, есть ли ошибки
    if ($result2=='TRUE')
С запросом вроде все нормально.. но вот с проверкой. Запомните, функции возвращают логический (булев) тип, а не строку! Так работает только по причине того, что php не жестко типизированный язык, в отличии от большинства, но это плохой код.
Правильно делать так:
PHP
1
2
3
4
5
6
7
if(TRUE === $result2) //только для запросов, которые НЕ возвращают ресурс, а только FALSE/TRUE
# или так
if(TRUE == $result)
#ну или и так можно
if($result)
#но никак не вот так
if($result == 'TRUE')
Ну и далее, опять ошибка читабельности - заключение одного условия в фигурные скобки
PHP
1
2
3
4
5
6
7
if ($result2=='TRUE')
    {
    echo "Вы успешно зарегистрированы! Теперь вы можете зайти на сайт. <a href='index.php'>Главная страница</a>";
    }
 else {
    echo "Ошибка! Вы не зарегистрированы.";
    }
Итак, перепишем код и посмотрим на то, что же у нас получилось.
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
<?php
if(isset($_POST['кнопка_формы'])) {
 
    if(isset($_POST['login'],$_POST['password'])) {
 
        #все данные существуют, можно работать
        $login = stripslashes(trim($_POST['login']));
        $password = stripslashes(trim($_POST['password']));
 
        #проверяем на пустоту
        if(empty($login) || empty($password))
            echo 'Вы заполнили не все поля!';
        else { #поля не пустые, идем дальше
 
            #экранируем переменные для запроса
            $login = mysql_real_escape_string($login);
            $password = mysql_real_escape_string($password);
            
            #выполняем сам запрос
            $result = mysql_query('SELECT COUNT(1) FROM `users` WHERE `login`="'.$login.'"');
            
            if(TRUE == $result)
                $data = mysql_fetch_array($result,MYSQL_NUM);
 
            if(!empty($data[0]))
                echo 'Пользователь с таким логином уже существует!';
            else {
                #пользователь не найден, регистрируем
                $result2 = mysql_query ('INSERT INTO `users` (`login`,`password`) VALUES("'.$login.'","'.$password.'")');
                
            // Проверяем, есть ли ошибки
                if (-1 != mysql_affected_rows())
                    echo 'Вы успешно зарегистрированы! Теперь вы можете зайти на сайт.<br />
                    <a href="./">Главная страница</a>';
                else 
                    echo 'Произошла ошибка при регистрации. Пожалуйста, попробуйте позднее.';
            }
 
        }
 
    }
    else 
       echo 'Вы заполнили не все данные';
 
}
Ну и, конечно, можно его немного сократить еще:
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
<?php
if(isset($_POST['кнопка_формы'])) {
 
    if( isset($_POST['login'], $_POST['password']) ) {
 
        #все данные существуют, можно работать
        $login = mysql_real_escape_string(stripslashes(trim($_POST['login'])));
        $password = mysql_real_escape_string(stripslashes(trim($_POST['password'])));
 
        #проверяем на пустоту
        if(empty($login) || empty($password))
            echo 'Вы заполнили не все поля!';
        else { #поля не пустые, идем дальше
            
            #выполняем сам запрос
            $result = mysql_query('SELECT COUNT(1) FROM `users` WHERE `login`="'.$login.'"');
            
            if($result)
                $data = mysql_fetch_array($result,MYSQL_NUM);
 
            if(!empty($data[0]))
                echo 'Пользователь с таким логином уже существует!';
            else {
                #пользователь не найден, регистрируем
                $result2 = mysql_query ('INSERT INTO `users` (`login`,`password`) VALUES("'.$login.'","'.$password.'")');
                
            // Проверяем, есть ли ошибки
                echo -1 !== mysql_affected_rows()
                    ? 'Вы успешно зарегистрированы! Теперь вы можете зайти на сайт.<br />
                    <a href="./">Главная страница</a>'
                    : 'Произошла ошибка при регистрации. Пожалуйста, попробуйте позднее.';
            }
        }
    }
    else 
       echo 'Вы заполнили не все данные';
}
А если убрать все комментарии, которые, в принципе, здесь и не нужны, оставив лишь пару пустых строк для лучшей читабельности то получится нечто наподобие такого:
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
<?php
if(isset($_POST['кнопка_формы']))
{
    if( isset($_POST['login'], $_POST['password']) )
    {
        $login = mysql_real_escape_string(stripslashes(trim($_POST['login'])));
        $password = mysql_real_escape_string(stripslashes(trim($_POST['password'])));
 
        if(empty($login) || empty($password))
            echo 'Вы заполнили не все поля!';
        else
        {
            if( ($result = mysql_query('SELECT COUNT(1) FROM `users` WHERE `login`="'.$login.'"')) )
                $data = mysql_fetch_array($result,MYSQL_NUM);
 
            if(!empty($data[0]))
                echo 'Пользователь с таким логином уже существует!';
            else
            {
                mysql_query ('INSERT INTO `users` (`login`,`password`) VALUES("'.$login.'","'.$password.'")');
                echo -1 !== mysql_affected_rows()
                    ? 'Вы успешно зарегистрированы! Теперь вы можете зайти на сайт.<br />
                        <a href="./">Главная страница</a>'
                    : 'Произошла ошибка при регистрации. Пожалуйста, попробуйте позднее.';
            }
        }
    }
    else 
       echo 'Вы заполнили не все данные';
}
ну и можно избавиться от первого if-a, он, в принципе, не так уж и важен.
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
<?php
if( isset($_POST['login'], $_POST['password']) )
{
    $login = mysql_real_escape_string(stripslashes(trim($_POST['login'])));
    $password = mysql_real_escape_string(stripslashes(trim($_POST['password'])));
 
    if(empty($login) || empty($password))
        echo 'Вы заполнили не все поля!';
    else
    {
        if( ($result = mysql_query('SELECT COUNT(1) FROM `users` WHERE `login`="'.$login.'"')) )
            $data = mysql_fetch_array($result,MYSQL_NUM);
 
        if(!empty($data[0]))
            echo 'Пользователь с таким логином уже существует!';
        else
        {
            mysql_query ('INSERT INTO `users` (`login`,`password`) VALUES("'.$login.'","'.$password.'")');
            echo -1 !== mysql_affected_rows()
                ? 'Вы успешно зарегистрированы! Теперь вы можете зайти на сайт.<br />
                    <a href="./">Главная страница</a>'
                : 'Произошла ошибка при регистрации. Пожалуйста, попробуйте позднее.';
        }
    }
}
else 
    echo 'Вы заполнили не все данные';


Вернуться к обсуждению:
FAQ по распространенным ошибкам
22
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.09.2012, 13:08

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

PHPStorm - навигация по ошибкам анализатора
Добрый день! В правом верхнем углу есть значок анализатора (см. вложение). В окне просто...

Сма Bauknecht WA 7540, Поделитесь информацией по ошибкам
Должен буду идти на вызов. Клиент говорит, что сма выдаёт ошибку. Но дисплея на ней нет. Поделитесь...

Сма Blomberg WNF 8447 нужна инфа по ошибкам
Сма Blomberg WNF 8447 нужна инфа по ошибкам ,заранее спасибо. ...

сма Whirlpool AWE 6514 859365110040, нужны данные по ошибкам
Приветствую всех! Машинка не переходит на полоскание. Нужна расшифровка по ошибкам. Модуль на...

0
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.