Блог


Стиль кодирования PHP

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

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

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

Первый, самый распространенный, основан на так называемом стиле K&R (Кернигана и Ричи). На его основе сегодня принято соглашение PSR, которое подписали разработчики основных, самых популярных фреймворков.

Второй - стиль BSD или стиль Алемена.

Основное (если не единственное) различие между ними в расстановке фигурных скобок. Первый рекомендует открывающую скобку ставить на одной линии с выражением:

1
 2
 3
 4
 5

if($var == 1){
    echo 
$var;
}

Второй рекомендует открывающую скобку ставить под ним. Закрывающую строго под ней. Отступы так же на 4 пробела.

1
 2
 3
 4
 5

if($var == 1)
{
    echo 
$var;
}

 

Важно! Именно 4 пробела, а не знак табуляции. Дело в том, что табуляция хоть и удобнее, но по разному отображается в разных редакторах. И код может расползтись так, что лучше бы вообще без стиля. Можно настроить редактор так, что бы он сам заменял таб четырьмя пробелами. Наш редактор делает это автоматически.

 

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

Экономия пространства была продиктована малой величиной мониторов на заре всеобщей компьютеризации. Сейчас этой проблемы нет. Однако искать начало и конец кода по разным границам для подсознания несколько сложнее. Мы открыли скобку и ищем закрытую. Все логично. В рациональном стиле (еще и так называют «K&R») начало блока нужно определять по началу оператора, а не по скобке. А если по скобке, приходится мотать головой и искать её уже в горизонтальном направлении. Что не совсем удобно на мой взгляд.

 

Кроме того, в стиле Алемена можно вообще не ставить скобок, если в блоке одно выражение. Сразу видно, нет над ним открывающей скобки, значит оно одно. В «K&R» нужно обязательно посмотреть в конец оператора на предмет её наличия. Потому что закрывающая может оказаться намного ниже. Поэтому в последнем наличие скобок обязательно, даже если оператор один. Сравните:

 

Ну как бы то нибыло, наши листинги оформлены в стиле Алемена, а вам выбирать самим.

Второе немаловажное правило - названия классов, функций и переменных. Ну соответственно методов и констант. Тут полный разброд и шатания. Просто расскажу почему мы используем такой стиль:

1. Классы оформляются в верблюжьей нотации, с заглавной буквы, через подчеркивание. Первым словом принадлежность, вторым суть класса. Допустим

1
 2
 3
 4

class Blog_Model
{
  


2. Функции и методы в верблюжьей нотации с маленькой буквы без подчеркивания.

1
 2
 3
 4

    public function setParametr()
    {
  

 

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

1
 2
 3
 4
 5
 6


    $check 
array_key_exists($array); // Штатная функция, через подчеркивание
    
    
$array arrayFilterZero($array); // Наша пользовательская, "верблюжья"

А отличие от класса видно с первой буквы. Заглавная - класс. Прописная - функция.

И еще. Общие классы библиотеки должны начинаться с префикса. Допустим IRB_Paginator. Ибо пагинаторов в свободном доступе пруд пруди, велика вероятность найти класс с таким же названием. А префикс уберегает от неоднозначности. 

3. А вот переменные пишем в нижнем регистре, и если она составная, через подчеркивание. Их отличить от функций просто - знак доллара. Исключения составляют переменные, находящиеся в глобальной области видимости, они полностью заглавными буквами. Не нужно бояться global, это удел слабаков. Главное все правильно оформлять, и все будет чики-пики. Видим переменную в верхнем регистре, не трогать. Она только для чтения.

1
 2
 3
 4
 5
 6
 7
 8

// Хоть переменная и функция созвучны,
// знак доллара как бы намекает.
    
$array_keys array_keys($array); 

// Константа. Она по сути глобальна
// значит большими буквами. Слова делим подчеркиванием.
    
$num IRB_CONFIG_BLOG_NUM_WORDS;
    
    function 
href()   
    {
// Глобальная переменная. Тоже большая.  
        
global $GET;
    
// Не трогаем, если нужно, временно организуем другую    
        
$tmp $GET;  
                            

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

И еще один штрих. Если используете ООП, приватные методы нужно начинать с подчеркивания. Это тоже сильно облегчает чтение кода. Сразу видно кто есть кто:

1
 2
 3
 4
 5
 6


    
// Приватный метод. Сразу понятно, 
    // что вне класса работать не будет
    
$tags self::_htmlLinks($id);    

 

 4. Еще важный момент - отделение операторов пробелами. Очень противно, когда все валится в кучу. Ну совершенно не трудно нажать пробел до и после. Это входит со временем в привычку, трудно только на первых порах. Но вот сравните, есть же разница?

1
 2
 3
 4
 5
 6
 7
 8


    
// Каша. Не понятно где точка, где минус, где подчеркивание
    
$start.=$num_page*$num_rows*$num_columns-$num_rows*$num_columns;
    
    
// А  так все видно и понятно
    
$start .= $num_page $num_rows $num_columns $num_rows $num_columns;  

 

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

Николай aka twin

Продолжение здесь

Теги: PHP | ajax

Комментарии (11)

kdes70
18-03-2013
Спасибо!!!!
Savage
18-03-2013
А кстати вот такой ещё находил документ - Стандарты оформления кода PHP
http://yadi.sk/d/un8ExNsx3MPDE

там есть рекомендация отделять пробелом перед открывающей скобкой условные операторы и операторы цикла, в отличии от функций, так как нагляднее смотрится. Как вы считаете, имеет смысл придерживаться такой рекомендации? И если у вас найдётся время на знакомство с тем документом, то как вы думаете, там в целом тоже актуальные рекомендации?
twin
18-03-2013
Ну любой документ по стилю кодирования может носить только рекомендательный характер. Так и этот, я с ним ознакомился. Многое нами используется, кое с чем я категорически не согласен. Вот с теми же пробелами перед скобками. В следующей публикации подробно расскажу почему.
Savage
19-03-2013
Будем ждать новых статей.
Savage
18-03-2013
А неймспейсы в 6-й версии PHP как раз для решения проблемы с пересечением названий и придумали? Или префиксы лучше всегда использовать?
twin
18-03-2013
Неймспейсы и префиксы служат для совершенно разных целей. Неймспейс ограничивает область видимости, локализует код. Префиксы уберегают от неоднозначности. Может возникнуть ситуация и внутри неймспейса, если мы захотим установить константу с мудреным именем LOG_AUTHPRIV и удивленно будем хлопать глазами, почему так нельзя. Да просто это предустановленная константа. А если IRB_LOG_AUTHPRIV никаких претензий нет.
Savage
19-03-2013
Понял, спасибо.
pamparam
18-03-2013
Спасибо Вам за Ваше терпение .....
Прочитал наматал на ус...
Игорь
08-07-2013
Пере залейте картинки пожалуйста. Они не отображаются в статье.
ABC
09-07-2014
Как всегда, супер. Спасибо!

 
Наверх