Написать пост

20 вещей, которые отличают PHP-программиста от обезьянки

Аватар Лапа

Обложка поста 20 вещей, которые отличают PHP-программиста от обезьянки

PHP — самый популярный язык для написания кода серверной части. Одной и той же цели на нем можно достичь несколькими путями: можно спроектировать красивую и легко поддерживаемую систему, а можно быстро слепить вместе куски кода со Stack Overflow, не забивая себе чересчур голову такими вещами, как правила проектирования и читаемость кода.

Конечно, даже если вы пока еще не гуру разработки, вы все равно захотите писать код, из-за которого окружающим не захочется плакать. Tproger вас выручит — в этой статье собрано 20 советов, каждый из которых поможет вам улучшить читаемость кода и за следование которым вам потом скажут спасибо. А в перспективе прилежное следование этим советам поможет вам стать ближе к статусу опытного и внимательно относящегося к деталям разработчика.

Используйте <?php

Не используйте <? ?> и прочие способы размещения в файле php-скриптов. Да, может быть, у вас все работает, а вот на другом сервере — не факт. На некоторых серверах короткие тэги вообще отключены. Не рискуйте, используйте только <?php. И кстати, не ставьте закрывающий php-тег — это признак дурного тона. А еще закрывающий тэг в конце может привести к неожиданным проблемам, связанным со случайно поставленным пробелом или переводом строки в конце вывода.

			<? ... ?> 	// Неправильно
<?php ... 	// Правильно
<?=$Var?> 	// Неправильно
<?php echo $Var // Правильно
		

Отделяйте файлы с параметрами

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

include("config.php");

Комментарии — ваши друзья

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

			// Однострочный комментарий
/** Многострочный
комментарий **/
		

Правда, просто? Еще стоит обратить внимание на PHPDoc.

Грамотно форматируйте код

Нет ничего хуже огромной стены кода, автор которого явно не знал о существовании кнопки Tab. Не спасут даже комментарии — отступы придумали для того, чтобы логически отделять друг от друга фрагменты кода. А использование или неиспользование отступов много говорит о вас как о программисте. Вот этот код отформатирован неправильно:

			function  dothisformula($a,$b) { $c = $b+$a;
    $e=3;
while ($c < 20) {
$e = $e - 1; $c = $c + 1; }
return $e; }
		

А вот это — тот же самый код, но с правильным форматированием:

			function dothisformula($a, $b) 
{
    $c = $b + $a;
    $e = 3;
    while ($c < 20) {
        $e = $e - 1;
        $c = $c + 1;
    }
    return $e;
}
		

Если вы хотите точно знать, какой способ форматирования кода правильный — почитайте PSR-ы.

Давайте переменным понятные имена

Конечно, к единому мнению по этому вопросу прийти нельзя. camelCase или under_score? Нужна ли Венгерская нотация? Важно здесь одно: раз и навсегда определитесь, что вам ближе. А даже если вам и захочется изменить стиль, то пожалуйста, не делайте это посреди проекта! Разные варианты именования переменных в одном проекте или, что еще хуже, в одном файле — это ужасно. И никаких магических чисел! Не поленитесь использовать константы.

Инициализируйте переменные

Конечно, PHP автоматически создает переменные при попытке к ним обратиться. Но вам не кажется, что пользоваться этой особенностью довольно рискованно? Хорошей практикой считается всегда инициализировать переменные еще перед первым использованием. Это сделает код понятнее и поможет убедиться, что вы не обращаетесь случайно к неинициализированной переменной.

			$foo = array();
$bar = 0;
$baz = false;
		

Булева переменная ложна, иначе — истинна

Если вы проверяете какое-то условие и потом результат сравнения сохраняете в булевом значении, при инициализации переменной для результата (мы ведь всегда заранее инициализируем переменную, помните?) сначала присваивайте ей false. То есть вот так делать не надо:

			function getStatus() 
{
    $result = true;

    if ($i != 2) 
    	$result = false;

    return $result;
}
		

Лучше вот так:

			function getStatus() 
{
    $result = false;

    if ($i == 2) 
    	$result = true;

    return $result;
}
		

