Приветствую Вас ГостьВторник, 11.02.2025, 10:50

Light Midnight Inc.


Каталог статей

Главная » Статьи » Программирование » PHP/JavaScripts

21 ошибка программиста PHP, часть 2.1

11. Неоправданное использование ООП

Парадигма ООП - замечательный подход к написанию кода. У ООП есть множество неоспоримых преимуществ, самое значительное из которых - возможность использовать заново уже некогда написанный код. Однако все мы рано или поздно осознаём тот факт, что 'PHP - не объектно-ориентированный язык'. 
Несмотря на то, что PHP имеет корректно работающую поддержку объектов, использовать объекты там, где можно без них обойтись - недальновидно и неэффективно. Причина? Дело в том, что поддержка парадигмы ООП в PHP реализована не в полном объёме

Несмотря на присутствие основных элементов, PHP всё-таки не хватает многих "продвинутых" функций (как защищённые члены или закрытые переменные), которые обязательны для "настоящих" объектно-ориентированных языков (например, Java, C++). 

Кроме того, поддержка объектов в PHP недостаточно отработана и не очень эффективна. Это означает, что использование парадигмы ООП может существенно снизить скорость выполнения программы.

Примечание: Другими словами, скрипт, работающий на объектах будет исполняться медленнее, как код внутриeval() по сравнению с обычным кодом. Для более наглядных примеров, где использование ООП принимает какие-то уродливые формы, пришлось бы прибегнуть к продвинутым функциям концепциям PHP, некоторые из которых даже незадокументированы. Так что остановимся на этом.

А что же мы сможем без ООП?

Если вы пришли в PHP из Java или C++, где без объектов трудно создать что-либо более или менее серьёзное, то и в PHP вам будет трудно обходиться без них. Но будьте уверены, что серьёзные приложения могут быть написаны и методик и приёмов ООП (PHP был написан на C, а последний, как мы знаем, не поддерживает объектов). 

Итак, для тех, кто не привык обходиться без ООП, приведём альтернативные технологии написания связных и расширяемых приложений вне парадигмы ООП:

  • Создание API.
  • Разработка концепции именования (и работа в её рамках).
  • Группирование взаимосвязанных функций в один файл.

Создание API

Соотнесём код программы с тремя уровнями:

  • Первый - собственно рабочие функции.
  • Второй - API функции. Сюда входят функции для построения конкретного приложения.
  • Третий - само приложение:

// MortgageRate.php (Ипотечный Кредит) 

// Уровень первый - внутренние функции 
// Внутренние функции для расчёта оптимальной  процентной ставки исходя из времени и размера помесячных выплат 

