Пять моих «граблей» в разработке на PHP

Здравствуйте, уважаемые читатели моего блога! Недавно на Хабре я публиковал один пост, который как-то неочень понравился его контингенту (видать для таких «гуру» пост оказался слишком простым). Сейчас пост находится в черновиках, а здесь я публикую его, т. к. все же считаю, что пост может быть достаточно интересным.

В этом посте хотел бы поделиться своим личным опытом «наступания на грабли» во время разработки веб-приложений на языке программирования PHP. Текст будет интересен тем, кто хочет посмотреть на то, каким был код у «зеленого самоучки» и каким он стал у более-мение опытного девелопера, а также начинающим программистам, которые не против узнать о том, «как не нужно делать» и почему. Возможно даже кто-то вспомнит себя и улыбнётся. Возможно, кто-то просто улыбнётся с моего старого кода.

Пять моих «граблей» в разработке на PHP

Пять моих «граблей» в разработке на PHP

Все мое ознакомление с веб-разработкой начиналось в далеком 2009-м году с распечатанных непонятных и сложных справочников и руководств, а также ковыряния кода (очень плохого, кстати) open source CMS. Позже я начал использовать ООП и заботиться о «правильности», а ещё позже — замечательный фреймворк Yii, поэтому весь «хороший» код в посте будет демонстрироваться именно с использованием этого фреймворка.

1. Дублирование кода. Сейчас, смотря на свой код минувшых лет, я понимаю, что это были действительно ужасные времена. У меня дублировалось практически всё. Функции писались редко, а один и тот же код можно было увидеть в трех-четырех (ато и больше) местах. Почему я так делал? Ну естественно потому что я был неопытным. Это раз. И потому что считал (глупо считал), что написание функции — это трата времени и что гораздо проще просто покопировать одно и тоже несколько раз.

Что было раньше:

$sql = 'SELECT `id` FROM `days` WHERE `sta`=1';
$r=mysql_query($sql,$conn);
$row=mysql_fetch_row($r);

$curday=$row[0];

if (($curday>=3 && $curday<=15) || ($curday>=45 && $curday<=55) || ($curday>=90 && $curday<=105))
    {
           $on_off=1;
    }else{
           $on_off=0;
    }

Что есть сейчас:

// Get current day and transfer status
$curDay = BasicFunctions::getCurrentDay();
$transferStatus = BasicFunctions::getTransferStatusByCurDay($curDay);

// statuses: 1 - opened, 0 - closed
if ($transferStatus === 1) {
   ...
}

Позже я понял, зачем делать «хорошо»:

Самая важная причина создания метода — снижение сложности программы. Методы создаются для того, чтобы можно было скрыть информацию и не думать о ней. Другие причины создания методов — минимизация объема кода, облегчение сопровождения программы и снижение числа ошибок.

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

2. Пересекание PHP и HTML. Да, я не использовал патернов проектирования. Да, я не использовал популярного MVC. И это было второй моей фатальной ошибкой. Почему я так делал? Я почему-то не думал о том, что код когда-то может быть переписан/дописан/изменен. Всё «хардкорилось» чисто с расчетом на сиюминутную выгоду.

Что было раньше:

echo 'HTML ... HTML ... HTML';

              $sql = 'SELECT * FROM `capitans` WHERE `club`='.$_SESSION['my_club'];
               $r=mysql_query($sql,$conn);
               $row=mysql_fetch_row($r);    $idp=$row[2];

if (!isset($row[2]) || $row[2]=="")
   {
   echo 'HTML ... HTML ... HTML';
   }else{

              $sql = 'SELECT * FROM `players` WHERE `id`='.$idp;
               $r=mysql_query($sql,$conn);
           $row=mysql_fetch_row($r);

     ....

}

Что есть сейчас:

// Get current capitan
$capitan = Capitans::model()->findByAttributes(array('club' => $user->club));

            $this->render('team', array(
                ...
                'capitan' => $capitan,
                ...
            ));

----------------------------------------