Зачем это? Представьте, что вы проверяете данные перед запросом к базе. Если по какой-то причине блок if вдруг не выполнится, то значение переменной останется false — так вы подстрахуете себя от попадания в базу ошибочных данных. В коде порой приходится иметь дело с конфиденциальными данными, так что лучше сначала исходить из того, что все данные ошибочны, пока не доказано обратное. Это правило практически написано кровью.

Кстати, лучше проверять, являются ли данные такими, как надо нам, чем являются ли они такими, как нам не надо.

Используйте кавычки, когда обращаетесь к элементам массива

В коде разных разработчиков можно увидеть два варианта доступа к элементам ассоциативного массива:

			$name = $names['marc'];
$name = $names[marc];
		

Во время выполнения второго варианта PHP сначала попытается найти константу с именем marc. И только если такой не найдется, marc будет сконвертировано в строку и передано в таком виде. Лучше не думать о том, что может случиться, если вдруг такая константа будет существовать… Всегда ставьте кавычки, чтобы такого не происходило.

Используйте запятые, чтобы обратиться к нескольким строкам в одном вызове

Если вам надо, например, в одном вызове функции обратиться к значению переменной и к строке, лучше используйте запятые, а не точки. Почему? Точка — оператор конкатенации строк, эта операция будет выполняться медленнее. Доказательство.

Еще раз. Так надо:

echo "Hello, my name is ", $name;

А вот так — не надо:

echo "Hello, my name is " . $name;

Пользуйтесь тернарными операторами

Если у вас в коде какое-то очень простое сравнение, желательно использовать тернарный оператор, чтобы не растягивать простой код на несколько строк. Вот так может выглядеть ваш простой if:

			if ($a == 1) 
    $b = 2;
else 
    $b = 3;
		

Но можно записать его и так:

			$b = ($a == 1) ? 2 : 3;
		

Обобщенно тернарный оператор работает следующим образом:

			$variable = ($condition) ? true : false;
		

Используйте для сравнения с булевыми значениями строгое сравнение

Если вы проверяете переменную на true или false, используйте ===, а не ==, которое задействуется в остальных сравнениях. Строгое сравнение из трех знаков равенства сравнит еще и типы переменных.

			if ($isMember == true) { ... } // Неправильно
if ($isMember === true) { ... } // Правильно
		

Используйте инкремент и декремент

Если вам нужно просто увеличить или уменьшить на 1 значение переменной, ни к чему писать эту громоздкую конструкцию:

			$number = $number + 1;
$number2 = $number2 - 1;
		

Куда лаконичнее такой вариант:

			$number++; // Инкремент
$number2--; // Декремент
		

А главная прелесть этих операций — в том, что одновременно с ними можно выполнять еще какое-нибудь действие (например, if или while). В зависимости от того, написано ли -- или ++ до или после самого названия переменной, очередность операций изменяется.

			// Инкремент произойдет после сравнения:
$number = 10;
while ($number++ == 10) { ... }

// А здесь декремент произойдет перед сравнением:
$number = 10;
if (--$number == 10) { ... }

$number = 10;
$total = $number++;
// $total будет равен 10.

$number = 10;
$total = --$number;
// $total будет равен 9.
		

Используйте сокращенные операторы присваивания

Если переменную надо увеличить или уменьшить на число, не равное 1, то и в этом случае код можно сократить. Например, у вас в коде может быть такое:

			$a = $a + $b;
$a = $a * 5;
$a = $a - $d;
$a = $a / 3;
		

А используя сокращенные операторы, этот же код можно будет записать так:

			$a += $b;
$a *= 5;
$a -= $d;
$a /= 3;
		

Со строками, кстати, это тоже работает. Если понадобится присоединить к существующей строке какую-то часть, сделайте это так:

			$string = $string . "hello";
$string .= "hello";
		

Создайте отдельную функцию для var_dump

Иногда бывает нужно во время активной отладки часто выводить прямо на страницу значение какой-то переменной. Конечно, лучше лишний раз так не делать, но если все-таки нужно, то имеет смысл себе помочь. Функция может выглядеть так:

			function d($var) 
{
    echo "<pre>";
    var_dump($var);
    echo "</pre>";
}
		

