Главная » Полезные статьи » Язык PHP » Новые возможности PHP 5
Распечатать статью

Новые возможности PHP 5

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

Однако, по словам создателей PHP 5, ничего революционного в этот раз ожидать не стоит — текущие изменения носят всего лишь ”эволюционный” характер. Тем не менее, сделанные дополнения являются давно ожидаемыми, крайне полезными и весьма своевременными.

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

Новый механизм работы с объектами

Основное отличие обработки объектов в PHP 5 от PHP 4 заключается в том, что теперь присвоение объекта или его передача в качестве параметра функции происходит по умолчанию по ссылке, а не по значению, как в предыдущей версии.

И если в PHP 4 объекты обрабатывались также как и простые типы данных, что часто приводило к появлению нескольких копий одного и того же объекта, то в PHP 5 такого не происходит, так как каждый объект получает свой собственный числовой идентификатор (handle), который и используется при обращении к объекту.

Таким образом, представленный ниже код, выполненный в PHP 4 и в PHP 5, очевидно может продемонстрировать различия в обработке объектов.

class MyClass {
var $property;
}
$obj1 = new MyClass;
$obj1->property = 1;
$obj2 = $obj1;
$obj2->property = 2;
echo $obj1->property; // Выводит 1 в PHP 4 и 2 в PHP 5
echo $obj2->property; // Выводит 2
?>

В PHP 4 $obj2 представляет собой копию объекта $obj1, а в PHP 5 и $obj1 и $obj2 указывают на один и тот же объект, так как оператор $obj2 = $obj1 копирует не сам объект, а только его идентификатор.

Различные механизмы обработки объектов имеют место по причине того, что Zend Engine 1, исполнявший сценарии в PHP 4, хранил значения всех типов одинаковым образом в специальной структуре, называемой zval (Zend VALue). В PHP 5 также используется zval, однако теперь в нем хранятся все типы данных, за исключением объектов, которые располагаются в новой структуре, получившей название Object Store. Zval же хранит только идентификаторы объектов, вот почему при присвоении или передачи в функцию передается не сам объект, а только его идентификатор.

Данное улучшение позволит значительно увеличить производительность PHP сценариев, где активно используется работа с объектами.

Клонирование объектов

Итак, в PHP 5 объекты передаются по ссылке. Однако, если же необходимо провести именно копирование объекта, как это делалось в PHP 4, то в PHP 5 придется явно использовать новый метод __clone(). При этом объект копируется со всеми своими методами, свойствами и их значениями:

class MyClass{
var $property;
}
$obj1 = new MyClass;
$obj1->property = 1;
$obj2 = clone $obj1;
echo $obj1->property; // Выводит 1
echo $obj2->property; // Выводит 1
$obj2->property = 2;
echo $obj2->property; // Выводит 2
?>

Следует обратить внимание на то, что к методу __clone() нельзя обратиться непосредственно и для копирования объекта используется ключевое слово clone.

Метод __clone() необязательно описывать в самом классе, однако его явное определение, т.е. перегрузка, позволит изменить значения свойств копируемого объекта:

class MyClass{
var $property;
function __clone() {
$this->property = 2;
}
}
$obj1 = new MyClass;
$obj1->property = 1;
$obj2 = clone $obj1;
echo $obj1->property; // Выводит 1
echo $obj2->property; // Выводит 2
?>

Метод __clone() не может принимать никакие аргументы, однако позволяет обратиться к исходному объекту через указатель $this и получаемому в результате копирования объекту через указатель $that.

Доступность элементов класса

В PHP 5 введены спецификаторы доступа public, protected и private, которые позволяют указать степень доступа к свойствам и методам класса.

К общедоступным (public) свойствам и методам можно получить доступ без каких либо ограничений.

Защищенные (protected) элементы класса доступны внутри класса, в котором они объявлены, и в производных от него классах.

Частные (private) элементы доступны только в классе, в котором они объявлены.

class MyClass {
public $public = «общедоступный элемент»;
protected $protected = «защищенный элемент»;
private $private = «частный элемент»;
public function printPrivate() {
echo $this->private;
}
}
$obj1 = new MyClass;
echo $obj1->public; // Выводит «общедоступный элемент»

class MyClass1 extends myClass {
public function printProtected() {
echo $this->protected;
}
}
$obj2 = new MyClass1();
$obj2->printProtected(); // Выводит «защищенный элемент»