function _mort_find_interest_rate ($total) { 
    if (
$total 30000
        return (
7.4); 
    elseif (
$total 30000
        return (
3.2); 
    elseif (
$total 50000
        return (
2.5); 
    else 
        return (
1.7); 


// Уровень второй - API функции 

// double calculate_mortgage_rate (int money, int time, int month) 
// Рассчитывает процентную ставку исходя из суммы займа, времени погашения и интервала выплат 

function calculate_mortgage_rate ($money$time$month) { 
    
$rate _mort_find_interest_rate ($money) / 100
    
$money /= ($time $month); 
    return (
$rate $money) + $money


?>

// CalcMortgage.php 

// Третий уровень - приложение 
// $money, $time и $period получаем  из формы 

include_once 'MortgageRate.php'

$price calculate_mortgage_rate ($money$time$period); 

print 
"Ваша процентная ставка за $period составляет $price"
?>

Разработка концепции именования и работа в её рамках.

Один из самых неприятных моментов при разработке больших приложений - это конфликты пространства имён. Классы его сегментируют. Таким образом, разные классы могут:

  • иметь свойства с одинаковыми именами или
  • содержать в себе методы с одинаковыми именами.

Например, класс Phillips и класс Normal могут одновременно содержать метод с именем screwdriver

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

Группирование взаимосвязанных функций в один файл

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

Например, можно было бы все функции, связанные с общением с БД, собрать в файл DB.php.

ООП, как и всё на свете, хорошо в меру

Небольшая оговорка: эта глава была написана не для того, чтобы отговорить вас от использования ООП вообще. Скорее, это была попытка убедить вас не работать с PHP в режиме Java или C++, где ООП - решение номер один. 

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

10. Неоправданное использование регулярных выражений

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

Например, для перевода целой строки в заглавные буквы, новичок в PHP мог бы написать следующее:

$URL "http://www.php.net"

$fp = @fopen ($URL"r"); 
if (!
$fp) { 
    die (
"Сбой при открытии $URL!"); 


while (
$line = @fgets ($fp1024)){ 
    
$data .= $line


@
fclose ($fp) or warn ("Сбой при закрытии дескриптора $URL"); 

$data ereg_replace ("[a-z]""[A-Z]"$data); 

print 
$data
?>

Однако, в этом случае, используя тяжеловесный и медленный ereg_replace(), он потратил бы кучу драгоценного времени выполнения на задачу, с которой более лёгкая функция strtoupper() справилась бы намного быстрее

$data = strtoupper ($data); 
 

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

Эти функции должен знать каждый

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

strtoupper(); strtolower(); ucfirst(); strtr(); str_replace(); trim(); explode(); implode(); substr(); strcmp() 

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

9. Программирование на php как на другом языке

Многие приходят в PHP уже с большим опытом программирования в другом языке, как PERL, C, Java или (ну это ещё куда ни шло) ASP. И частенько "импортируют" техники и подходы, которые не всегда хорошо сочетаются с методиками PHP. 

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

При таком подходе очень часто на выходе мы получаем медленный и трудно поддерживаемый код. И такие случаи не редкость:

  • "однострочники" PERL. PHP - язык мало приспособленный к так называемому методу - "всё в одной строке". Рекомендуем разбивать сложные хитросплетения комбинированных функций и представлять их в более структурированном виде. 
    Perl
    while () { 
     @_ = split /:/; 
     $quotes{shift} = shift; 
    } 
    print map { "$_: ", reverse split //,$quotes->{$_},"\n"; } keys %quotes; 
     

    PHP


    $fp 
    = @fopen('php://stdin''r'); 
    if (!
    $fp) { 
        die (
    'Сбой при открытии STDIN'); 


    while (
    $line = @fgets ($fp1024)){ 
        list(
    $name$quote) = explode (':'$line); 
        
    $quotes$name ] = $quote


    foreach (
    $quotes as $name => $quote){ 
        print 
    "$name: "
        print 
    implode (" "array_reverse (preg_split ('//'$quote))); 
        print 
    "\n"


    @
    fclose ($fp); 
    ?>

  • Уклонение от встроенных функций: Многие PHP-программисты, пришедшие из C, кажется, не понимают того, что PHP содержит целую армию встроенных функций. Их цель - избавить вас от километровых скриптов. Если вы раньше писали на C, вам настоятельно рекомендуется изучить техническое описание PHP и узнать, какие функции PHP вам может предложить и тем самым облегчить вам жизнь.
  • Переименование стандартных функций PHP: некоторые программисты переименовывают стандартные функции PHP только для того, чтобы легче их запоминать. Это не только снижает скорость выполнения скрипта, но и затрудняет чтение кода.
  • Неоправданное использование ООП: PHP - не объектно-ориентированный язык, хотя некоторая поддержка объектов всё-таки имеется. И всегда стоит помнить, что использование функций поддержки ООП значительно снижает скорость выполнения скрипта.

Где можно почитать об "изящном стиле" программирования на PHP

На ваше счастье Инет просто забит статьями о том, как правильно программировать на PHP.

8. Недостаточное внимание к вопросам безопасности

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

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

Пример: многие скрипты не используют встроенную PHP-функцию mail(), которая обеспечивает безопасную отправку почты. Вместо этого почта отправляется через программу sendmail с помощью popen(). Это делает код весьма неустойчивым к искажению данных и представляет собой "дыру" в безопасности системы (получателю можно отправить /etc/passwd). 

Перечислим наиболее распространённые "дыры", позволяющие искажать данные:

  • системные вызовы. Никогда нелишне повторить. Каждый раз нужно убедиться, сто пользователь отправляет вам "безопасные" данные для системного вызова. НИКОГДА НЕ ДОВЕРЯЙТЕ ДАННЫМ, ПОЛУЧЕННЫМ ОТ ПОЛЬЗОВАТЕЛЯ. И ПРЕЖДЕ ЧЕМ ПОДСТАВИТЬ ИХ В СИСТЕМНЫЙ ВЫЗОВ ПРОВЕРЬТЕ ИХ.
  • регистрация пользователей. Если вы желаете получить корректные результаты, обязательно проверяйте полученные данные, причём, лучше если проверка будет состоять из нескольких этапов. Прежде всего, это проверка адреса электронной почты: убедитесь, что пользователь предоставил вам работающий аккаунт. Кроме того, стоит убедиться, что указанный возраст находится в определённых пределах. Вы можете быть совершенно уверены, что на нашей планете нет двухсотлетних товарищей, которые ещё способны сесть за компьютер.
  • Приём номеров кредитных карточек. Некоторые программисты ограничиваются самыми простыми алгоритмами; их легко обмануть. Существуют крупные специализированные организации для проверки кредитных карточек; рекомендуем прибегать к их помощи или ресурсам и только потом решать, принята карточка или нет. НИКОГДА НЕ ПОЛАГАЙТЕСЬ ТОЛЬКО НА АЛГОРИТМЫ.

Безопасность системных вызовов.

Если возникает необходимость поместить полученные от пользователя данные в системный вызов, обязательнопроверьте и перепроверьте их. Убедитесь, что данные, которые пользователь предоставил системе, не содержат "опасных" элементов и не взломают систему нежелательными командами. Для этого PHP предлагает специальную функцию EscapeShellCmd()

Каждый раз при системном вызове с потенциально небезопасными данными, дезактивируйте их с помощьюEscapeShellCmd():

Примечание: дезактивация проходит путём подстановки бэкслэша ("\") перед потенциально небезопасными для системы символами (а именно: #&;?'\"|*?~<>^()[]{}$\\\x0A\xFF).

<html> 
<head> 
<title>Поиск аккаунта</title> 
</head> 
<body> 
<h1>Поиск аккаунта</h1> 
if ($name) { 
    
system (EscapeShellCmd ("lookup $name")); 
    print 
"
\n\n"


?> 
<form action="print $PHP_SELF?>" method="GET"> 
Введите аккаунт для поиска: 
<input type="text" name="name"> 
<input type="submit" value="Найти аккаунт"> 
</form> 
</body> 
</html>

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

Усиленная проверка данных

Как правило, лучше проверять строку на наличие допустимых символов, нежели на отсутствие недопустимых

Например, проверить, что переменная $name содержит только буквенные символы. При этом новые пути проникновения в систему имеют меньше шансов просочиться через ваш фильтр.

Проверка адресов электронной почты

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

  • проверка соединения
  • интерактивная проверка

Проверка соединения

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

Плюсы

  • Никаких действий со стороны пользователя, поскольку операция проводится на программном уровне.
  • Выявляет несуществующие адреса, с чем никогда не справится регулярное выражение (например,joe@fgsdh.com).

Минусы

  • Выявляются только несуществующие адреса. Например, если John Doe пошлёт e-mail автора этих строк (sterling@php.net), данные будут приняты, несмотря на то, что был предоставлен неверный адрес.
  • Данный метод работает медленнее, чем регулярные выражения.
  • Почтовый сервер пользователя может временно не работать, при этом рабочий адрес будет восприниматься как некорректный.

Интерактивная проверка

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

Плюсы

  • Лучший способ убедиться, что пользователь предоставил корректный и свой адрес (Пользователь должен иметь доступ к аккаунту, указанному при регистрации).

Минусы

  • Требуются некоторые действия со стороны пользователя. Это раздражает тех, кто пытается вас одурачить.
  • Как и любой другой, этот способ не даёт стопроцентной гарантии надёжности. Пользователь может создать временный аккаунт на Hotmail или Netaddress, а потом дать его при регистрации.

Категория: PHP/JavaScripts | Добавил: Cromartie (31.01.2013)
Просмотров: 575 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Наш опрос
Оцените мой сайт
Всего ответов: 543
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Реклама
Cheсking
Часы
Мини-чат
200
Друзья Сайта
  • Light Midnight - Ваша Еда
  • Light Midnight - Anim as life style
  • Поиск