Тэг pre используется, чтобы сделать значение более читаемым. Кстати, такое странное имя функции дано неслучайно — оно короткое, хоть и неочевидное. Набрать ее название будет быстро. Только потом не забудьте убрать эту функцию, когда будете подчищать код в конце разработки.

Но лучше всего забыть этот совет и научиться пользоваться XDebug.

Пользуйтесь константами

Если у вас есть переменная, значение которой изменять не стоит, имеет смысл использовать вместо нее константу. Константы можно использовать, чтобы хранить в них пути, сообщения об ошибках и так далее. Имя константам стоит давать капсом — так их будет просто отличить, и вы будете уверены, что вызываете то, что нужно.

			define ("DIRECTORY", "/path/to/site/");
echo DIRECTORY;
		

Пользуйтесь $_GET и $_POST

$_REQUEST лучше не использовать. Четко разделяйте данные: $_GET — это параметры, переданные из адресной строки, $_POST — это, например, полученные из формы данные. И не вздумайте передавать в скрипт пароли, особенно незашифрованные, GET-запросом!

			$action = $_GET['actions'];
$name = $_POST['name'];
		

Пользователи могут руками заменить значения в адресной строке на любые произвольные и доставить вам немало хлопот.

Используйте объекты, а не функции

PHP — все-таки в том числе и объектно-ориентированный язык. Если вы работаете над большим проектом, сотни строк функционального кода вам точно быстро надоедят. А если вам нужно хранить множество однотипных параметров, то тем более задумайтесь об использовании соответствующего класса.

Вызывайте методы цепочками

Если вы подряд вызываете несколько методов одного объекта, имеет смысл сократить код, не выписывая каждый раз название этого объекта. Если есть вот такой класс:

			class User 
{
    function setThis($var) 
    {
        ....
        return $this;
    }

    function setThis2($var2) 
    {
        ....
        return $this;
    }
}
		

… то обращаться к его методам можно так:

			$user = new User();
$user->setThis(...)
      ->setThis2(...);
		

Чтобы лучше понять, как это работает и при каких обстоятельствах можно это пользоваться, почитайте статью.

Не повторяйте себя

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

Почитайте о методах DRY и WET.

Стремитесь к слабой связанности и сильной сцепленности

Связанность — это способ проектирования проекта, когда изменение одного компонента требует изменения другого. Другими словами, если вы измените одну функцию, придется ли менять другую? Чем свободнее связь, тем проще будет менять компоненты, не перелопачивая половину кода.

Сцепленность же — это когда вместе отдельные части образуют значимую единицу. У вас есть одна функция или метод на весь проект, которая делает вообще все возможное и невозможное, или есть много функций или методов, каждый из которых выполняет свой участок работы? Особенно это касается ООП. Дробите методы, магические методы на десятки и сотни строк недопустимы.

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

Проиллюстрировать этот совет можно так. Возьмем этот код:

			/* Мы хотим сложить два числа,
только если первое число меньше 5 */

function add($var, $var2) 
{
    if ($var < 5) 
        return false;
    else 
        $result = $var + $var2;

    echo "The Result is ", $result;
}
$var = 3;
$var2 = 2;
add($var, $var2);
		

Главный минус этой функции в том, что она сама осуществляет проверку данных, а потом выводит на экран значение. Да и такое поведение не совсем очевидно — согласитесь, столь избирательно работающее сложение вам вряд ли еще где-то повторно понадобится. А если вам еще и захочется поменять сообщение для вывода? Этот код лучше переписать так:

			function add($var, $var2) 
{
    return $var + $var2;
}

function result($message) 
{
    return "The Result is " . $message;
}

$var = 3;
$var2 = 2;

if ($var < 5) {
    echo result(add($var, $var2));
}
		

Теперь каждая функция выполняет только свою работу: add складывает числа, result выводит результат.

Следите за новыми постами
Следите за новыми постами по любимым темам
36К открытий36К показов