pl_id) {  ?>
   HTML ... HTML ... HTML

Позже я понял, зачем делать «хорошо»:

Использования паттерна проектирования (при веб-разработке чаще всего это MVC) снижает сложность разработки за счёт готовых абстракций для решения целого ряда проблем. Например, логические части приложения разделяются на автономные области. Например, в том же MVC модель данных, пользовательский интерфейс и взаимодействие с пользователем разделены на три отдельных компонента. Зачем? Затем, чтобы модификация одного из компонентов оказывала минимальное воздействие на остальные.

Пять моих «граблей» в разработке на PHP

Пять моих «граблей» в разработке на PHP

3. Не использование фреймворка. Я года два писал всё сам и не использовал фреймворков. Я считал, что это что-то очень сложное и на изучение «этого» у меня нет времени. Есть люди, которые принципиально не используют фреймворки, например, потому что они считают, что фреймворк — это open source, который доступен каждому (т. е. каждый может просмотреть его код и найти узкие места). Эти люди, которые так считают, пишут свои фреймворки, которые используют в подальших проектах. Лично я считаю, что сейчас есть TOP-3 (или TOP-5) тех фреймворков, которые проверены на популярных проектах и отточены до максимума, поэтому резон писать что-то свое стремится к нулю. Если вы так не считаете, проголосуйте в конце поста.

Что было раньше (авторизация):

if (!isset($_POST['login']) || strlen($_POST['login'])<3)
{
    $errorsArray[] = 'Не введён логин или он слишком короткий';
    $sum=$sum+1;
}
if (!isset($_POST['pass']) || strlen($_POST['pass'])<3)
{
    $errorsArray[] = 'Не введён пароль или он слишком короткий';
    $sum=$sum+1;
}
if (!preg_match("/^([a-zA-Z0-9]+)$/", $_POST['login']))
{
    $errorsArray[] = 'В поле "логин" присутствуют недопустимые символы';
    $sum=$sum+1;
}
if (!preg_match("/^([a-zA-Z0-9]+)$/", $_POST['pass']))
{
    $errorsArray[] = 'В поле "пароль" присутствуют недопустимые символы';
    $sum=$sum+1;
}

$sql = 'SELECT * FROM `users` WHERE `login`="'.$_POST['login'].'"';
$r=mysql_query($sql,$conn);
$row=mysql_fetch_row($r);

if ($row[1]!==$_POST['login'] || $row[2]!==md5($_POST['pass']))
{
    $errorsArray[] = 'Неверный логин или пароль';
    $sum=$sum+1;
}

Что есть сейчас (авторизация):

    public function actionLogin()
    {
        $model=new LoginForm;

        if(isset($_POST['LoginForm']))
        {
            $model->attributes=$_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if($model->validate() && $model->login())
                $this->redirect(Yii::app()->user->returnUrl);
        }
        // render form
        $this->render('login',array('model'=>$model));
    }

Позже я понял, зачем нужно использовать фреймворк:

Любой фреймворк — это, в первую очередь, набор уже готовых к использованию стандартов, которые используют, тратя намного меньше времени, разработчики. Кроме этого, вокруг популярных open source фреймворков собирается серьезное сообщество разработчиков. Что это значит? А это значит то, что будет легко подключить или заменить человека в команде работающей над проектом. Плюс, комьюнити создает массу готовых сторонних решений.

4. Классы? Не, не слышал. Классы не использовались вообще. Хотя, при описанных выше «ляпах», о каких классах может идти речь :)

Что было раньше:

include_once("inc.php");
include_once("head.php");
include_once("system.php");

if (isset($_SESSION['login']) && isset($_SESSION['password']))
   {

  if (!isset($_GET['id']) || $_GET['id']=="")
     {

       ...

     }
   }

Что есть сейчас:

class UsersInfo {
   ...

    /**
     * Get info about last registered users
     * @ param type $limit - limit
     * @ return array - users
     */
    public function getLastRegUsers ($limit) {
           $criteria=new CDbCriteria;
           $criteria->limit = $limit;
           $criteria->order = 'user_id DESC';
           $users = Users::model()->findAll($criteria);

           return $users;        
    }

   ...

}

Позже я понял, зачем делать «хорошо»:

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

Пять моих «граблей» в разработке на PHP

Пять моих «граблей» в разработке на PHP

