Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 11
На сайте нет зарегистрированных пользователей

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Медиа плейер на Delphi + Пояснительная записка
Выбор наилучших альтернатив с использованием методов оптимизации на Delp...
База данных - рабочее место кассира на Delphi + бд Access

21 ошибка программиста PHP
Автор: Стерлинг Хьюз
Целевая аудитория
Эта серия статей предназначена для тех программистов на языке PHP, которые хотят избежать наиболее общих ошибок в написании кода. Читатель, как минимум, должен знать общий синтаксис PHP, а также весьма желателен некоторый опыт использования языка на практике.
Введение
Одна из наиболее сильных сторон PHP является, одновременно, и его слабой стороной: PHP очень прост в изучении. Это привлекает многих людей; однако, несмотря на его кажущуюся простоту, не так-то просто научиться использовать этот язык правильно и эффективно.
Как правило, дело в недостаточной практике программирования. Неопытные программисты становятся перед лицом необходимости создания сложных веб-приложений. Поэтому сплошь и рядом допускаются ошибки, которых избежал бы опытный программист, такие как необоснованное использование функции printf() или неправильное использование семантики PHP.
В этой серии из трех статей представлены наиболее, по нашему мнению, характерные ошибки. Эти ошибки можно классифицировать по нескольким категориям, от "некритических" до "смертельных". Наряду с анализом этих ошибок представлены способы их избежания, а также некоторые "маленькие хитрости", накопленные за многие годы практики программирования.
Часть 1: Описываются 7 "детских" ошибок (21-15 в обратном порядке, в соответствии со степенью серьезности по нашей классификации). Такие ошибки не вызывают серьезных проблем, но приводят к уменьшению эффективности работы программы, а также выражаются в громоздком трудночитаемом коде, в который, к тому же, трудно вносить изменения.
Часть 2: Следующие 7 ошибок (14-8) относятся к "серьезным". Они ведут к еще более значительному уменьшению скорости выполнения кода, уменьшению безопасности скриптов; код становится еще более запутанным.
Часть 3: Описания семи последних, "смертельных" ошибок. Эти ошибки концептуальны по своей природе и являются причиной появления ошибок, описанных в 1-ой и 2-ой частях статьи. Они включают и такие ошибки, как недостаточное внимание, уделенное как проекту в целом, так и коду программы, в частности.
21. Неоправданное использование функции printf()
Функция printf() предназначена для вывода форматированных данных.
Например, ее следует использовать при необходимости вывода переменной в формате с плавающей запятой с определенной точностью, либо в любом другом случае, когда возникает необходимость изменения формата выводимых данных.
Ниже приведен пример обоснованного применения функции printf(). В данном случае она используется для форматированного вывода числа "пи":
<?php