$obj1->printPrivate(); //Выводит «частный элемент»

echo $obj1->protected; // Вызывает ошибку доступа
echo $obj1->private; // Вызывает ошибку доступа
?>

Если не указывать ни один из спецификаторов, то по умолчанию элемент будет иметь уровень доступа public. Такой же уровень доступа получают свойства, для объявления которых использовалось устаревшее и не рекомендуемое к использованию в PHP 5 ключевое слово var.

В PHP 5 введены конструкторы и деструкторы

Метод-конструктор вызывается автоматически при каждом создании объекта. И хотя конструктор появился в PHP давно (эту роль выполнял метод, названный именем класса), но в PHP 5 была изменена схема именования конструктора — метод __construct() является теперь конструктором класса.

Аналогично, при уничтожении объекта вызывается специальный метод __destruct() – деструктор класса.

class MyClass {
function __construct() {
echo «Запущен конструктор»;
}
function __destruct() {
echo «Запущен деструктор»;
}
}
$obj = new MyClass(); // Выводит «Запущен конструктор»
unset($obj); // Выводит «Запущен деструктор»
?>

Если же необходимо вызвать конструктор или деструктор базового класса, то необходимо это делать явно, через указатель parent.

class MyClass {
function __construct() {
echo «Запущен конструктор базового класса»;
}
function __destruct() {
echo «Запущен деструктор базового класса»;
}
}
class MyClass1 extends MyClass {
function __construct() {
parent::__construct();
}
function __destruct() {
parent::__destruct();
}
}
$obj = new MyClass1(); // Выводит «Запущен конструктор
// базового класса»
unset($obj); // Выводит «Запущен деструктор базового класса»
?>

Для целей совместимости с предыдущей версией PHP 5 поступает следующем образом: если при создании объекта в классе не найдет конструктор __construct(), то PHP пытается выполнить метод, имя которого совпадает с именем класса. Т.о. конструкторы PHP 4 будут работать с PHP 5 без каких-либо изменений кода.

В PHP 5 впервые введены абстрактные (abstract) классы и методы

Абстрактные методы имеют только объявление и не имеют реализации. Класс, который содержит такие методы, должен быть обязательно объявлен как абстрактный.

abstract class MyClass {
abstract public function abstrFunc();
}
class MyClass1 extends MyClass {
public function abstrFunc() {
echo 1;
}
}
$obj = new MyClass1;
$obj->abstrFunc(); // Выводит 1
?>

При этом невозможно создать объект абстрактного класса, можно только определять новые классы от базового абстрактного класса и создавать объекты уже от производных классов.

Стоит отметить, что абстрактные классы также могут содержать и обычные (не абстрактные) элементы.

Итнерфейсы

Интерфейсами (interface) являются абстрактные классы, содержащие только абстрактные методы и не имеющие никаких свойств.

Основное отличие интерфейсов от абстрактных классов заключается в том, что в PHP 5 класс не может быть порожден от нескольких классов, в том числе и абстрактных, но зато может быть создан на основе любого числа интерфейсов.

При этом в интерфейсе методы объявляются ключевым словом function без указания каких-либо спецификаторов, в том числе и abstract.

interface Int1 {
function func1();
}
interface Int2 {
function func2();
}
class MyClass implements Int1, Int2 {
public function func1() {
echo 1;
}
public function func2() {
echo 2;
}
}
$obj = new MyClass;
$obj->func1(); // Выводит 1
$obj->func2(); // Выводит 2
?>

Таким образом, хотя множественное наследование (multiple inheritance) и не поддерживается в PHP 5, однако разработчики получили реальную возможность создавать классы на основе отдельно описанных интерфейсов.

Финальные методы и классы

В PHP 5 введена новая возможность определять методы класса и сами классы как финальные (final).

Метод, при определении которого используется ключевое слово final, не может быть переопределен в классах, производных от данного класса.

class MyClass {
final public function func() {
// Код метода
}
}
class MyClass1 extends MyClass {
// Следующий код вызывает ошибку
// переопределения финального метода
// базового класса MyClass
public function func() {
// Код метода
}
}
?>

Кроме этого, если final используется при определении самого класса, то порождение от него других классов становится невозможным.

final class MyClass {
// Код описания класса
}
// Следующий код вызывает ошибку
// порождения от финального класса
class MyClass1 extends MyClass {
// Код описания класса
}
?>

