Пять хороших привычек при программировании на PHP

Эти привычки упростят чтение и сопровождение вашего PHP-кода

Точно так же, как и в случае любого другого языка программирования, PHP-разработчики способны написать на PHP код самого различного качества – от совершенно ужасного до очень хорошего

Натан А. Гуд, инженер по программному обеспечению, консультант

Натан Гуд (Nathan A. Good) живет в регионе Twin Cities (штат Миннесота, США). Н. Гуд профессионально занимается разработкой программного обеспечения, архитектурой программного обеспечения и системным администрированием. Когда Н. Гуд не занят написанием программного обеспечения, он с удовольствием занимается построением ПК и серверов, изучением и освоением новых технологий, а также убеждением своих коллег в необходимости перехода на программное обеспечение с открытым кодом. Натан Гуд лично и в соавторстве написал множество книг и статей, в том числе: Professional Red Hat Enterprise Linux 3, Regular Expression Recipes: A Problem-Solution Approach, Regular Expression Recipes for Windows Developers: A Problem-Solution Approach, PHP 5 Recipes: A Problem-Solution Approach. Самая новейшая из его работ: Foundations of PEAR: Rapid PHP Development.



18.06.2009

Точно так же, как и в случае любого другого языка программирования, PHP-разработчики способны написать на PHP код самого различного качества – от совершенно ужасного до очень хорошего. Освойте навыки хорошего программирования, которые помогут вам повысить свою продуктивность.

С точки зрения продуктивности «прекрасный» разработчик может превосходить просто «хорошего» разработчика в 10 – 20 раз. Прекрасный разработчик является более продуктивным вследствие своего опыта и следования хорошим привычкам. Привычки плохого программирования, прокравшиеся в ваш код, являются причиной снижения продуктивности. В данной статье демонстрируется несколько хороших привычек, следование которым поможет вам повысить свое профессиональное мастерство программиста.

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

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

  1. Давайте надлежащие имена
  2. Разбивайте код на фрагменты меньшего размера
  3. Документируйте свой код
  4. Обрабатывайте ошибки
  5. Никогда не пользуйтесь операцией «копировать и вставить»

Следующие разделы посвящены подробному разъяснению этих привычек.

Давайте надлежащие имена

Использование «хороших» имен – это самая важная привычка, поскольку содержательные имена упрощают чтение и понимание программного кода. Понятность вашего кода в конечном итоге определяет возможность его последующего сопровождения. Даже если написанный вами код не будет содержать комментариев, но при этом будет прост для понимания, то вам или кому-либо еще будет легче его изменить в случае необходимости. При выработке этой привычки ваша цель должна состоять в том, чтобы благодаря «хорошим» именам ваш код читался так же легко, как книга.

Плохая привычка: неоднозначные или бессмысленные имена

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

Листинг 1. Плохая привычка: неоднозначные или бессмысленные имена
<?php

function getNBDay($d)
{
    switch($d) {
        case 5:
        case 6:
        case 7:
            return 1;
        default:
            return ($d + 1);
    }
}

$day = 5;

$nextDay = getNBDay($day);

echo ("Next day is: " . $nextDay . "\n");

?>

Хорошая привычка: осмысленные и лаконичные имена

Код, приведенный в листинге 2, демонстрирует использование хороших привычек именования. Измененные имена методов лучше отражают, что делают эти методы и почему. Имена переменных также стали более содержательными. Единственная переменная, которая осталась короткой в этом листинге – это переменная цикла $i. Хотя многие могут не согласиться со мной, но я считаю, что короткое название для переменной цикла является вполне приемлемым и даже хорошим выбором, поскольку оно четко указывает на ее функциональное назначение.

Листинг 2. Хорошая привычка: осмысленные и лаконичные имена
<?php

define ('MONDAY', 1);
define ('TUESDAY', 2);
define ('WEDNESDAY', 3);
define ('THURSDAY', 4);
define ('FRIDAY', 5);
define ('SATURDAY', 6);
define ('SUNDAY', 7);

/*
 *
 * @param $dayOfWeek
 * @return int Day of week, with 1 being Monday and so on.
 */
function findNextBusinessDay($dayOfWeek)
{
    $nextBusinessDay = $dayOfWeek;

    switch($dayOfWeek) {
        case FRIDAY:
        case SATURDAY:
        case SUNDAY:
            $nextBusinessDay = MONDAY;
            break;
        default:
            $nextBusinessDay += 1;
            break;
    }

    return $nextBusinessDay;
}

$day = FRIDAY;

$nextBusDay = findNextBusinessDay($day);

echo ("Next day is:" . $nextBusDay . "\n");

?>

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


Разбивайте код на фрагменты меньшего размера

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

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

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

Плохая привычка: длинные функции (которые делают слишком много)

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

Листинг 3. Плохая привычка: длинные функции
<?php

function writeRssFeed($user)
{
    // Get the DB connection information
    
    
    // look up the user's preferences...
    $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
        OR die(mysql_error());

    // Query
    $perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= '%s'",
            mysql_real_escape_string($user));

    $result = mysql_query($query, $link);
    
    $max_stories = 25; // default it to 25;
    
    if ($row = mysql_fetch_assoc($result)) {
        $max_stories = $row['max_stories'];
    }
            
    // go get my data
    $perfsQuery = sprintf("SELECT * FROM stories WHERE post_date = '%s'",
            mysql_real_escape_string());
            
    $result = mysql_query($query, $link); 


    $feed = "<rss version=\"2.0\">" .
        "<channel>" .
        "<title>My Great Feed</title>" .
        "<link>http://www.example.com/feed.xml</link>" .
        "<description>The best feed in the world</description>" .
        "<language>en-us</language>" .
        "<pubDate>Tue, 20 Oct 2008 10:00:00 GMT</pubDate>" .
        "<lastBuildDate>Tue, 20 Oct 2008 10:00:00 GMT</lastBuildDate>" .
        "<docs>http://www.example.com/rss</docs>" .
        "<generator>MyFeed Generator</generator>" .
        "<managingEditor>editor@example.com</managingEditor>" .
        "<webMaster>webmaster@example.com</webMaster>" .
        "<ttl>5</ttl>";
    
        // build the feed...
        while ($row = mysql_fetch_assoc($result)) {
            $title = $row['title'];
            $link = $row['link'];
            $description = $row['description'];
            $date = $row['date'];
            $guid = $row['guid'];

            $feed .= "<item>";
            $feed .= "<title>" . $title . "</title>";
            $feed .= "<link>" . $link . "</link>";
            $feed .= "<description> " . $description . "</description>";
            $feed .= "<pubDate>" . $date . "</pubDate>";
            $feed .= "<guid>" . $guid . "</guid>";
            $feed .= "</item>";
        }

        $feed .= "</rss";

        // write the feed out to the server...
        echo($feed);

}

?>

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

Хорошая привычка: управляемые, фокусированные функции

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

Листинг 4. Хорошая привычка: управляемые, конкретные функции
<?php

function createRssHeader()
{
    return "<rss version=\"2.0\">" .
        "<channel>" .
        "<title>My Great Feed</title>" .
        "<link>http://www.example.com/feed.xml</link>" .
        "<description>The best feed in the world</description>" .
        "<language>en-us</language>" .
        "<pubDate>Tue, 20 Oct 2008 10:00:00 GMT</pubDate>" .
        "<lastBuildDate>Tue, 20 Oct 2008 10:00:00 GMT</lastBuildDate>" .
        "<docs>http://www.example.com/rss</docs>" .
        "<generator>MyFeed Generator</generator>" .
        "<managingEditor>editor@example.com</managingEditor>" .
        "<webMaster>webmaster@example.com</webMaster>" .
        "<ttl>5</ttl>";
}

function createRssFooter()
{
    return "</channel></rss>";
}

function createRssItem($title, $link, $desc, $date, $guid) 
{
    $item .= "<item>";
    $item .= "<title>" . $title . "</title>";
    $item .= "<link>" . $link . "</link>";
    $item .= "<description> " . $description . "</description>";
    $item .= "<pubDate>" . $date . "</pubDate>";
    $item .= "<guid>" . $guid . "</guid>";
    $item .= "</item>";
    return $item;
}

function getUserMaxStories($db_link, $default)
{
    $perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= '%s'",
            mysql_real_escape_string($user));

    $result = mysql_query($perfsQuery, $db_link);
    
    $max_stories = $default;
    
    if ($row = mysql_fetch_assoc($result)) {
        $max_stories = $row['max_stories'];
    } 
    
    return $max_stories;
}

function writeRssFeed($user)
{
    // Get the DB connection information
    $settings = parse_ini_file("rss_server.ini");
    
    // look up the user's preferences...
    $link = mysql_connect($settings['db_host'], $settings['user'], 
        $settings['password']) OR die(mysql_error());

    $max_stories = getUserMaxStories($link, 25);
        
    // go get my data
    $newsQuery = sprintf("SELECT * FROM stories WHERE post_date = '%s'",
            mysql_real_escape_string(time()));
            
    $result = mysql_query($newsQuery, $link); 

    $feed = createRssHeader();
    
    $i = 0;
    // build the feed...
    while ($row = mysql_fetch_assoc($result)) {
        if ($i < $max_stories) {
            $title = $row['title'];
            $link = $row['link'];
            $description = $row['description'];
            $date = $row['date'];
            $guid = $row['guid'];

            $feed .= createRssItem($title, $link, $description, $date, $guid);
            
            $i++;
        } else { 
            break;
        }
    }
    
    mysql_close($link);

    $feed .= createRssFooter();

    // write the feed out to the server...
    echo($feed);
}
?>

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


Документируйте свой код

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

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

Плохая привычка: отсутствующее и избыточное документирование функций

Комментарии в листинге 5 просто описывают, что делает код – осуществляет итерацию цикла или добавление числа. Однако при этом отсутствует объяснение, почему выполняется именно это. Тому, кто в будущем станет сопровождать этот код, будет непросто понять, сможет ли он безопасно изменить этот код.

Листинг 5. Плохая привычка: отсутствующее и избыточное документирование функций
<?php

class ResultMessage 
{
    private $severity;
    private $message;
    
    public function __construct($sev, $msg) 
    {
        $this->severity = $sev;
        $this->message = $msg;
    }
    
    public function getSeverity()
    {
        return $this->severity;
    }
    
    public function setSeverity($severity)
    {
        $this->severity = $severity;
    }
    
    public function getMessage()
    {
        return $this->message;
    }
    
    public function setMessage($msg)
    {
        $this->message = $msg;
    }
}

function cntMsgs($messages)
{
    $n = 0;
    /* iterate through the messages... */
    foreach($messages as $m) {
        if ($m->getSeverity() == 'Error') {
            $n++; // add one to the result;
        }
    }
    return $n;
}

$messages = array(new ResultMessage("Error", "This is an error!"),
    new ResultMessage("Warning", "This is a warning!"),
    new ResultMessage("Error", "This is another error!"));
    
$errs = cntMsgs($messages);

echo("There are " . $errs . " errors in the result.\n");

?>

Хорошая привычка: документирование функций и классов

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

Листинг 6. Хорошая привычка: документирование функций и классов
<?php
/**
 * The ResultMessage class holds a message that can be returned
 * as a result of a process. The message has a severity and
 * message.
 * 
 * @author nagood
 *
 */
class ResultMessage 
{
    private $severity;
    private $message;
    
    /**
     * Constructor for the ResultMessage that allows you to assign
     * severity and message.
     * @param $sev See {@link getSeverity()}
     * @param $msg
     * @return unknown_type
     */
    public function __construct($sev, $msg) 
    {
        $this->severity = $sev;
        $this->message = $msg;
    }
    
    /**
     * Returns the severity of the message. Should be one
     * "Information", "Warning", or "Error".
     * @return string Message severity
     */
    public function getSeverity()
    {
        return $this->severity;
    }
    
    /**
     * Sets the severity of the message
     * @param $severity
     * @return void
     */
    public function setSeverity($severity)
    {
        $this->severity = $severity;
    }
    
    public function getMessage()
    {
        return $this->message;
    }
    
    public function setMessage($msg)
    {
        $this->message = $msg;
    }
}


/*
 * Counts the messages with the given severity in the array
 * of messages.
 * 
 * @param $messages An array of ResultMessage
 * @return int Count of messages with a severity of "Error"
 */
function countErrors($messages)
{
    $matchingCount = 0;
    foreach($messages as $m) {
        if ($m->getSeverity() == "Error") {
            $matchingCount++;
        }
    }
    return $matchingCount;
}

$messages = array(new ResultMessage("Error", "This is an error!"),
    new ResultMessage("Warning", "This is a warning!"),
    new ResultMessage("Error", "This is another error!"));
    
$errs = countErrors($messages);

echo("There are " . $errs . " errors in the result.\n");

?>

Обрабатывайте ошибки

Хорошо известно, что при написании устойчивых приложений объем кода для обработки ошибок должен соответствовать правилу 80/20: 80% кода посвящено обработке исключений и валидации, 20% кода выполняет фактическую работу. Вполне естественно, что при написании кода многие разработчики ориентируются на наиболее благоприятный сценарий (happy-path). Такой код хорошо работает в т.н. «базовой» обстановке, когда все данные являются валидными, а все условия соответствуют ожидаемым. Однако в течение срока службы приложения такой код может проявить свою неустойчивость. С другой стороны, вы можете потратить слишком много времени на написание кода в расчете на условия, с которыми, возможно, никогда не столкнетесь.

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

Плохая привычка: полное отсутствие обработки ошибок

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

Листинг 7. Плохая привычка: полное отсутствие обработки ошибок
<?php

// Get the actual name of the 
function convertDayOfWeekToName($day)
{
    $dayNames = array(
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday");
    return $dayNames[$day];
}

echo("The name of the 0 day is:  " . convertDayOfWeekToName(0) . "\n");
echo("The name of the 10 day is:  " . convertDayOfWeekToName(10) . "\n");
echo("The name of the 'orange' day is:  " . convertDayOfWeekToName('orange') . "\n");

?>

Хорошая привычка: программирование с защитой

В листинге 8 демонстрируется осмысленное выполнение обработки и бросания исключений. Добавленная обработка ошибок не только повысила устойчивость кода, но и улучшила его удобочитаемость и понятность. Используемый способ обработки исключений позволяет четко увидеть, каковы были намерения автора при написании данного метода.

Листинг 8. Хорошая привычка: программирование с защитой
<?php

/**
 * This is the exception thrown if the day of the week is invalid.
 * @author nagood
 *
 */
class InvalidDayOfWeekException extends Exception { }

class InvalidDayFormatException extends Exception { }

/**
 * Gets the name of the day given the day in the week. Will
 * return an error if the value supplied is out of range.
 * 
 * @param $day
 * @return unknown_type
 */
function convertDayOfWeekToName($day)
{
    if (! is_numeric($day)) {
        throw new InvalidDayFormatException('The value \'' . $day . '\' is an ' .
            'invalid format for a day of week.');
    }
    
    if (($day > 6) || ($day < 0)) {
        throw new InvalidDayOfWeekException('The day number \'' . $day . '\' is an ' .
            'invalid day of the week. Expecting 0-6.');
    }
    
    $dayNames = array(
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday");
    return $dayNames[$day];
}

echo("The name of the 0 day is:  " . convertDayOfWeekToName(0) . "\n");

try {
    echo("The name of the 10 day is:  " . convertDayOfWeekToName(10) . "\n");
} catch (InvalidDayOfWeekException $e) {
    echo ("Encountered error while trying to convert value:  " . $e->getMessage() . "\n");
}

try {
    echo("The name of the 'orange' day is:  " . convertDayOfWeekToName('orange') . "\n");
} catch (InvalidDayFormatException $e) {
    echo ("Encountered error while trying to convert value:  " . $e->getMessage() . "\n");
}

?>

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

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

Никогда пользуйтесь операцией «копировать и вставить»

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

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

Плохая привычка: схожие фрагменты кода

В листинге 9 показано несколько методов, которые почти идентичны, за исключением нескольких значений. Существуют инструменты, которые помогут вам найти код, полученный путем копирования и вставки (см. раздел Ресурсы).

Листинг 9. Плохая привычка: схожие фрагменты кода
<?php
/**
 * Counts the number of messages found in the array of 
 * ResultMessage with the getSeverity() value of "Error"
 * 
 * @param $messages An array of ResultMessage
 * @return unknown_type
 */
function countErrors($messages)
{
    $matchingCount = 0;
    foreach($messages as $m) {
        if ($m->getSeverity() == "Error") {
            $matchingCount++;
        }
    }
    return $matchingCount;
}

/**
 * Counts the number of messages found in the array of 
 * ResultMessage with the getSeverity() value of "Warning"
 * 
 * @param $messages An array of ResultMessage
 * @return unknown_type
 */
function countWarnings($messages)
{
    $matchingCount = 0;
    foreach($messages as $m) {
        if ($m->getSeverity() == "Warning") {
            $matchingCount++;
        }
    }
    return $matchingCount;
}

/**
 * Counts the number of messages found in the array of 
 * ResultMessage with the getSeverity() value of "Information"
 * 
 * @param $messages An array of ResultMessage
 * @return unknown_type
 */
function countInformation($messages)
{
    $matchingCount = 0;
    foreach($messages as $m) {
        if ($m->getSeverity() == "Information") {
            $matchingCount++;
        }
    }
    return $matchingCount;
}

$messages = array(new ResultMessage("Error", "This is an error!"),
    new ResultMessage("Warning", "This is a warning!"),
    new ResultMessage("Error", "This is another error!"));
    
$errs = countErrors($messages);

echo("There are " . $errs . " errors in the result.\n");
?>

Хорошая привычка: многократно используемые функции с параметрами

В листинге 10 показан измененный код, с преобразованием скопированного блока в один метод. Другие методы также были изменены, чтобы делегировать свою работу новому методу. Построение общего метода отнимает некоторое время на этапе проектирования; кроме того, вам обязательно придется остановиться и подумать, вместо того, чтобы инстинктивно использовать операцию «копировать и вставить». Однако вы с лихвой компенсируете затраченное вами время впоследствии, когда вам понадобится вносить какие-либо изменения.

Листинг 10. Хорошая привычка: многократно используемые функции с параметрами
<?php
    /*
     * Counts the messages with the given severity in the array
     * of messages.
     * 
     * @param $messages An array of ResultMessage
     * @return int Count of messages matching $withSeverity
     */
    function countMessages($messages, $withSeverity)
    {
        $matchingCount = 0;
        foreach($messages as $m) {
            if ($m->getSeverity() == $withSeverity) {
                $matchingCount++;
            }
        }
        return $matchingCount;
    }

    /**
     * Counts the number of messages found in the array of 
     * ResultMessage with the getSeverity() value of "Error"
     * 
     * @param $messages An array of ResultMessage
     * @return unknown_type
     */
    function countErrors($messages)
    {
        return countMessages($messages, "Errors");
    }

    /**
     * Counts the number of messages found in the array of 
     * ResultMessage with the getSeverity() value of "Warning"
     * 
     * @param $messages An array of ResultMessage
     * @return unknown_type
     */
    function countWarnings($messages)
    {
        return countMessages($messages, "Warning");
    }

    /**
     * Counts the number of messages found in the array of 
     * ResultMessage with the getSeverity() value of "Warning"
     * 
     * @param $messages An array of ResultMessage
     * @return unknown_type
     */
    function countInformation($messages)
    {
        return countMessages($messages, "Information");
    }

    $messages = array(new ResultMessage("Error", "This is an error!"),
        new ResultMessage("Warning", "This is a warning!"),
        new ResultMessage("Error", "This is another error!"));
        
    $errs = countErrors($messages);

    echo("There are " . $errs . " errors in the result.\n");

?>

Заключение

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

Использование хороших имен и организация кода в виде фрагментов меньшего размера упрощает его чтение. Документирование назначения вашего кода упрощает понимание ваших намерений и облегчает возможность расширения. Надлежащая обработка ошибок делает код более устойчивым. И, наконец, отказ от «костыля» в виде операции «копировать/вставить» позволяет вам содержать свой код в чистоте.

Ресурсы

Научиться

  • Оригинал статьи: Five good programming habits in PHP (EN).
  • Прочитайте статью "Семь хороших привычек при объектно-ориентированном программировании на PHP" (EN), посвященную переходу от процедурного программирования к объектно-ориентированному программированию.
  • Прочитайте книгу Code Complete (EN), автор Steven C. McConnell (русский перевод: Совершенный код, Стивен Макконнелл), посвященную разработке высококачественного программного кода.
  • Прочитайте статью "Advanced PHP V5 objects" (EN) о построении PHP-кода многократного использования.
  • Прочитайте статью "Five common PHP design patterns" (EN) (Пять типовых шаблонов проектирования в PHP) о применении объектно-ориентированных шаблонов проектирования в PHP
  • Прочитайте статью "Five more PHP design patterns" (EN) (Следующие пять типовых шаблонов проектирования в PHP) о применении объектно-ориентированных шаблонов проектирования в PHP.
  • В разделе Architecture zone (EN) сайта developerWorks размещены ресурсы, необходимые для совершенствования навыков в архитектурной области.
  • PHP.net (EN): центральный ресурс для PHP-разработчиков.
  • Ознакомьтесь со "списком рекомендованной литературы по PHP." (EN)
  • Для углубления навыков по PHP рекомендуем посетить раздел ресурса IBM developerWorks под названием Ресурсы проекта PHP (EN).
  • Прослушайте интересные интервью и дискуссии для разработчиков ПО: подкасты ресурса developerWorks (EN).
  • Используете базу данных с PHP? Ознакомьтесь с продуктом Zend Core for IBM (EN) – простой в установке и применении, готовой к использованию средой для разработки и эксплуатации кода на языке PHP, поддерживающей IBM DB2 V9.
  • Следите за техническими событиями и Web-трансляциями на ресурсе developerWorks (EN).
  • Своевременно узнавайте о намечаемых конференциях, выставках, Web-трансляциях и других событиях (EN) во всем мире, представляющих интерес для разработчиков продуктов IBM с открытым кодом.
  • Посетите раздел Web-сайта developerWorks, посвященный продуктам с открытым кодом (EN) – к вашим услугам обширный ассортимент справочной информации, инструментов и обновлений, который поможет осуществлять разработки на основе технологий с открытым кодом и использовать их вместе с продуктами IBM.
  • Наблюдайте и изучайте технологии IBM и технологии с открытым кодом, а также функции новых продуктов бесплатно: демонстрации «по запросу» на ресурсе developerWorks (EN).

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


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

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source
ArticleID=394753
ArticleTitle=Пять хороших привычек при программировании на PHP
publish-date=06182009