PHP это гораздо больше, чем язык сценариев. Это полноценный язык, способный создавать очень сложные приложения. Используя всю мощь объектно-ориентированного программирования, вы можете сократить время, затрачиваемое на кодирование, и использовать его для создания лучших веб-сайтов. Этот урок покажет вам, как.
Что такое ООП?
ООП обозначает O bject Oriented P rogramming. ООП — это парадигма программирования, в которой вы создаете «объекты» для работы. Затем эти объекты могут быть адаптированы к вашим конкретным потребностям для обслуживания различных типов приложений при сохранении одной и той же базы кода. Действительно полезно.
Что такое объект?
Объект — это просто копия или экземпляр «класса». Класс можно определить как «черный ящик», из которого мы создаем наши объекты и получаем доступ к его атрибутам (переменным) и методам (функциям). Наиболее распространенная аналогия, приведенная при объяснении классов и ООП, заключается в том, как вы управляете автомобилем: в основном у вас есть 2 или 3 педали, рычаг переключения передач и рулевое колесо. Вам не нужно (и, скорее всего, не хотите) знать, как работает машина, когда вы нажимаете педали. Вы просто хотите, чтобы ваша машина двигалась вперед и назад, влево и вправо. И ООП именно это. Вам не нужно знать, как работают методы класса (если вы сами его не реализовали), а только то, что они делают. ООП также полезно, если в системе имеется большое количество объектов одного типа: вам просто нужно создать объекты, а затем манипулировать ими всеми одинаково, без переписывания кода. Более того, объект может поддерживать свое состояние (значения переменных и т. Д.) На протяжении всего выполнения программы.
Реализация «Авто» скрыта от нас, однако мы можем использовать ее в полном объеме.
ООП в PHP
PHP 5 (хотя большинство идей в этой статье также применимы к PHP 4) имеет отличную поддержку объектно-ориентированного программирования, обеспечивая простое создание классов. PHP предоставляет каждую парадигму, которую реализуют другие «настоящие» языки ООП (например, Python и JAVA), такие как наследование, полиморфизм и инкапсуляция.
наследование
Основная идея наследования заключается в том, что похожие объекты имеют общие свойства. Таким образом, создав «универсальный» класс, мы можем иметь план для построения наших последующих классов. Представьте, если хотите, свойства автомобиля: цвет, количество колес, мощность, количество мест и т. Д. Имея этот шаблон, мы можем дополнительно специализировать наши автомобили, расширяя этот класс: создавая гоночный автомобиль, обладающий свойством «нитро», или грузовик, у которого есть свойство «трейлер». Суть заключается в следующем: создайте более общий класс, который содержит большинство общих атрибутов, и у вас будет гораздо меньше работы по определению других объектов, лишь немного отличающихся. Вместо того, чтобы переписывать весь код, вы просто расширяете его свойства, экономя много времени в процессе.
Диаграмма наследования для наших классов автомобилей.
Инкапсуляция
Как было объяснено ранее, одним из основных преимуществ использования объектов является то, что нам не нужно раскрывать все его элементы (атрибуты или функции); просто необходимые интерфейсы для работы с ним. Детали, не полезные для использования этих объектов, должны быть скрыты от остальных объектов. Это то, что называется инкапсуляцией.
Уровни видимости
- public: означает, что член класса виден и может использоваться / изменяться всеми
- private: означает, что член класса может использоваться / изменяться только самим классом
- protected: означает, что член класса может использоваться / модифицироваться только самим классом и возможными подклассами
ПРИМЕЧАНИЕ. По умолчанию в PHP член класса является общедоступным, если он не объявлен как закрытый или защищенный. Проверьте пример здесь .
Полиморфизм
Полиморфизм является характеристикой ООП, которая позволяет программисту назначать различное значение или использование чему-либо в разных контекстах — в частности, чтобы позволить члену класса выполнять различные задачи в зависимости от контекста, который он использовал. Представьте, что у вас есть класс Person и два подкласса Person: японский и американский. Оба реализуют функцию с именем talk (), но с разными языками и социальным контекстом. И хотя оба они в основном люди (как они происходят от класса Person), их реализация функции talk () сильно отличается. Таким образом, у вас есть два объекта класса Person, в которых функция talk () работает по-разному.
Пачкать руки
Хорошо, теперь для реальных действий. Мы будем создавать простой класс для обработки изображений и извлечения информации. В течение этого урока я предполагаю, что у вас есть базовое понимание PHP (переменных, создания функций, работы с операторами потока управления и циклами). Чтение руководства по GD PHP избавит вас от любых сомнений относительно функций обработки изображений.
Шаг 1: Создание нашего класса
Начнем с определения нашего класса:
|
1
2
3
4
|
<?php
class Image {
}
?>
|
Это просто говорит PHP, что мы начнем определять новый класс с именем «Image». Теперь мы определим конструктор класса. Конструктор — это просто функция, которая вызывается при создании нового объекта. В PHP 5 это может быть достигнуто двумя различными способами: путем создания общедоступной функции с точно таким же именем класса (PHP 4 и выше) или путем создания функции с именем «__construct ()» (только PHP 5):
Шаг 2: Создание конструктора класса
Следующие два фрагмента кода делают одно и то же:
|
1
2
3
4
5
6
7
8
|
<?php
class Image {
public function Image() {
echo «We just created and object!»;
}
}
$image = new Image();
?>
|
|
1
2
3
4
5
6
7
8
|
<?php
class Image {
function __construct() {
echo «We just created and object!»;
}
}
$image = new Image();
?>
|
ПРИМЕЧАНИЕ. Конструктор класса всегда открыт.
Конструкторы классов должны использоваться, чтобы гарантировать, что созданный объект имеет минимальный объем данных для работы; в нашем случае желаемое изображение.
Таким образом, первое, что мы должны сделать, это прочитать изображение, каким бы оно ни было. В настоящее время библиотека GD поддерживает несколько типов изображений, таких как jpg, png, gif, bmp и другие; мы просто должны прочитать изображение и определить его тип.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
<?php
class Image {
function __construct($filename) {
// read the image file to a binary buffer
$fp = fopen($filename, ‘rb’) or die(«Image ‘$filename’ not found!»);
$buf = »;
while(!feof($fp))
$buf .= fgets($fp, 4096);
// create image
imagecreatefromstring($buf);
}
}
$image = new Image(«image.png»);
?>
|
Итак, что мы сделали? Чтобы открыть изображение настолько легко, насколько это возможно, мы будем использовать функцию GD imagecreatefromstring (которая принимает двоичную строку данных в качестве входных данных) вместо, например, imagecreatefromjpeg , imagecreatefrompng или imagecreatefromgif .
Поэтому мы пытаемся открыть файл изображения и присвоить его указатель файла $fp , и, в случае сбоя, прекратить выполнение программы.
|
1
|
$fp = fopen($filename, ‘rb’) or die(«Image ‘$filename’ not found!»);
|
Далее мы создаем пустую строку для хранения наших данных …
|
1
|
$buf = »;
|
… и читать весь файл, объединяя прочитанные данные с вновь созданным содержимым строки.
|
1
2
|
while(!feof($fp))
$buf .= fgets($fp, 4096);
|
Теперь нам просто нужно создать наше изображение, используя данные, которые мы только что прочитали …
|
1
|
imagecreatefromstring($buf);
|
… и создать объект для использования всех этих функций.
|
1
|
$image = new Image(«image.png»);
|
ПРИМЕЧАНИЕ: jpg, png, gif и большинство файлов изображений должны быть прочитаны в двоичном режиме, поэтому «rb» передается как второй аргумент функции fopen. «r» означает «только для чтения», а «b» означает двоичный файл.
Шаг 3: Определение атрибутов и методов класса
В нынешнем виде наш класс не очень полезен. Поэтому мы будем добавлять некоторые атрибуты и методы, чтобы сделать его более полезным. Итак, мы начнем с 1: определения некоторых внутренних переменных (обратите внимание на объявление «private» видимости перед каждой переменной)
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?php
class Image {
// class atributes (variables)
private $image;
private $width;
private $height;
private $mimetype;
function __construct($filename) {
// read the image file to a binary buffer
$fp = fopen($filename, ‘rb’) or die(«Image ‘$filename’ not found!»);
$buf = »;
while(!feof($fp))
$buf .= fgets($fp, 4096);
// create image and assign it to our variable
$this->image = imagecreatefromstring($buf);
// extract image information
$info = getimagesize($filename);
$this->width = $info[0];
$this->height = $info[1];
$this->mimetype = $info[‘mime’];
}
}
$image = new Image(«image.png»);
?>
|
И 2: метод для отображения изображения.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
<?php
class Image {
.
.
.
public function display() {
header(«Content-type: {$this->mimetype}»);
switch($this->mimetype) {
case ‘image/jpeg’: imagejpeg($this->image);
case ‘image/png’: imagepng($this->image);
case ‘image/gif’: imagegif($this->image);
}
//exit;
}
}
$image = new Image($_GET[‘image’]);
?>
|
На этом шаге мы просто создали некоторые атрибуты класса (изображение, ширина, высота и mimetype) для хранения данных объекта. Затем мы внесли некоторые изменения, чтобы назначить созданное изображение нашему атрибуту класса $image …
|
1
|
$this->image = imagecreatefromstring($buf)
|
… и извлек информацию об изображении в наши оставшиеся переменные класса (прочитайте документацию по getimagesize, чтобы полностью понять, как читается информация об изображении):
|
1
2
3
4
5
|
// extract image information
$info = getimagesize($filename);
$this->width = $info[0];
$this->height = $info[1];
$this->mimetype = $info[‘mime’];
|
Затем мы создали функцию, которая выводит изображение в браузер, определяя соответствующие заголовки (подробнее о заголовках http здесь ) и используя соответствующую функцию (с оператором switch) для вывода изображения на основе исходного mimetype изображения (для этого урока) мы будем просто поддерживать jpg, png и gif, но, как я уже говорил, GD поддерживает множество других форматов (подробнее см. документацию php).
Так что это за «$ this» там? «$ this» в PHP относится к самому классу и используется для указания на атрибуты или функции класса. Таким образом, $ this-> image указывает на атрибут класса с именем $ image, а $ this-> image = … изменяет значение атрибута класса. Если бы вы написали $ image = …, вы бы просто создали новую локальную переменную с именем «$ image», доступную исключительно на время действия функции. Это одна из главных вещей, на которую следует обратить внимание при создании классов в PHP.
Наш не очень полезный (пока!) Метод отображения.
Шаг 4. Определение подкласса «Миниатюра»
Прямо сейчас наш класс не очень полезен. Конечно, мы можем прочитать наше изображение и показать его, но это все. Теперь мы создадим подкласс для создания наших миниатюр. (Нам действительно не нужно создавать подкласс, но мы сделаем это ради учебника, чтобы продемонстрировать наследование и полиморфизм). Итак, для правильной работы наследования нам нужно немного изменить определение нашего суперкласса (Изображение). Нам просто нужно изменить видимость переменных нашего класса с «приватных» на «защищенные». А теперь мы создадим конструктор нашего подкласса.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<?php
class Image {
// class atributes (variables)
protected $image;
protected $width;
protected $height;
protected $mimetype;
.
.
.
}
class Thumbnail extends Image {
function __construct($image, $width, $height) {
// call the super-class contructor
parent::__construct($image);
// modify the image to create a thumbnail
$thumb = imagecreatetruecolor($width, $height);
imagecopyresampled($thumb, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
$this->image = $thumb;
}
}
?>
|
Так что именно мы здесь делаем? Мы создали новый класс, производный от нашего оригинала, что означает, что мы можем получить доступ ко всем его открытым и защищенным атрибутам и методам. Мы вызываем конструктор суперкласса, отвечающий за чтение изображения и извлечение его информации. Конструктор подкласса не вызывает его конструктор суперкласса, поэтому мы должны вызывать его явно.
Теперь мы создаем новое изображение для нашего эскиза с шириной и высотой:
|
1
|
$thumb = imagecreatetruecolor($width, $height);
|
Измените размер (измените размер) исходного изображения на новое, чтобы создать миниатюру:
|
1
|
imagecopyresampled($thumb, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
|
И, наконец, измените исходное изображение, чтобы оно содержало миниатюру вместо полноразмерного изображения:
|
1
|
$this->image = $thumb;
|
И угадайте, что? Нам не нужно писать новую функцию для отображения миниатюры, потому что применяется тот же принцип, независимо от того, отображаете ли вы полноразмерное изображение или миниатюру. В конце концов, это все еще изображение! Так что нам просто нужно вызвать нашу функцию display (), определенную в суперклассе, и все готово!
Наш законченный класс и соответствующий подкласс.
На этом мы завершаем наш урок. В качестве упражнения я предлагаю вам реализовать функцию для сохранения сгенерированных миниатюр на диск, а не выводить их на лету (где вы должны реализовать эту функцию? В супер- или подклассе?). Удачи и проверьте почтовый индекс, предоставленный для примера использования и полных классов, разработанных здесь (вам нужно иметь сервер на PHP, чтобы протестировать его).
- Подпишитесь на RSS-канал NETTUTS, чтобы узнать о ежедневных новостях и статьях о веб-разработке.

