Отправляет email-рассылки с помощью сервиса Sendsay

PHP 5: Новые возможности.

  Все выпуски  

ZEND FRAMEWORK: Стандарты кодирования


Вниманию читателей!

Отдельные выпуски рассылки в той или иной мере взаимосвязаны; особенно, это относится к материалам практических занятий.

С предыдущими выпусками Вы можете ознакомиться:

  1. в архиве рассылки (оригиналы выпусков);
  2. на сайте рассылки (исправленные и дополненные версии).

Кроме того, для чтения в онлайне доступен сборник статей, составленный на основе выпусков рассылки.

# # #

Вы также можете подписаться на рассылку "PHP 5 для начинающих".

PHP 5: Новые возможности.

В предлагаемом материале освещены стандарты кодирования, рекомендуемые для применения вместе с Zend Framework как отдельными разработчиками, так и командами разработчиков, и касающиеся следующих тем.

  1. Форматирование PHP файлов.

  2. Использование имен.

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

  4. Встроенная документация.

Zend Framework, как и PEAR [10], использует свои стандарты кодирования [9], применение которых особенно продуктивно в случае командной разработки приложений. Стандартизация позволяет добиться более высокого качества кода, минимизировать количество ошибок, облегчить управление проектом и т. д.

[Подсказка]Подсказка

Перед изучением изложенного далее материала может оказаться полезным вспомнить стандарты кодирования, принятые в PEAR. Сделать это поможет статья "Стандарты кодирования" в электронном сборнике "PHP 5: Новые возможности", опубликованном на сайте Pterodactyl's School.

Закрывающий тэг. В файлах, содержащих только PHP код, использование закрывающего PHP тэга (?>) не разрешается.


[Замечание]Замечание

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

Пример 5.2. Влияние закрывающего PHP тэга на вывод

<?php

// foo.inc
print 'Foo';

?> 1
                
<?php

// foo.php
print '[';
include 'foo.inc';
print ']';

?>
                
1

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

[Foo ] 1
1

Наличие дополнительного пробельного символа приводит к непредусмотенному результату (ожидалось, что будет выведено сообщение, показанное ниже).

[Foo]

Отступы. В качестве отступа используется последовательность, состоящая из четырех пробелов. Символ табуляции не используется.

Длина строк. Следует стремиться к тому, чтобы длина строк не превышала 80 символов. Однако, допустимы и более длинные строки. Максимальная длина любой строки PHP кода составляет 120 символов.

Перевод строк. Используются переводы строк в стиле Unix (LF; код 0x0A), но не в стиле Macintosh (CR; код 0x0D) или Windows (CRLF; коды 0x0D, 0x0A).

Классы. Названия классов должны находиться в прямой зависимости от директорий, в которых они хранятся. Корневой директорией для классов Zend Framework является директория Zend, в которой все классы хранятся в иерархическом порядке.

Названия классов могут содержать только буквенно-цифровые символы; однако, использование цифр не рекомендуется. Знаки подчеркивания разрешены только в качестве замены путевого разделителя (например, класс Zend_Controller_Front в файле Zend/Controller/Front.php).

Если название класса состоит из нескольких слов, то каждое новое слово должно начинаться с прописной буквы. Следующие одна за другой заглавные буквы не разрешаются (так, например, следует использовать Zend_Db вместо Zend_DB; Zend_Http_Client вместо Zend_HTTP_Client и т. д.).

Названия классов, входящих в поставку Zend Framework, должны всегда начинаться с Zend_ (и, соответственно, храниться в директории Zend/).

[Внимание]Внимание

Названия классов, не входящих в поставку Zend Framework (хоть и взаимодействующих с этим приложением), никогда не должны начинаться с Zend_.

Интерфейсы. Названия интерфейсов должны во всем следовать соглашениям, принятым для классов (см. Классы), за исключением того, что они всегда должны иметь окончание _Interface.

Файлы. Для названий всех других файлов разрешены только буквенно-цифровые символы, знаки подчеркивания (_) и черточки (-). При этом названия файлов, в которых содержится PHP код, должны иметь расширение .php.

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

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

[Подсказка]Подсказка

Многословные названия функций приветствуются (конечно, в разумных пределах), поскольку помогают сделать код более понятным.

Названия акцессоров всегда должны начинаться с get или set, а реализации шаблонов проектирования (например, Singleton или Factory) в своем названии должны содержать название шаблона.

Глобальные функции допустимы, но нежелательны. Вместо них предпочтительнее использовать статические методы классов.