Если класс определен как final, то и все методы данного класса автоматически становятся финальными, таким образом, определять их явно как final уже нет необходимости.

Определять же свойства класса как финальные – недопустимо.
Константы класса

В PHP 5 введен новый элемент класса – константа.

class MyClass {
const CONSTANT = «константа класса»;
}
echo MyClass::CONSTANT; // Выводит «константа класса»
?>

Ранее написанные сценарии для PHP 4, не использующие функции или классы с именем const будут работать без модификации кода.

Статические свойства и методы класса

В PHP 5 возможно объявление статических свойств класса.

class MyClass {
static $static = 1;
}
echo MyClass::$static; // Выводит 1
?>

Статические свойства едины для всего класса и не могут принадлежать ни одному из объектов класса. Изменение такого свойства в одном из методов любого объекта приводит к его изменению для всех остальных объектов данного класса. Кроме этого, становится возможным обратиться к такому свойству вне контекста объекта.

Статические методы классов в PHP 5, также как и статические свойства, принадлежат всему классу в целом. Это позволяет использовать такой метод без создания какого-либо объекта такого класса.

class MyClass {
static function statFunc() {
echo «статический метод»;
}
}
MyClass::statFunc(); // Выводит «статический метод»
?>

Однако в статическом методе становится невозможным использовать указатель $this, так как при вызове статического метода или неизвестно в контексте какого объекта он вызывается, или такого объекта может и не существовать вовсе.

Instanseof

Специальное ключевое слово instanceof в PHP 5 позволяет определять является ли объект экземпляром определенного класса, или же экземпляром класса производного от какого-либо класса.

class MyClass { }
$obj1 = new MyClass();
if ($obj1 instanceof MyClass) {
echo «\$obj1 — объект класса MyClass»;
}

class MyClass1 extends MyClass { }
$obj2 = new MyClass1();
if ($obj2 instanceof MyClass) {
echo «\$obj2 — объект класса, производного от MyClass»;
}

interface Int { }
class MyClass2 implements Int { }
$obj3 = new MyClass2();
if ($obj3 instanceof Int) {
echo «\$obj3 — объект класса, созданного на основе интерфейса Int»;
}
?>

Также с помощью instanceof можно определить является ли объект экземпляром класса, созданного на основе определенного интерфейса.

__autoload()

Специальная функция __autoload() будет вызываться в PHP 5 в случае попытки создания объекта неопределенного класса.

function __autoload($class) {
echo «попытка создать объект неопределенного класса «, $class;
}
$obj = new MyClass;
?>

В качестве параметра функции __autoload() передается имя неопределенного класса.
Методы доступа к свойствам объекта

В PHP 5 возможна перегрузка доступа к свойствам объектов.

class MyClass {
private $properties;
function __set($name, $value) {
echo «задание нового свойства $name = $value»;
$this->properties[$name]=$value;
}
function __get($name) {
echo «чтение значения свойства «, $name;
return $this->properties[$name];
}
}
$obj = new MyClass;
$obj->property = 1; // Выводит «задание нового свойства property=1″
$a = $obj->property; // Выводит «чтение значения свойства property»
echo $a; // выводит 1;
?>

Новые методы доступа __get() и __set() позволяют легко проводить динамическое назначение свойств объектам. В качестве параметров этим методам передаются имена свойств.

Перегрузка вызовов методов объекта

Метод __set() также получает и значение, которое устанавливается для свойства.

При вызове в PHP 5 несуществующего метода объекта автоматически вызывается специальный метод __call().

class MyClass {
function __call($name, $params) {
echo «Вызван метод $name с параметром $params[0]«;
}
}
$obj = new MyClass;
echo $obj->method(1); // Выводит «Вызван метод method
// с параметром 1″
?>

В качестве параметров __call() принимает имя вызываемого метода и передаваемые этому методу параметры.

Итераторы

В PHP 5 возможен полный перебор всех свойств объекта в операторе foreach.

class MyClass {
public $a = 1;
public $b = 2;
}
$obj = new MyClass;
foreach ($obj as $name => $value) {
echo «$name => $value «; // Выводит «a => 1 b => 2″
}
?>

Специальные интерфейсы PHP 5 IteratorAggregate и Iterator позволяют указывать поведение класса при его использовании с оператором foreach.

Источник:   codingrus.ru

Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

Оставить комментарий

Похожие статьи