Когда переходить на ООП? I. Зачем использовать классы вместо функций.
Увидев первый раз такой код (например здесь), обычный человек, не сталкивавшийся до этого с ОО-программированием сразу скажет: «Спасибо, нам этого добра не надо. Обойдусь как-нибудь функциями».
Можно долго повторять, что всё новое человек воспринимает с подозрением, что нужно заставить его поверить... Но, вопрос в том, когда стоит использовать классы вместо функций. Ради чего стоит переходить от процедурного подхода к объектно-ориентированному?
1. Сохранение состояния (напр. cookie, referer при HTTP-запросах)
Итак, нужно совершить 2 последовательных HTTP-запроса, сохранив при этом номер последней ошибки (или 0), реферер и кукисы:
$p_content = submit_request("http://www.google.com/advanced_search?hl=ru", "", $last_error, $req_referer, $cookie_ar);
$p_content = submit_request("http://www.google.com/search?hl=ru&as_q=Mr.KTO&num=100", "", $last_error, $req_referer, $cookie_ar);
Здесь производится запрос к гуглу через форму advanced_search (т.к. до недавнего времени нельзя было сразу, без cookie вернуть 100 результатов на страницу). Куки сохраняются в глобальной переменной, массиве $cookie_ar, а функция submit_request принимает этот массив по ссылке:
function submit_request($req_url, $req_POST, &$last_error, &$req_referer, &$cookie_ar) { /*...*/ }
Если для вашей конкретной задачи такой код подходит... – оставьте его! Я серьёзно.
Как только вам понадобится совершить в промежутке между первым и вторым запросом к гуглу, третий запрос (вдруг приспичило проверить PR :)) – то возникнет проблема с корректностью $req_referer (и $cookie_ar, если куки не распределены, как массивы по доменам). Чтобы решить проблему, нам придётся ввести 3 новые глобальные переменные $req_referer_PR, $cookie_ar_PR, $last_error_PR.
Как это будет выглядеть в виде класса:
<?php class qrl { //public: var $last_error = 0; var $req_referer = ""; var $cookie_ar = array(); function submit_request($req_url, $req_POST = "") { /*...*/ } } // создаём объекты класса qrl $req = new qrl; // для гугл-поиска $PR = new qrl; // для проверки PR $req->submit_request("http://www.google.com/advanced_search?hl=ru"); //1 echo "PageRank:" . $PR->submit_request("http://toolbarqueries.google.com/search?ch=$hash&q=info:".urlencode($url)); echo "GoogeSearch:" . $req->submit_request("http://www.google.com/search?hl=ru&as_q=Mr.KTO&num=100"); ?>
Теперь нам не нужно каждый раз придумывать (и писать) 3 переменных, они все храняться в свойствах класса. К тому же, современные PHP-редакторы поддерживают autocomplete (т.н. Code Insight), достаточно после -> нажать Ctrl+space, чтобы появился список всех публичных свойств и методов класса.
2. Замена С++ namespace
Вы заметили – я ещё не упомянул «о вреде глобальных переменных». Сколько написано статей... я не знаю. Не хочу говорить, что «вы случайно создадите новую переменную с тем же именем» (в конце концов, можно использовать префиксы). Лучше покажу на конкретном примере.
Предположим, мы делаем класс для парсинга URL. (Потому что стандартный нам не нравится, хотим функцию фиксинга УРЛов, просто не ищем простых путей.) Логично было бы назвать функцию parse_url(). Но такая функция уже есть в PHP. Что делать? Изменить регистр – но в PHP функции регистронезависимые. Убрать подчёркивание – может возникнуть путаница.
В C++ есть такая полезная вещь, как пространства имён (в PHP >v.5.3.0 ещё только экспериментируют с этим):
namespace URLTools {
typedef struct { // это описание типа TUrl, вместо ассоциативных массивов PHP
String scheme;
String host;
String query;
//....
} TUrl;
TUrl parse_url(String this_adr) // функция парсинга УРЛ
{
/*...*/
}
}
// далее парсим URL, можно было обойтись без «URLTools::»,
// если написать «using namespace URLTools;»
URLTools::TUrl myURL = URLTools::parse_url("http://mrkto.com/");
На PHP это можно реализовать с помощью класса. Как правило, это полностью статический класс:
class URL {
private static $_cache = array(); // напр. кэшированные результаты парзинга
public static fucntion parse_url($this_adr)
{
/*...*/
}
}
print_r( URL::parse_url("http://mrkto.habrahabr.ru/") );
3. Почему "Hello world" и его потомки такие сложные
Действительно, почему некоторые, казалось бы простые скрипты растягиваются на сотни строк кода?
В данном случае виноваты стандарты кодирования PEAR, которые требуют в каждом скрипте писать шапку с именем автора, версией, описанием; указывать перед каждой переменной описание, тип, private/public; а перед каждой функцией – не только описание, но и описание всех аргументов, возвращаемое значение, и т.д. Конечно, некоторые редакторы учитывают всё это в Code Hint-е. Но код уже не выглядит так явно. Это пример, как следование общепринятым стндартам мешает продуктивной работе.
Впрочем, стандарты кодирования – это тема для другой статьи.
_____________________________________
Интересует использование классов как массивов – вот пример для PHP 5 – это виртуальные массивы, фактически перегрузка квадратных скобок.
Что-то подобное на php4 можно наблюдать и в моём Шаблонизаторе за 5 секунд.
Подпишитесь на блог. Задавайте ЛЮБЫЕ вопросы в комментах - ответы в виде постов появятся МГНОВЕННО!


сентября 17, 2008 в 22:51
У меня никак не получается перейти на ООП в пхп.
Сам принцип ООП нужно понять, а мне все равно проще функциями =(
Видимо надо сесть и попраграммировать на с++ или яве.