printf ("Число Пи: %2f\n
\n", M_PI);
printf ("Это тоже число Пи: %3f\n
\n", M_PI);
printf ("И это Пи: %4f\n
\n", M_PI);

?>




Примечание: Наблюдаются случаи патологической боязни функции printf(), когда люди пишут свои функции форматированного вывода, порой по 30-40 строк, хотя все проблемы мог бы решить один-единственный вызов функции printf().
Многие программисты используют функцию printf() для вывода переменных, результатов вызова функций, а иногда даже обычных текстовых данных. Наиболее часто это происходит в следующих двух случаях:
• когда следовало бы использовать функцию print();
• при выводе результатов, возвращаемых функциями.
Когда следует использовать print()
Вызов функции printf() зачастую используется там, где следовало бы использовать print(). В следующем примере функция printf() используется для вывода четырех переменных:
<?php

$name = 'Sterling Hughes';
$job = 'Senior Engineer';
$company = 'DesignMultimedia';
$email = 'shughes@designmultimedia.com';

printf ( "Меня зовут %s\n
\n
Я работаю %s, %s\n
\n
Мой адрес E-mail:%s\n
\n",
$name, $job, $company, $email );
?>



В данном случае возможно (и желательно!) применение print():
print "Меня зовут $name\n
\n
Я работаю в $company, $job\n
\n
Мой адрес E-mail: $email\n
\n";
Использование print() вместо printf() в случаях, когда выводятся неформатированные данные, как в данном примере, дает следующие выгоды:
• Увеличение производительности: Функция printf() форматирует свои аргументы перед выводом. Таким образом, время ее выполнения больше, чем для функций print() или echo().
• Более ясный код: Все-таки надо признать, что использование функции printf() затрудняет чтение кода (имеющих достаточный опыт программирования на C это, конечно, касается в меньшей степени). Чтобы функция printf() не повела себя самым неожиданным для вас образом, требуется как знание синтаксиса данной функции, (т.е. %s определяет строковый формат вывода, тогда как %d - десятичный), так и знание типов переменных.
Использование функции printf() для вывода значения, возвращаемого функцией
Еще одна характерная ошибка использования функции printf() - вывод значения, возвращаемого функцией, как в следующем примере:
<?php

printf ("Найдено %d вхождений строки %s", count ($result), $search_term);


?>



Наряду с функцией print() при использовании ее в тех же целях, следует использовать оператор "." В данном случае этот оператор добавляет текст к результату вызова функции:
<?php

print "Найдено " .
count ($result) .
" вхождений строки $search_term";

?>



Использование оператора . в паре с функцией print() позволяет избежать использования более медленной функции printf().
20. Неверное применение семантики языка
Многие программисты используют в своей работе PHP, фактически не понимая тонкостей этого языка. Одна из тонкостей - разница между синтаксисом и семантикой PHP.
• Синтаксис PHP: Представляет собой набор правил для определения элементов языка. Например, как мы определяем переменную? Ставим знак $ перед ее именем. Как определяем функцию? В общем случае, используя скобки, аргументы и т.п.
• Семантика PHP: Представляет собой набор правил для применения синтаксиса. Например, возьмем функцию с двумя аргументами, что определяется ее синтаксисом. Причем в качестве аргументов ей следует передавать переменные строкового типа - это определяется семантикой.
Заметьте: "следует". В языках с четким разделением типов (таких как Java или C) нет понятия "следует" (в общем случае, хотя бывают и исключения). В таком случае компилятор вынудит использовать переменные строго определенного типа.
Языки, в которых отсутствует само определение типов переменных, предоставляют больше гибкости в написании кода. Но, как бы то ни было, в случае неправильного использования семантики для большинства функций PHP следует ожидать появления сообщения об ошибке.
Возьмем кусок кода, который открывает файл и выводит его построчно:
<?php

$fp = @fopen ( 'somefile.txt', 'r' )
or die ( 'Не могу открыть файл somefile.txt' );

while ($line = @fgets ( "$fp", 1024)) // Здесь ошибка!

{
print $line;
}

@fclose ("$fp") // И здесь тоже color
or die( 'Не могу закрыть файл somefile.txt' );

?>



В данном случае появится сообщение об ошибке типа:
"Warning: Supplied argument is not a valid File-Handle resource in tst.php on line 4"



("Внимание: аргумент не может являться дескриптором файла")
Это вызвано тем, что переменная $fp заключена в двойные кавычки, что однозначно определяет ее как строку, тогда как функция fgets() ожидает в качестве первого аргумента дескриптор, но не строку. Соответственно, вам следует использовать переменную, которая может содержать дескриптор.
Примечание: В данном случае строковый тип допустим синтаксически.
Для решения проблемы следует просто убрать двойные кавычки:
<?php
$fp = @fopen ( 'somefile.txt', 'r' )
or die ( 'Не могу открыть файл somefile.txt' );


while ( $line = @fgets ($fp, 1024) )
{
print $line;
}

@fclose ($fp)
or die ( 'Не могу закрыть файл somefile.txt' );
?>



Как избежать неправильного приложения семантики?
В приведенном примере генерируется сообщение об ошибке. Но PHP предоставляет программисту больше свободы, чем другие, традиционные языки программирования. Это позволяет получать интересные результаты. Как минимум, теоретически возможно написать корректный код, неправильно используя семантику языка.
Но будьте осторожны, заигрывая с семантикой языка! Возможно появление трудноуловимых ошибок в программах. Если же вы все-таки решили поэкспериментировать, вам следует понимать три ключевых момента:
• Типы: В PHP каждая переменная в любой момент времени относится к определенному типу. И это несмотря на тот факт, что ее тип можно свободно изменять. Другими словами, в языке PHP переменная не может существовать, при этом не относясь к определенному типу (и, соответственно, не обладая характеристиками, присущими этому типу). В PHP есть 7 основных типов переменных: Boolean, resource, integer, double, string, array и object.
• Область видимости: В PHP переменные имеют область видимости, которая определяет то, откуда она может быть доступна и насколько долго будет существовать. Недопонимание концепции "области видимости" может проявляться в виде различного рода "плавающих" ошибок.
• php.ini: При написании кода следует понимать, что не все пользователи имеют такую же конфигурацию программно-аппаратных средств, как и вы. Таким образом, совершенно необходимо лишний раз убедиться, сохраняется ли работоспособность вашего кода в той конфигурации, в которой программа должна работать, а не в той, в которой разрабатывалась.
19. Недостаточно либо излишне комментированный текст
Плохо документированный текст программы является признаком эгоистичного программиста. Результатом попытки анализа вашей программы с целью внесения улучшений будет только головная боль. Причем все программисты считают самодокументированный код хорошим тоном, но сами крайне редко пишут комментарии.
Следует также избегать избыточных комментариев. Это тоже встречается очень редко, и, опять же, создает трудно читаемый исходный код. Следующий пример это иллюстрирует:
<?php // Начало кода

$age = 18; // Возраст равен 18

$age++; // Увеличим $age на один год

// Напечатаем приветствие
print "Вам сейчас 19 лет, и это значит, что Вам уже было:";
print "\n
\n
\n";


// Цикл "для" чтобы вывести все
// предыдущие значения возраста
for ($idx = 0; $idx < $age; $idx++)
{
// Напечатаем каждое значение возраста

print "$idx лет\n
\n";
}
// Конец кода
?>



И все-таки: где золотая середина?
Итак, какой же объем комментариев следует помещать в скрипт?! Это зависит от многого: от времени, которым вы располагаете, от политики компании, сложности проекта и т.д. Тем не менее, запомните несколько основных принципов, которым надо следовать при написании программ вне зависимости от вашего решения:
• Перед телом функции всегда помещайте комментарий - назначение функции.
• Добавляйте комментарии в сомнительных участках кода, когда нет уверенности, что он будет работать как надо.
• Если назначение кода неочевидно, внесите информацию о предназначении этого участка. Вы же потом воспользуетесь этим комментарием.
• Избегайте комментарии вида # - используйте только /* */ либо //.
Следующий пример иллюстрирует хороший стиль комментариев:
<?php

// Random_Numbers.lib
// Генерация случайных чисел различного типа

mt_srand((double)microtime()*1000000);

//
// mixed random_element(array $elements[, array weights])
// Возвращает случайный элемент массива-аргумента
// Массив weights содержит относительные вероятности
// выборки элементов
//

function random_element ($elements, $weights = array())
{

// Для корректного функционирования этого алгоритма
// количество элементов массива должно быть равным
// количеству элементов массива относительных вероятностей

if (count ($weights) == count ($elements)) {
foreach ($elements as $element) {
foreach ($weights as $idx) {


// Примечание: мы не используем $idx, потому что
// нам не нужен доступ к отдельным элементам
// массива weights

$randomAr[] = $element;
}
}
}
else {
$randomAr = $elements;
}

$random_element = mt_rand (0, count ($randomAr) - 1);
return $randomAr [$random_element];
}
?>



18. Слишком много переменных - слишком большое время выполнения
Некоторые прямо-таки страдают навязчивой идеей вводить временные переменные где надо и где не надо. Совершенно невозможно понять, чем руководствовался человек, написавший такой код:
<?php
$tmp = date ("F d, h:i a"); // т.е. формат даты February 23, 2:30 pm
print $tmp;
?>
Для чего здесь использована временная переменная?! Она просто не нужна:
<?php
print date ("F d, h:i a");
?>



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

// string reverse_characters (string str)
// Переворачивает строку символов

function reverse_characters ($str)
{
return implode ("", array_reverse (preg_split ("//", $str)));
}

?>




Вызову функции implode() в качестве одного из параметров передается результат выполнения вложенных функций, поэтому такой код трудно прочесть. В данном случае нам может здорово помочь использование временной переменной:
<?php

// string reverse_characters (string str)
// Переворачивает строку символов

function reverse_characters ($str)
{
$characters = preg_split ("//", $str);
$characters = array_reverse ($characters);
return implode ("", $characters);
}


?>



Золотое правило
Если вы думаете, ввести или нет еще одну временную переменную, задайте себе два вопроса:
• Будет ли эта переменная использована хотя бы дважды?
• Значительно ли улучшится с ее введением читаемость кода?
Если на любой из этих вопросов вы ответили "да", тогда введите временную переменную. Иначе комбинируйте вызовы функций (если это необходимо) и обойдитесь без ее использования.
17. Переписываем стандартные функции
Кое-кто рекомендует переименовывать стандартные функции для того, чтобы программистам на Visual Basic"е проще было перейти к использованию языка PHP:
<?php

function len ($str) {
return strlen ($str);
}
?>



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

Используйте стандартные функций языка!
Иногда так трудно устоять! Ведь программист редко знает сразу весь набор функций - у него обычно нет времени запомнить их все. Почему бы просто не переименовать функцию? Но, повторимся, этого не следует делать в силу изложенных выше причин.
Хорошо бы иметь под рукой справочник по функциям PHP (удобно использовать индексированную версию в формате PDF). И перед тем как написать какую-либо функцию, внимательно посмотреть - не существует ли она уже в списке стандартных функций.
Но следует заметить, что в кодах программ можно встретить пользовательские функции, написанные еще до их введения в качестве стандартных (например, функции сравнения двух массивов). Это не означает, что вы обязательно должны переписать код и заменять их стандартными функциями.
16. Клиентская часть программы не отделяется от серверной части
Многие программисты рекомендуют объединять код HTML (интерпретируемый на стороне клиента) и код PHP (выполняемый сервером) в один большой файл.
Для маленьких сайтов это, возможно, неплохо. Но, когда ваш сайт начнет расти, вы можете столкнуться с проблемами при необходимости добавить какие-либо новые функции. Такой стиль программирования приводит к очень "непослушному" и громоздкому коду.
API функций
Если вы собрались отделить код PHP от HTML кода, у вас есть два варианта. Один способ - - создать функции динамического формирования вывода и поместить их в нужное место на веб-странице.
Например, так:
index.php - код страницы

<?php include_once ("site.lib"); ?>








<?php print_header (); ?>


<?php print_links (); ?> <?php print_body (); ?>




site.lib - Сам код программы

<?php

$dbh = mysql_connect ("localhost", "sh", "pass")
or die (sprintf ("Не могу открыть соединение с MySQL [%s]: %s",
mysql_errno (), mysql_error ()));

@mysql_select_db ("MainSite")

or die (sprintf ("Не могу выбрать базу данных [%s]: %s",
mysql_errno (), mysql_error ()));

$sth = @mysql_query ("SELECT * FROM site", $dbh)
or die (sprintf ("Не могу выполнить запрос [%s]: %s",
mysql_errno (), mysql_error ()));


$site_info = mysql_fetch_object ($sth);

function print_header ()
{
global $site_info;
print $site_info->header;
}

function print_body ()
{
global $site_info;
print nl2br ($site_info->body);
}

function print_links ()
{
global $site_info;


$links = explode ("\n", $site_info->links);
$names = explode ("\n", $site_info->link_names);

for ($i = 0; $i < count ($links); $i++)
{
print "\t\t\t
\"$links[$i]\">$names[$i]

\n
\n";
}
}
?>



Очевидно, такой код лучше читаем. Еще одно преимущество использования этой концепции - возможность изменения дизайна без модификации самого кода программы.
Плюсы использования API функций
• Относительно чистый, ясный код
• Быстрый код
Минусы использования API функций
• Не настолько наглядно как система шаблонов
• Все-таки для модификации дизайна требуется некоторое знание PHP
Система шаблонов
Второй способ, используемый для разделения PHP и HTML кода, - использование шаблонов. В данном случае некоторые элементы дизайна заменяются пользовательскими тегами, а сама программа сканирует файл на предмет их наличия и заменяет их необходимой информацией.
Пример использования шаблонов:







<BODY< font> %%BODY_PROPERTIES%%>


%%PAGE_TITLE%%


%%PAGE_LINKS%% %%PAGE_CONTENT%%






Затем пишем программу, просматривающую код шаблона и при выводе заменяющую тэги вида %%SOME%% нужной информацией.
Примечание: неплохой класс для использования его в системе шаблонов - FastTemplate, его можно скачать с http://www.thewebmasters.net/.
Опубликовал Kest October 26 2008 12:46:29 · 1 Комментариев · 65535 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Страница 1 из 4 1 2 3 4 >
Комментарии
Михаил November 24 2010 13:20:09
По-моему статья не закончена.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Отлично! Отлично! 50% [1 Голос]
Очень хорошо Очень хорошо 0% [Нет голосов]
Хорошо Хорошо 50% [1 Голос]
Удовлетворительно Удовлетворительно 0% [Нет голосов]
Плохо Плохо 0% [Нет голосов]
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Стелтинг Стивен, ...
BIOS
Pro-Download Sys...
Программирование ...
AlnComponents
ScreenSaver [Исхо...
Java Server Pages...
Проигрыватель Mp3
Разработка интерн...
Архив значков
Proeffectimage
Размещение элемен...
Введение в станда...
Учебник для продв...
Rss Parser
Обучение Borland ...
Алгоритм DES шифр...
Расширенный загру...
PHP 5. Практика с...
Игра Car [Исходни...

Топ загрузок
Приложение Клие... 100793
Delphi 7 Enterp... 98032
Converter AMR<-... 20298
GPSS World Stud... 17060
Borland C++Buil... 14244
Borland Delphi ... 10376
Turbo Pascal fo... 7392
Калькулятор [Ис... 6082
Visual Studio 2... 5232
Microsoft SQL S... 3674
Случайные статьи
Язык программирова...
Интим магазин
1.3. Схема алгорит...
Печать документа
Ждать последующих ...
Коллекция диалогов
Объектно-ориентиро...
Хакинг
Спил деревьев
Что такое объектно...
ThisForm.PageFrame1.
Предложения, факты...
О возможностях игр...
Процедуры и функци...
Иногда требуется б...
Нагрузка на процес...
5.1. ЦЕЛЬ: УПРОЩЕН...
Измените DACL, что...
наследования ОГП
Поиск максимально...
Стандартные модули
Несколько прекрасн...
Предикат, вычисляю...
Подписки на новую ...
• Решите, какой IP...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?