Переменные. Названия переменных могут содержать только буквенно-цифровые символы, но использование цифр не рекомендуется. Использование знаков подчеркивания не разрешается (за исключением первого символа в названиях свойств класса, объявленных как приватные (private) или защищенные (protected), где использование знака подчеркивания, напротив, обязательно).

[Внимание]Внимание

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

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

[Замечание]Замечание

В небольших циклах допускаются краткие названия для счетчиков ($i, $j и т. п.); однако, если количество строк кода в теле цикла превышает двадцать, то даже эти переменные следует называть более осмысленно.

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

Все буквы в названиях констант должны быть прописными; поэтому для разделения слов следует использовать знаки подчеркивания (например, THE_VERY_LONG_CONSTANT_NAME, но ни в коем случае не THEVERYLONGCONSTANTNAME).

Константы следует объявлять как члены класса, используя конструктор const. Объявление констант в глобальном контексте с помощью функции define() допустимо, но нежелательно.

Литералы. Если строка не содержит переменных, вместо которых должны быть подставлены их значения, то для ее отграничения следует использовать одинарные кавычки.

$str
= 'Foo';

Литералы, содержащие апострофы. Если в строковом литерале встречаются апострофы, то его разрешается отграничивать с помощью двойных кавычек (это особенно касается SQL выражений).

$sql = "SELECT 'id' FROM 'table' WHERE 'foo'='bar' OR 'bar'='foo'";

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

$hello
= "Hello, $name!";
$hello = "Hello, {$name}!";
[Внимание]Внимание

Однако, использование фигурных скобок только вокруг названия переменной (когда символ $ остается за их пределами) не разрешается.

$hello = "Hello, ${name}!"; // NOT PERMITTED

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

$str = 'Foo' . 'Bar';
[Замечание]Замечание

Если при слиянии получается слишком длинное выражение, то для повышения читабельности допустимо разбивать его на несколько строк кода; при этом оператор конкатенции выравнивается таким образом, чтобы он находился на одном уровне с оператором присваивания (=).

$sql = "SELECT 'id' FROM 'table' "
     . "WHERE 'foo'='bar' OR 'bar'='foo'";
                

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

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

$a = array(777, M_PI, $foo, 'bar');

Если количество элементов слишком большое, разрешаются многострочные объявления; при этом последующие строки необходимо выравнивать по отношению к первому элементу.

$a = array($a, $b, $c,
           $d[0], $d[1], $d[2],
           'foo', 'bar');
            

Ассоциативные. При объявлении с помощью конструктора array() ассоциативных массивов не только разрешается, но и рекомендуется использовать многострочный код. В данном случае выравниваются как ключи, так и значения элементов массива.

$a = array($foo      => $bar,
           'somekey' => 'value');
            

Объявление. Классы должны объявляться в соответствии с соглашением об именах (см. Классы). Каждая из фигурных скобок, окружающих тело класса, должна находиться на отдельной строке, без каких-либо отступов[6]. Для кода в теле класса используется отступ в четыре пробела. Объявлению класса должен предшествовать блок встроенной документации.

/**
 * Class Documentation Block
 */
class FooClass
{
    // code intended 4 spaces
}
            

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

Свойства. Названия свойств класса должны следовать соглашениям об именах (Переменные) и располагаться в самом начале класса до объявления каких-либо методов. Использование конструктора var не разрешается; вместо этого всегда следует объявлять видимость свойств класса с помощью модификаторов доступа public, protected и private (при этом следует помнить, что публичные свойства предполагают непосредственный доступ, а это не приветствуется, хоть и разрешено; следует отдавать предпочтение использованию акцессоров get/set).

Объявление. Названия функций должны следовать соглашениям об именах (Функции и методы). Между названием функции и открывающей круглой скобкой для аргументов не должно быть ни одного пробела. Для методов класса всегда должна быть объявлена видимость с помощью модификаторов доступа public, protected и private. Каждая из фигурных скобок, окружающих тело функции, должна находиться на отдельной строке, на одном уровне с началом объявления функции. Для кода в теле функции используется отступ в четыре пробела. Объявлению любой функции должен предшествовать блок встроенной документации.

    /**
    * Function Documentation Block
    */
    function foo()
    {
        // code intended 4 spaces
    }
            

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

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

foo(array($a, $b, $c,
          $d[0], $d[1], $d[2],
          'foo', 'bar'), 'x', 'y', 'z');
            

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

if ($x == 1) {
    // code intended 4 spaces
} elseif (($y == 2) || ($z == 3)) {
    // code intended 4 spaces
} else {
    // code intended 4 spaces
}
            

Рекомендуется отдавать предпочтение конструкции else if вместо elseif.

switch. Контрольные структуры на основе switch должны иметь по одному пробелу до и после круглых скобок с условием. Правила употребления фигурных скобок совпадают с таковыми для контрольной структуры на основе if / elseif / else. Код в целом должен иметь отступ в 4 пробела. Выражения case располагаются на отдельных строках, а последующий код должен иметь дополнительный отступ в 4 пробела. Блок по умолчанию (default) должен всегда присутствовать. В случае пропуска break для последовательного выполнения нескольких блоков обязательно наличие комментария о преднамеренном характере такого шага. Отдельные блоки разделяются пустой строкой.

switch ($foo) {
    case 1:
        break;

    case 2:
        // break intentionally omitted

    case 3:
        break;

    default:
        break;
}
            

Формат. Все блоки документации должны быть совместимы с форматом phpDocumentor (http://phpdoc.org/). Наличие блоков уровня файла и класса является обязательным.

Файлы. Каждый файл, содержащий PHP код должен иметь в своем начале блок документации со следующим минимумом тэгов (приведены примерные значения).

/**
 * Short file description
 *
 * Long file description (optional)...
 *
 * LICENSE: Permissions are granted to...
 *
 * @copyright  2006 Pterodactyl's School
 * @license    http://www.zend.com/license/3_0.txt   PHP License 3.0
 * @version    CVS: $Id:$
 * @link       http://pterodactyl.l2p.net/download/PackageName/
 * @since      1.2.0
*/        

Классы. Каждый класс должен быть предварен блоком документации со следующим минимумом тэгов (приведены примерные значения).

/**
 * Short class description
 *
 * Long class description (optional)...
 *
 * @copyright  2006 Pterodactyl's School
 * @license    http://www.zend.com/license/3_0.txt   PHP License 3.0
 * @version    Release: @package_version@
 * @link       http://pterodactyl.l2p.net/download/PackageName/
 * @since      1.2.0
 * @deprecated 2.0.0
 */        

Функции. Каждая функция, включая методы классов, должна быть предварена блоком документации, включающей, как минимум, описание функции, ее аргументы и возможные возвращаемые значения. Необходимость в использовании тэга @access отпадает, так как его заменяют модификаторы доступа public, protected и private. Если функция или метод могут генерировать исключительную ситуацию, документация должна включать тэг @throw.

@throws exceptionclass [description]
  1. Какие стандарты кодирования и рекомендации, принятые в Zend Framework, нарушены в приведенном ниже примере?

    <?php
    
    // foobar.php
    
    function foobar($x,$y)
    {
        // TO DO
    }
    
    class Foo
    {
        public $foo;
    
        function __construct()
        {
            // TO DO
        }
    }
    
    class Bar
    {
        var $bar;
    
        function __construct()
        {
            // TO DO
        }
    }
    
    ?>
                    
  2. Какому стандарту, PEAR или Zend Framework, соответствует приведенное ниже фрагмент кода? Объясните, почему.

    /**
     * TO DO
     */
    class Foo {
        /**
         * TO DO
         */
        function __construct()
        {
            // TO DO
        }
    }
                    
  3. Какому стандарту, PEAR или Zend Framework, соответствует приведенный ниже фрагмент кода? Объясните, почему.

        /**
         * TO DO
         */
        public function foo()
        {
            print 'Foo';
        }
                    
  4. Приведите в соответствие стандартам Zend Framework следующий пример кода (реализовывать блоки встроенной документации, помеченные как «TO DO», не нужно).

    <?
    
    /**
     * TO DO: File Documentation
     */
    
    /**
     * TO DO: Class Documentation
     */
    class Foo
    {
        /**
         * TO DO: Method Documentation
         */
        function Bar() {
        $foo = "Foo";
        $bar = "Bar";
        print $foo.$bar;
        }
    }
                    

«Ответы и решения к Глава 5, Стандарты кодирования»



[4] От английских слов stud (гвоздь с большой шляпкой) и cap (заглавная буква, сокращение от capital letter).

[5] От английских слов camel (верблюд) и cap (заглавная буква, сокращение от capital letter).

[6] В этом моменте наблюдается отличие от стандартов PEAR, согласно которым открывающая фигурная скобка в объявлении класса находится на одной строке с названием класса [10].

Created with DocBook


В избранное