Все статьи >> Объектно-ориентированное программирование в PHP (просмотров: 1513)

Объектно-ориентированное программирование в PHP

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

Что такое ООП?

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

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

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

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

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

Причем же здесь PHP?

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

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

class ClassName {

/* Ниже - определение свойств. Оператором var инициализируется параметр, его наличие обязательно */

var $a1="value1"; /* Свойство можно инициализировать некоторым значением по умолчанию */

var $a2; /* Но делать это необязательно */

/* Ниже - определение методов. Они вводятся ключевым словом function */

function func1($a3, $a4) {

/* здесь следует описание метода. Как видно, функция принимает два параметра, являющимися свойствами описываемого класса; вообще, для указания на создаваемый класс используется переменная $this (ведь у класса может быть множество экземпляров с самыми разными именами). */

} }

 

Создание нового экземпляра класса реализуется при помощи оператора new:

$NewObject=new ClassName;

Теперь ссылаться на свойства и методы этого объекта можно уже известным способом: $NewObject->var1.

Наследование позволяет создавать новые классы путем добавления атрибутов к уже существующему классу. Это реализуется при помощи оператора extends:

/* Ниже мы создадим новый класс ClassName, который унаследует все атрибуты ClassName, но будет иметь и собственные */

class ClassName2 extends ClassName {

                  /* определяем новые свойства */

                 var $a3="value3";

                /* Определение дополнительных методов */

              function func2($a65) {

              /* описание функции */

              }

}

Кодим

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

class HttpConnection {

var $ProxyHost;

var $ProxyPort;

function HttpOpenConnection ($Host, $Path, $Port) {

/* Проверяем, хочет ли юзер использовать прокси-сервер для соединения */

if (!isset($ProxyHost) || !isset($ProxyHost)) {

/* Подключаемся без использования прокси-сервера, поскольку

пользователь не определил соответствующие свойства класса */

$ConnectionHost=$Host;

$ConnectionPort=$Port;

echo $Port;

} else {

$ConnectionHost=$this->$ProxyHost;

$ConnectionPort=$this->$ProxyPort;

}

/* Следует заметить, что и запрос прокси-серверу, и запрос веб-браузеру имеют один и тот же вид (см. соответствующие RFC-документы). Поэтому вся разница между прямым подключением и коннектом через проксик заключается в удаленном сокете, с которым осуществляется связь. */

$Query="GET "."$Host:$Port".$Path." HTTP/1.1\r\n".

"Accept: */*\r\n"."User-Agent: Xa-style phpClass v1.0\r\n".

"Host:$Host\r\n\r\n";

/* Открываем сокет с удаленной точкой связи */

$SocketPointer=fsockopen($ConnectionHost, $ConnectionPort);

if ($SocketPointer) { /* Если соединение установлено */

fputs($SocketPointer, $Query); /* Пишем в сокет запрос */

return $SocketPointer; /* Возвращаем указатель на соединение */

} else return false; /* Если соединение не удалось установить, возвращаем false */

}

/* Пример использования класса */

Require Class.php; /* подключаем класс */

$conn=new HttpConnection; /* создаем новый экземпляр класса */

$conn->ProxyHost="192.168.0.1"; /* Определяем свойства объекта */

$conn->ProxyPort=3128;

$fp=$atom->ShowFile("www.host.ru", "/index.html", 80); /* Вызываем метод ShowFile */


Автор: Никита Кислицин
 
 
Email:
не зарегистрированы?
Пароль:
забыли?
 
Астраханские магазины