5. Не использование LIMIT’ов, JOIN’ов, запросы в циклах. Если бы сейчас существавала инквизиция, то на огонь попадали бы все начинающие программисты, которые занимаются такой ересью :) Это, наверное, самый смертный грех программиста. Такими действиями я просто убивал быстродействие своих приложений. А, как вы знаете, быстродействие — это один из основных факторов, которые влияют на то, вернется ли второй раз к вам пользователь или нет.

Что было раньше (случайный код):

             $sqlo = 'SELECT `id`, `pos` FROM `players`';
               $ro=mysql_query($sqlo);
           while($rowo=mysql_fetch_row($ro))
        {
if ((int)$rowo[0]==(int)$ex2[0]){

$r_tmp_2 = mysql_query("SELECT `pos` FROM `pos` WHERE `id`=".$rowo[1]."");
$row_tmp_2=mysql_fetch_row($r_tmp_2);

            ...

                }
        }

Что есть сейчас (случайный код):

if ($addNewBuild = Yii::app()->request->getQuery('addNewBuild')) {
                $building = Buildings::model()->findByPk($addNewBuild); // Ищем первую запись по Primary Key и возвращаем её, если она найдена
                if ($building) {
                   ...
                }else{
                  ...
                }
}

Позже я понял, зачем делать «хорошо»:

Вы должны заботиться о быстродействии своих приложений. Вы должны заботиться о правильности написания SQL-запросов. Именно SQL-запросы составляют большую часть приложения и именно они в основном влияют на быстродействие. Использование LIMIT‘ов помогает избежать проходов по всем записям таблицы, а использование JOIN‘ов помогает избежать циклических запросов.

Вот такая вот история. Всем спасибо за интерес, внимание, и улыбки (надеюсь, они у вас были).

P. S. Про именование переменных уже не стал писать (вы наверное заметили $rowo, $r_tmp_2, $sqlo), как нибудь в другой раз обязательно напишу.

Пять моих «граблей» в разработке на PHP
5 votes, 5.00 avg. rating (99% score)

20 thoughts on “Пять моих «граблей» в разработке на PHP

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

  2. Обстановка в всяком помешении считается главным составляющим стилистики и отличием вкуса хозяев, от этого пользователь стремится настроить что-набудь неповторимое у любой помещении, оформление комнаты, ванной, терассы к тому же иных склада социального оборота часто воздействуется мозаика, с удобный и живописный сырье декорация работает в всяческой подборе цветов также мгновенном снабжении, то что дозволяет материал эксплуатировать при все тип ремонтных и промышленных деятельности. Выбрать мозаику от качественного поставщика, осмотреть необходимые трансформации убранства из применением камушков, избрать окраску, параметры плюс установление потребитель получает возможность непосредственно на источнике данного интернет магазина Мир мозаики Мозаика K05.55 C. , который показывает совершенный гарнитуру изделия, какой выполнимо подбирать в параметрам плюс стоимости. У нас любой получает возможность назначить собственно для предпочтение угодный тип керамики на низкими оплату и хорошим обслуживанием.

  3. Поехали в отпуск, и захворал ребенок, а денег капля. Легко получили займ онлайн, на карту пришли наличные моментально. Отдали через неделю уже дома. Никаких справок или поручителей. Нужен только телефон и кредитка с которой можно снять всю ссуду буквально через несколько минут после одобрения заявки.
    Выручали такие живые деньги и соседей, когда сыну нужно было немедленно оплатить экзамен. Никому не надо объяснять, унижаться и выпрашивать. Сам выбираешь необходимую сумму и время возврата. Советую абсолютно всем, кто оказался в непростой ситуации.

  4. Easy way to lose weight fast for a week:
    https://sites.google.com/site/weightlossluxury/the-20-most-weight-loss-friendly-foods-on-the-planet—healthline

    Food for Google:
    can you lose weight drumming
    dramitic weight loss
    rapid weight loss springfield mo
    transitions weight loss supplements
    best exercise to lose upper body weight
    hypothalmus weight loss
    is the best weight loss supplement
    the biggest weight loss in history
    medical weight loss kingwood tx

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *