ФорумФорум  КалендарьКалендарь  ЧаВоЧаВо  ПоискПоиск  ПользователиПользователи  ГруппыГруппы  РегистрацияРегистрация  Вход  
Поиск
 
 

Результаты :
 
Rechercher Расширенный поиск
Последние темы
» Подтверждение о прочтении
автор worker8281 Сб Дек 27, 2014 1:05 pm

» Проблема с сессией
автор Murphy Ср Дек 03, 2014 5:20 pm

» Нужнга настройка SugarCRM
автор iliandr777 Пн Ноя 10, 2014 2:28 pm

» Отображение записей (адресатов) в списках адресатов
автор FatherMother Пн Авг 25, 2014 12:21 pm

» Нужен совет. Модуль с множеством одинаковых субпанелей.
автор Павел Пн Июл 28, 2014 12:55 pm

» Нужна помощь с опенкартом
автор manux86 Вс Фев 02, 2014 10:45 am

» вопрос работы насчет СУГАР на сервере
автор Meiir2 Пт Янв 31, 2014 8:46 am

» Интеграция с Google календарем от компании "Куб Три"
автор Dmitry.bereza Ср Авг 14, 2013 10:29 am

» настройка воронки продаж
автор EkaterinaGolovina Чт Июн 13, 2013 12:14 pm

Июль 2018
ПнВтСрЧтПтСбВс
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
КалендарьКалендарь
Баннеры
Яндекс цитирования статистика
Поддержка проекта
41001634550309

Поделиться | 
 

 5 полезных в PHP навыков

Перейти вниз 
АвторСообщение
Admin
Admin


Сообщения : 74
Очки : 71
Дата регистрации : 2010-08-23

СообщениеТема: 5 полезных в PHP навыков   Чт Сен 09, 2010 6:34 pm

Перевод статьи Nathan A. Good, размещенной на IBM DeveloperWorks

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

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

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

1. Давайте правильные имена
2. Разбивайте код на небольшие части
3. Документируйте код
4. Обрабатывайте ошибки
5. Никогда, никогда не делайте копи-пейст!


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

Пример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. Хорошо: Смысловое отражение в именах

Код:

<?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 coding (да простит меня читатель, но это я не перевела). Это значит писать код, который работает хорошо в благоприятной обстановке, когда все данные правильны и все условия выполняются, как и ожидалось. Но такой код неустойчив. С другой стороны, вы можете потратить слишком много времени на условия, с которыми никогда не столкнетесь.
Плохая привычка: Ошибки не обрабатываются вообще
Код в листинге 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");

?>


Заключение
Если вы разовьете навыки описанные в этой статье, вы построите код который просто читать, понимать и поддерживать. Создание легко поддерживаемого приложения позволит вам отладить, исправить и расширить его с низким уровнем риска.

Использование правильных имен и организация кода небольшими блоками упрощает чтение. Документирование целей того, что методы и классы намереваются делать, упрощает понимание и облегчает возможность наращивания. Обработка ошибок должным образом делает код более устойчивым. И наконец, за счет отказа от копи-паста, код становиться чище.
Вернуться к началу Перейти вниз
Посмотреть профиль http://easy-sugarcrm.forum2x2.ru
 
5 полезных в PHP навыков
Вернуться к началу 
Страница 1 из 1

Права доступа к этому форуму:Вы не можете отвечать на сообщения
 :: PHP - статьи, советы-
Перейти: