PHP5 ще офіційно не вийшов, але "робітники" версії вже працездатності (так само як і нестабільні!), Так що ми цілком можемо почати вивчення нових можливостей прийдешнього релізу PHP і попрактикуватися з ними. У цій статті ми поговоримо про три основних нововведення в PHP5: top: 5px; margin-left: 60px "> Нова об'єктна модель Виключення Простори імен Але спочатку пара офіційних заяв: - Деякі з наведених у даній статті рішень відтворюваних в PHP4, але, тим не менш,їх опис присутній і тут для більшої удобочітаемості та цілісності всієї статті.
- Деякі з описаних у даній статті особливостей у кінцевому релізі PHP5 можуть бути змінені.
PHP5 ще не випущений і мені невідомо, коли це станеться, але вже зараз ви можете потестіровать і вивчити нові можливості мови, завантаживши робочу версію PHP5 з http://snaps.php.net і встановивши її. За цим посиланням ви можете знайти готові для установки Windows і Linux версії PHP5. Інсталяція проходить як у будь-якого нормального релізу PHP, такщо всі бігцем за новою іграшкою. Нова об'єктна модель В PHP5 об'єктну модель грунтовно подлаталі і додали багато нових можливостей, завдяки чому PHP5 став "чем-то" нагадувати Java. У цій частині нашої статті буде описана ця новая об'єктна модель і наведено кілька невеликих прикладів, щоб вам позначити вихідний рубіж для ваших експериментів. - Конструктори і деструктор
- Об'єкти як посилання
- Клонування об'єктів
- Дескриптори Private, Publicі Protected
- Інтерфейси
- Абстрактні класи
- __call
- __set and __get
- Закриті члени
Конструктори і деструктор В PHP4 конструктор іменується так само як і сам клас, а деструктор відсутні повністю. В PHP5 конструктор класу іменується __construct, а деструктор - __destruct.
Приклад 1: Конструктори і деструктор <? php clas s foo ( var $ x;
function __constructlor: # 007700 "> ($ x) ( $ this -> x = $ x; )
function display () ( print ($ this an> -> x); )
function __destruct () ( print (</ span> "ну, поки, до швидкого"); ) )
$ o1 = new foo pan> (4); $ o1 -> display (); yle = "color: # 0000bb">?> Як ви бачите, деструктор викликається перед самим знищенням класу. Об'єкти як посилання Як вам вже напевно відомо, в PHP4 змінні передаються у функції / методи за значенням (передається копія), Якщо в оголошенні функції не поставлений символ '&', який вказує на те, що змінна повинна передаватися як посилання. В PHP5 об'єкти передаються завжди як посилання. Привласнення об'єктів теж відбувається по посиланню.
Приклад 2: Об'єкти як посилання ass = "highlight"> <? php class foo ( var $ xle = "color: # 007700">;
function setX ($ x) ( $ this x = $ x; )
function getX < span style = "color: # 007700"> () ( return $ this -> x; ) )
or: # 0000bb "> $ o1 = new foo; $ o1 -> setX or: # 007700 "> (4); $ o2 = $ o1; b "> $ o1 -> setX (5); if ($ o1 -> () == $ o2 -> getX ()) print ( "Ох & nbsp, ти, Боже мій! "); ?> Клонування об'єктів Якщо об'єкти привласнюються й передаються по посиланню, то вам потрібно якось створювати й копії про б'ектов. Для цього використовуйте метод __clone.
Приклад 3: Клонування об'єктів <? php class "> foo ( var $ x;
function setX ( b "> $ x) ( $ this -> x = $ xtyle = "color: # 007700">; )
function getX () ( return $ this -> < span style = "color: # 0000bb"> x; ) )
$ o1 = new foo; style = "color: # 0000bb"> $ o1 -> setX (4); $ o207700 "> = $ o1 -> __clone (); $ o1 -> setX (5);
if ($ o1 -> getX ()! = & nbsp; $ o2 -> getX ()) print ( "Копії взаімонезавісіми"); >?> У програмуванні клонування дозволено, так що все легально ;-) Дескриптори Private, Public і Protected В PHP4 всі методи й змінні усередині об'єкта були доступні ззовні, іншими слівами всі методи й змінні завжди були відкритими. В PHP5 вводиться три дескриптора для здійснення контролю над доступом до змінним і методам: Public, Protected і Private. - Public (відкритий): Метод / змінна доступні з будь-якого місця в коді. < br />
- Private (закритий): Закриті методи або змінні доступні тільки усередині класу.
- Protected (захищений): Захищені методи або змінні доступні тільки усередині класу, де вони були оголошені й з його похідних класів.
d "> Приклад 4: Public, protected and private <? php class foo ( private; $ X;
public function public_foo () ( print ( "Це відкритий метод "); )
protected function protected_foo () ( bb "> $ this -> private_foo (); / / Все правильно, ми можемо викликати закриті методи, тому що ми находимся в тому ж класі print ( "Це захищений метод"); )
private functionprivate_foo () ( $ this -> x = pan style = "color: # 0000bb"> 3; print ( "Це закритий метод"); ) )
classbb "> foo2 extends foo ( public function display () ( & nbsp; $ this -> protected_foo (); $ this -> < span style = "color: # 0000bb"> public_foo (); / / $ This-> private_foo (); / / Неправильно! У базовому класі метод закритий = "color: # 007700">) )
$ x = new foo (); $ x ->public_foo (); / / $ x-> protected_foo (); / / Неправильно, захищені методи можуть викликатися тільки з того ж класу або его похідних класів / / $ x-> private_foo (); / / Неправильно, закриті методи можуть бути викликані тільки в класі, де вони були оголошені
$ x2 </ span> = new foo2 (); $ x2 -> display (); ?> Рада розробникам: Змінні класу завжди варто робити закритими, прямий доступ до змінним - не дуже гарна практика в ООП, найкраще для доступу / зміни змінних класу визначати спеціальні методи. Як ви знаєте, PHP4 підтримує спадкування класів синтаксисом "class foo extends parent". В PHP4 И в PHP5 клас може успадковувати тільки один клас, тобто множинне спадкування не підтримується. Інтерфейсом називається клас,в якому не реалізується жоден метод, визначаються тільки назви методів і набір переданих їм параметрів. Згодом класи можуть 'реалізовувати' як завгодно багато інтерфейсів, показуючи тим самим, що той чи інший клас реалізує методи, визначені в інтерфейсі.
<? php interface displayable ( function display (); )
interface printable ( function doprint (); )
class foo implements displayable, printable ( function display () ( / / Код ) /> Function doprint () ( / / Код ) ) ">?> Використання інтерфейсів корисно для більш зручного читання й розуміння коду: прочитавши оголошення класу, ми побачимо, що клас реалізує інтерфейси displayable і printable; це означає, що клас повинен мати методи display () і doprint (). Як ці методи реалізованийи - значення не має, головне - уже з об'яви класу, ви знаєте, що можете викликати ці методи. Абстрактні класи Абстрактним називається клас, який може використовуватися тільки як базовий (тобто створювати об'єкти цього класу не можна). Как і в будь-якому нормальному базовому класі, в абстрактному класі ви можете визначати методи й змінні. В абстрактному класі також можна визначати абстрактні методи: методи, які не реалізовані в абстрактному класі, але які обов'язково повинні бути реалізовані в похідних класах. />
Приклад 6: абстрактні класи <? php abstract class foo# 007700 "> ( protected $ x;
abstract function display ();
function setX ($ x) ( $ this -> > x = $ x; ) )
class foo2 extends olor: # 0000bb "> foo ( function display () ( / / Код olor: # 007700 ">) ) ?> __call З PHP5 ви можете реалізувати в класі спеціальний метод __call (), як метод для "вилову" всіх нереалізованих у даному класі методів. Метод__call (якщо він визначений) викликається при спробі викликати недоступний або неіснуючий метод.
Приклад 7: __call <? php class & n bsp; foo (
function __call ($ name, = "color: # 0000bb"> $ arguments) ( print ( "викликали? Я - $ name!"); ) )
or: # 0000bb "> $ x = new foo (); $ x -> doStuffcolor: # 007700 ">(); $ x -> fancy_stuff (); ?> Цей спеціальний метод може бутивикористаний для реалізації перевантаження методів: ви можете досліджувати отримані аргументи і в залежності від результату викликати підходящий для даного випадку закритий метод, наприклад:
Приклад 8: Перевантаження методів за допомогою __call <? php class Magic (
function __call yle = "color: # 007700"> ($ name, $ arguments) ( if ($ name> == 'Foo') ( if (is_int ($ arguments [ 0])) $ this -> foo_for_int ($ arguments an style = "color: # 007700"> [0]); if (is_string ($ arguments or: # 007700 "> [0])) $ this -> foo_for_string ( > $ arguments [0]); ) )
private function foo_for_int: # 007700 "> ($ x) ( print ( "у, дивіться, ціле число!"); )
& nbsp; private function foo_for_string ($ x) ( print ( "у, дивіться, рядок! "); ) )
$ x = new Magic (); : # 0000bb "> $ x -> foo (3); $ x -> ( "3"); ?> __set і __get Але це ще н е все, тепер ви можете визначити методи __set і __get для "вилову" всіх спроб зміни або доступу до невизначеним (або недоступним) змінним.
Приклад 9: __set і __get r: # 0000bb "> <? php class foo (
function __set (# 0000bb "> $ name, $ val) ( print ( "Привіт, ви спробували привласнити значення $ val змінної$ name "); )
function __get ($ name) ( & nbsp; print ( "Привіт, ви намагалися звернутися до $ name"); ) )
$ x = newfoo (); $ x -> bar = 3 n style = "color: # 007700">; print ($ x -> winky_winky); ?> small_caption "> Вказівка типів для аргументів В PHP5 ви зможете "сказати" методу, що він повинен отримати в якості аргументу об'єкт певного типу.
Приклад 10: вказівка типів tyle = "color: # 0000bb"> <? php class foo ( / / Код ... )
cl ass bar ( public function process_a_foo (foo $ foo 07700 ">) ( / / Ще який-небудь код ) )
$ b = newstyle = "color: # 0000bb"> bar (); $ f = new foo (); $ b process_a_foo ($ f); ?> Як ви помітили, перед ім'ямаргумента тепер можна поставити ім'я його класу, і таким чином PHP5 визначить, що змінна $ foo повинна бути класу foo. Статичні члени класу Статичні члени і статичні методи можуть використовуватися для реалізації того, що в ООП називается "методи класу" і "змінні класу". "Статичні методом класу" називають метод, який можна викликати без створення об'єкта цього класу. "Змінна класу" називають змінну, до якої можна звернутися без створення об'єкта цього класу (і метод доступу при цьому не потрібно).
Приклад 11: методи класу й змінні класу <? php class: # 0000bb "> calculator ( static public $ pi = 3.14151692;
& nbsp; static public function add ($ x, $ y) ( return $ x + $ y; ) )
$ s = Calculator:: $ pi; $ result ="> calculator:: add (3, 7); print ( result"); ?> Виключення Виключення - це загальноприйнятий підхід до обробки помилок і несподіваних ситуацій у таких яз иках як Java і C + +; в PHP5 перехоплення виключень реалізований з допомогою пари "try" - "catch".
Приклад 12: Виключення <? php : # 007700 "> class foo (
function divide ($ x, $ y) ( if ($ y == 0) throw new n style = "color: # 0000bb"> Exception ( "розподіл на нуль неприпустимо"); return $ x color: # 007700 "> / $ y; ) )
$ x = new foo 00 ">();
try ( $ x -> divide (3, "color: # 0000bb"> 0); ) Catch (Exception $ e) ( echo $ e r: # 007700 "> -> getMessage (); echo " n <br /> n"; color: # ff8000 "> / / Які-небудь драконівські заходи ) ?> Як ви бачите, "try" використовується для позначення блоку, у якому знаходяться помилки, в опрацюванні оперативнимиором "catch", що стояв в кінці блоку. У блоці "catch" вам потрібно реалізувати вашу власну політику обробки помилок. У підсумку отримуємо зручним код і всього один блок обробки помилок.
Винятки, визначені користувачем Для обробки непередбачених проблем у ваших програмах ви можете визначити ваші власні винятки. Все, що вам потрібно - це просто доповнити (extend) клас Exception, визначивши конструктор класу й метод getMessage.
Приклад 13: Виключення, опр еделенние користувачем <? php class WeirdProblem extends 0000bb "> Exception (
private $ data;
function WeirdProblem : # 007700 "> ($ data) ( parent:: exception or: # 007700 ">(); $ this -> data = $ datae = "color: # 007700">; )
function getMessage () ( return $ this -> data. "викликало якесь дивне виключення!"; ) ) ?> Потім, для порушення визначеного вами виключення використайте конструкцію throw new WeirdProblem ($ foo); якщо виключення відбувається всередині блоку try (), то PHP5 передасть керування в "catch"-блок для обробки. Простори імен З метою зручності класи та функції можуть бути згруповані в простори імен (namespaces). Прімеченіе: розроблювачі відмовилися від підтримка цієї можливості.
Приклад 14: Простір імен <? php namespace Math (
class Complex"> ( //... код ... function __construct () ( print ( "привіт"); ) ) )
$ m = newMath:: Complex (); ?> Зверніть увагу на синтаксис використання іменного простору для позначення класу, об'єкт которого ми створюємо. Приклад практичного застосування: створення однойменних класів у різних іменних просторах; при цьому класи роблять відмінну друг від друга роботу (маючи однаковий інтерфейс).
|