Відмінності між версіями «ООП в PHP»
Tkanoff (обговорення • внесок) |
м |
||
(не показані 13 проміжних версій ще одного учасника) | |||
Рядок 1: | Рядок 1: | ||
− | В програмуванні на PHP в основному використовуються такі парадигми програмування як '''процедурне''' і '''об'єктно-орієнтоване''' програмування. | + | В програмуванні на '''PHP''' в основному використовуються такі парадигми програмування як '''процедурне''' і '''об'єктно-орієнтоване''' програмування. |
− | ''Розглянемо ці парадигми детальніше | + | ''Розглянемо ці парадигми детальніше.'' |
== '''Процедурне програмування.''' == | == '''Процедурне програмування.''' == | ||
Рядок 24: | Рядок 24: | ||
'''ООП функціонує за наступними принципами:''' | '''ООП функціонує за наступними принципами:''' | ||
− | 1. '''Наслідування''' – це можливість породжувати один клас від іншого, при чому всі методи і властивості батьківського класу передаються дочірньому, дочірній клас в свою чергу може набувати нових методів і властивостей, яких не було в батьківському і також передавати їх в похідні від себе класи. | + | 1. '''Наслідування''' – це можливість породжувати один клас від іншого, при чому всі методи і властивості батьківського класу |
+ | передаються дочірньому, дочірній клас в свою чергу може набувати нових методів і властивостей, | ||
+ | яких не було в батьківському і також передавати їх в похідні від себе класи. | ||
2. '''Поліморфізм''' – це можливість дочірнього класу змінювати реалізацію тих чи інших дій батьківського класу. | 2. '''Поліморфізм''' – це можливість дочірнього класу змінювати реалізацію тих чи інших дій батьківського класу. | ||
− | 3. '''Інкапсуляція''' – це властивість об'єкта мати спеціальний інтерфейс (певний метод), через який і здійснюється взаємодія зовнішнього середовища з внутрішніми методами класу. При чому зовнішнє середовище може і не підозрювати про структуру і логіку внутрішніх методів. | + | 3. '''Інкапсуляція''' – це властивість об'єкта мати спеціальний інтерфейс (певний метод), через який і здійснюється |
+ | взаємодія зовнішнього середовища з внутрішніми методами класу. При чому зовнішнє середовище може і не | ||
+ | підозрювати про структуру і логіку внутрішніх методів. | ||
− | Якщо розглядати практичне застосування парадигм програмування стосовно PHP, то в попередніх до PHP 5 версіях використовується в основному процедурне програмування, так як об'єктна схема там вимальована достатньо умовно (тільки для виділення окремих сутностей, їх методів і властивостей в певні класи). Вже в 5-й версії PHP механізм взаємодії з об'єктами зазнав еволюційних змін. | + | Якщо розглядати практичне застосування парадигм програмування стосовно '''PHP''', то в попередніх до '''PHP 5''' версіях використовується в основному процедурне програмування, так як об'єктна схема там вимальована достатньо умовно (тільки для виділення окремих сутностей, їх методів і властивостей в певні класи). Вже в '''5-й''' версії '''PHP''' механізм взаємодії з об'єктами зазнав еволюційних змін. |
− | |||
− | + | == Області видимості методів і властивостей класів. == | |
− | + | В '''PHP 5''' введені специфікатори доступу до методів і властивостей класів: | |
− | + | ||
− | Розглянемо приклад | + | * '''public''' – доступний без обмежень |
+ | * '''protected''' – тільки в середині класу, в якому вони оголошені і похідних від нього класах | ||
+ | * '''private''' – тільки в середині класу, в якому вони оголошені | ||
+ | |||
+ | |||
+ | По замовчуванню виставляється тип доступу ''public''. | ||
+ | |||
+ | Розглянемо приклад з методами і властивостями різних типів доступності. | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
<?php | <?php | ||
+ | // оголошуємо основний клас | ||
class SomeClass | class SomeClass | ||
{ | { | ||
− | + | private $privateName = 'Private Name'; | |
+ | protected $protectedName = 'Protected Name'; | ||
+ | public $publicName = 'Public Name'; | ||
+ | |||
+ | private function PrivateFunction() | ||
+ | { | ||
+ | echo 'PrivateFunction()'; | ||
+ | } | ||
+ | |||
+ | protected function ProtectedFunction() | ||
+ | { | ||
+ | echo 'ProtectedFunction()'; | ||
+ | } | ||
+ | |||
+ | public function PublicFunction() | ||
+ | { | ||
+ | echo 'PublicFunction()'; | ||
+ | } | ||
+ | |||
+ | public function GetPrivate() | ||
+ | { | ||
+ | echo $this->privateName; | ||
+ | } | ||
+ | |||
+ | public function GetProtected() | ||
+ | { | ||
+ | echo $this->protectedName; | ||
+ | } | ||
+ | |||
+ | public function GetPublic() | ||
+ | { | ||
+ | echo $this->publicName; | ||
+ | } | ||
} | } | ||
− | + | // оголошуємо похідний клас від SomeClass | |
− | + | class SomeClass1 extends SomeClass | |
− | $ | + | { |
+ | public function GetPrivateFromParent() | ||
+ | { | ||
+ | echo $this->privateName; | ||
+ | } | ||
+ | } | ||
− | + | $someObj1 = new SomeClass; | |
− | $someObj2 = | + | $someObj2 = new SomeClass1; |
− | + | // Доступ до private методів і властивостей | |
− | + | echo $someObj1->privateName; // Виводить помилку | |
+ | echo $someObj2->privateName; // Виводить помилку | ||
+ | $someObj1->PrivateFunction(); // Виводить помилку | ||
+ | $someObj2->PrivateFunction(); // Виводить помилку | ||
+ | $someObj1->GetPrivate(); // Виводится 'Private Name' | ||
+ | $someObj2->GetPrivate(); // Виводится 'Private Name'*/ | ||
+ | $someObj2->GetPrivateFromParent(); // Нічого не виводиться | ||
− | // | + | // Доступ до protected методів і властивостей |
− | $someObj2-> | + | echo $someObj1->protectedName; // Виводить помилку |
+ | echo $someObj2->protectedName; // Виводить помилку | ||
+ | $someObj1->ProtectedFunction(); // Виводить помилку | ||
+ | $someObj2->ProtectedFunction(); // Виводить помилку | ||
+ | $someObj1->GetProtected(); // Виводится 'Protected Name' | ||
+ | $someObj2->GetProtected(); // Виводится 'Protected Name' | ||
− | + | // Доступ до public методів і властивостей | |
− | + | echo $someObj1->publicName; // Виводиться 'Public Name' | |
− | ?> | + | echo $someObj2->publicName; // Виводиться 'Public Name' |
+ | $someObj1->PublicFunction(); // Виводиться 'PublicFunction()' | ||
+ | $someObj2->PublicFunction(); // Виводиться 'PublicFunction()' | ||
+ | $someObj1->GetPublic(); // Виводиться 'Public Name' | ||
+ | $someObj2->GetPublic(); // Виводиться 'Public Name' | ||
+ | ?> | ||
+ | </syntaxhighlight> | ||
− | + | Є ще також статичні (''static'') методи і властивості. Їхньою особливістю є те, що вони не належать певному об'єктові, вони єдині для цілого класу, і можуть викликатися без створення об'єкту. Зміна статичної властивості в одному з об'єктів класу призводить до його зміни для всіх об'єктів цього класу. | |
− | + | ||
− | + | ||
Приклад: | Приклад: | ||
− | <?php | + | |
− | class SomeClass{ | + | <syntaxhighlight lang="php"> |
− | + | <?php | |
+ | // оголошуємо основний клас | ||
+ | class SomeClass | ||
+ | { | ||
+ | static $staticVar = 'Static Variable'; | ||
− | + | static function StaticFunction() | |
− | + | { | |
− | + | echo 'StaticFunction()'; | |
− | + | } | |
− | } | + | } |
+ | echo SomeClass::StaticFunction(); // Виводить StaticFunction() | ||
+ | echo SomeClass::$staticVar; // Виводить Static Variable | ||
+ | ?> | ||
+ | </syntaxhighlight> | ||
− | + | == Константи класу == | |
− | + | ||
− | + | ||
− | + | При описі класу в '''PHP 5''' можна задавати властивості-константи (ключове слово '''const'''). Викликати константи можна і без створення об'єкту на основі класу, в якому оголошені константи. | |
− | + | ||
− | + | ||
− | + | Приклад: | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | <syntaxhighlight lang="php"> | |
− | + | <?php | |
− | + | class SomeClass | |
+ | { | ||
+ | const SOME_CONSTANT = "SOME CONSTANT"; | ||
+ | } | ||
+ | echo SomeClass::SOME_CONSTANT; // Виводить "SOME CONSTANT" | ||
+ | ?> | ||
+ | </syntaxhighlight> | ||
+ | == Конструктори и деструктори. == | ||
− | |||
− | + | Конструктор ('''__construct()''') і деструктор ('''__destruct()''') це методи що викликаються автоматично при створенні і знищенні об'єкту відповідно: | |
− | <?php | + | |
− | + | <syntaxhighlight lang="php"> | |
− | class SomeClass{ | + | <?php |
− | + | class SomeClass | |
− | + | { | |
− | + | function __construct() | |
− | + | { | |
− | + | echo 'Create object'; | |
− | + | } | |
− | + | ||
− | + | function __destruct() | |
− | + | { | |
− | + | echo 'Destroy object'; | |
− | + | } | |
− | + | } | |
− | + | $someObj = new SomeClass; // Виводиться Create object | |
− | + | unset($someObj); // Виводиться Destroy object | |
− | + | ?> | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | == Абстрактні методи і класи. == | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Абстрактні (''abstract'') методи і класи тільки оголошуються, клас який містить абстрактні методи повинен оголоситися як абстрактний. На основі абстрактного класу можна тільки створювати інші класи, а вже від них об'єкти. Абстрактний клас може містити і звичайні (не абстрактні) елементи. | |
− | + | ||
− | + | Приклад: | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | <syntaxhighlight lang="php"> | |
− | + | <?php | |
− | + | abstract class SomeAbstractClass | |
− | + | { | |
− | + | // оголошення абстрактної функції | |
− | + | abstract public function abstractFunction(); | |
− | + | // оголошення неабстрактної функції | |
+ | public function GeneralFunction() | ||
+ | { | ||
+ | |||
+ | } | ||
+ | } | ||
− | // | + | class SomeClass extends SomeAbstractClass |
− | echo | + | { |
− | + | // перевантаження абстрактного методу | |
− | $someObj1 | + | public function abstractFunction() |
− | $ | + | { |
− | + | echo 'abstractFunction()'; | |
− | + | } | |
− | + | } | |
+ | $someObj = new SomeAbstractClass; // Помилка створення об'єкта | ||
+ | $someObj1 = new SomeClass; | ||
+ | $someObj1->abstrFunc(); // Виводить 'abstractFunction()' | ||
+ | ?> | ||
+ | </syntaxhighlight> | ||
− | + | == Інтерфейси. == | |
− | + | В '''PHP 5''' немає множинного наслідування, тобто один клас не може бути створений на основі кількох інших класів. Але клас може бути створений на основі кількох інтерфейсів. Інтерфейс – це фактично абстрактний клас, який містить тільки абстрактні методи і не містить ніяких властивостей. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Оголошуються інтерфейси з використанням ключового слова ''interface'', а всі функції оголошуються стандартно, з використанням ключового слова ''function''. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
Приклад: | Приклад: | ||
− | |||
− | |||
− | |||
− | |||
− | + | <syntaxhighlight lang="php"> | |
− | ? | + | <?php |
− | + | // оголошення інтерфейсів | |
− | + | interface InterfaceOne | |
+ | { | ||
+ | function SomeFunctionOne(); | ||
+ | } | ||
− | + | interface InterfaceTwo | |
− | + | { | |
− | + | function SomeFunctionTwo(); | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | } | + | |
− | $ | + | // оголошення класу на основі інтерфейсів |
− | + | class SomeClass implements InterfaceOne, InterfaceTwo | |
− | + | { | |
− | + | public function SomeFunctionOne() | |
− | + | { | |
+ | echo 'SomeFunctionOne()'; | ||
+ | } | ||
+ | public function SomeFunctionTwo() | ||
+ | { | ||
+ | echo 'SomeFunctionTwo()'; | ||
+ | } | ||
+ | } | ||
+ | $object = new SomeClass; | ||
+ | $object->SomeFunctionOne(); // Виводить 'SomeFunctionOne()' | ||
+ | $object->SomeFunctionTwo(); // Виводить 'SomeFunctionTwo()' | ||
+ | ?> | ||
+ | </syntaxhighlight> | ||
− | + | == Фінальні методи і класи. == | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | В '''PHP 5''' є можливість задати таку властивість класу і методу як фінальний (final). На основі фінальних класів неможливо створити класи нащадки. Також не можна перевизначити фінальний метод в класах нащадках. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
Приклад: | Приклад: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | <syntaxhighlight lang="php"> | |
− | + | <?php | |
− | } | + | final class FinalClass |
+ | { | ||
+ | |||
+ | } | ||
− | + | class ClassWithFinalMethod | |
− | + | { | |
− | + | final public function FinalFunction() | |
− | + | { | |
− | + | echo 'FinalFunction()'; | |
− | + | } | |
− | + | } | |
− | + | ||
− | } | + | |
− | + | // наступне оголошення класу викликає помилку | |
− | + | class SomeClass1 extends FinalClass | |
− | + | { | |
− | + | // опис класу | |
− | + | } | |
− | + | ||
− | + | // створюємо клас на основі класу з фінальним методом | |
− | + | class SomeClass1 extends ClassWithFinalMethod | |
− | + | { | |
− | + | // наступне перевизначення методі викликає помилку | |
− | } | + | public function FinalFunction() |
+ | { | ||
+ | } | ||
+ | } | ||
+ | ?> | ||
+ | </syntaxhighlight> | ||
− | + | == Обробка винятків (помилок). == | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Найцікавішим нововведенням в '''PHP 5''' є методи для обробки винятків. Для цього використовуються конструкції try/catch/throw. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | Найцікавішим нововведенням в PHP 5 є методи для обробки винятків. Для цього використовуються конструкції try/catch/throw. | + | |
Розглянемо простий приклад використання цих методів: | Розглянемо простий приклад використання цих методів: | ||
− | <?php | + | |
− | + | <syntaxhighlight lang="php"> | |
− | + | <?php | |
− | + | try { | |
− | + | // відкриваємо файл для читання | |
− | + | $fp = @fopen("somefile.txt", "r"); | |
− | + | // якщо файл відсутній, створюємо виключення | |
+ | if (!$someFile) | ||
+ | throw new Exception(" Помилка відкриття файлу!"); | ||
− | + | fclose($someFile); | |
− | + | } | |
− | + | catch | |
− | + | (Exception $exception) | |
− | + | { | |
− | + | // метод $exception->getLine() повертає номер рядка даного скрипта, в якому виникла помилка | |
− | ?> | + | echo "Помилка в рядку ", $exception->getLine(); |
− | Ключове слово instanceof. | + | echo $exception->getMessage(); // Выводит "Помилка відкриття файлу!" |
− | Метод instanceof дозволяє визначити походження об'єкта, його приналежність до певного класу, або чи є він нащадком якогось об'єкта. Також за допомогою instanceof можна визначити чи об'єкт екземпляром класу, створеного на основі певного інтерфейсу. | + | } |
+ | ?> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Ключове слово ''instanceof''. | ||
+ | Метод ''instanceof'' дозволяє визначити походження об'єкта, його приналежність до певного класу, або чи є він нащадком якогось об'єкта. Також за допомогою instanceof можна визначити чи об'єкт екземпляром класу, створеного на основі певного інтерфейсу. | ||
Приклад: | Приклад: | ||
− | <?php | + | |
− | + | <syntaxhighlight lang="php"> | |
− | + | <?php | |
− | + | interface SomeInterfaceOne { } | |
− | + | interface SomeInterfaceTwo { } | |
− | + | class SomeClassTypeOne { } | |
+ | class SomeClassTypeTwo extends SomeClassTypeOne {} | ||
+ | class SomeClassTypeThree implements SomeInterfaceOne, SomeInterfaceTwo {} | ||
− | + | $objOne = new SomeClassTypeOne; | |
− | + | $objTwo = new SomeClassTypeTwo; | |
− | + | $objThree = new SomeClassTypeThree; | |
− | + | $clonedObj = clone $objThree; | |
− | + | // наступний блок виводить: об'єкт $objOne належить до класу SomeClassTypeOne | |
− | + | if($objOne instanceof SomeClassTypeOne) | |
− | + | echo 'об\'єкт $objOne належить до класу SomeClassTypeOne'; | |
− | + | // наступний блок виводить: об'єкт $objTwo належить до класу SomeClassTypeTwo | |
− | + | if($objTwo instanceof SomeClassTypeTwo) | |
− | + | echo 'об\'єкт $objTwo належить до класу SomeClassTypeTwo'; | |
− | + | // наступний блок виводить: об'єкт $objThree належить до класу SomeClassTypeThree | |
− | + | if($objThree instanceof SomeClassTypeThree) | |
− | + | echo 'об\'єкт $objThree належить до класу SomeClassTypeThree'; | |
− | + | // наступний блок виводить: об'єкт $objTwo є екземпляром класу створеного на основі класу SomeClassTypeOne | |
− | + | if($objTwo instanceof SomeClassTypeOne) | |
− | + | echo 'об\'єкт $objTwo є екземпляром класу створеного на основі класу SomeClassTypeOne'; | |
− | + | // наступний блок виводить: об'єкт $objThree є екземпляром класу створеного на основі інтерфейсу SomeInterfaceOne | |
− | + | if($objThree instanceof SomeInterfaceOne) | |
− | + | echo 'об\'єкт $objThree є екземпляром класу створеного на основі інтерфейсу SomeInterfaceOne'; | |
− | + | // наступний блок виводить: об'єкт $objThree є екземпляром класу створеного на основі інтерфейсу SomeInterfaceTwo | |
− | + | if($objThree instanceof SomeInterfaceTwo) | |
− | + | echo 'об\'єкт $objThree є екземпляром класу створеного на основі інтерфейсу SomeInterfaceTwo'; | |
− | + | // наступний блок виводить: об'єкта $clonedObj створений на основі об'єкту $objThree | |
− | + | if($clonedObj instanceof $objThree) | |
− | + | echo 'об\'єкта $clonedObj створений на основі об\'єкту $objThree'; | |
− | ?> | + | ?> |
− | Функція __autoload() | + | </syntaxhighlight> |
− | Функція __autoload() викликається в випадку коли створюється об'єкт на основі неіснуючого класу | + | |
+ | == Функція __autoload() == | ||
+ | |||
+ | Функція ''__autoload()'' викликається в випадку коли створюється об'єкт на основі неіснуючого або неописаного в даному конкретному файлі з кодом класу | ||
Приклад: | Приклад: | ||
− | <?php | + | |
− | + | <syntaxhighlight lang="php"> | |
− | echo "спроба створити об'єкт невизначеного класу ", $class; | + | <?php |
− | + | function __autoload($class) | |
+ | { | ||
+ | echo "спроба створити об'єкт невизначеного класу ", $class; | ||
+ | } | ||
− | + | // спроба створити об'єкт невизначеного класу MyClass | |
− | + | // Fatal error: Class 'MyClass' not found in C:\wamp\www\test.php on line 5 | |
− | + | $someObj = new SomeWrongClass; | |
− | + | ||
− | + | // наступна стрічка трохи практичніша | |
− | + | // (екрануємо створення об'єту символом "@") | |
− | + | // вона виводить: | |
− | + | // спроба створити об'єкт невизначеного класу MyClass | |
− | + | $someObj = @new SomeWrongClass; | |
− | ?> | + | ?> |
− | Перевантаження доступу до властивостей об'єкту. | + | </syntaxhighlight> |
− | Методи доступу __get() і __set() дозволяють динамічно визначати властивості об'єктів. __get() в якості параметра отримує ім'я властивості, а __set() окрім імені ще і нове значення властивості, яке відповідно і присвоює. | + | |
+ | == Перевантаження доступу до властивостей об'єкту. == | ||
+ | |||
+ | Методи доступу ''__get()'' і ''__set()'' дозволяють динамічно визначати властивості об'єктів. ''__get()'' в якості параметра отримує ім'я властивості, а ''__set()'' окрім імені ще і нове значення властивості, яке відповідно і присвоює. | ||
Приклад: | Приклад: | ||
− | <?php | + | |
− | + | <syntaxhighlight lang="php"> | |
− | private $classPropertys; | + | <?php |
− | + | class SomeClass | |
− | + | { | |
− | + | private $classPropertys; | |
− | + | function __set($name, $value) | |
+ | { | ||
+ | echo "__set: присвоювання властивості $name = $value"; | ||
+ | $this->classPropertys[$name]=$value; | ||
+ | } | ||
− | + | function __get($name) | |
− | + | { | |
− | + | echo "__get: читання властивості $name: "; | |
+ | echo $this->classPropertys[$name]; | ||
+ | } | ||
} | } | ||
− | |||
− | + | $obj = new SomeClass; | |
− | + | $obj->name = 'New Value'; // Виводить "__set: присвоювання властивості name=New Value" | |
− | + | $value = $obj->name; // Виводить "__get: читання властивості name: New Value" | |
− | ?> | + | ?> |
− | Перевантаження викликів методів класу. | + | </syntaxhighlight> |
− | Якщо метод __call() описаний в певному класі, тоді він автоматично переловлює виклики до неіснуючих методів цього класу. В якості параметрів він отримує ім'я і параметри методу що викликається. | + | |
+ | == Перевантаження викликів методів класу. == | ||
+ | |||
+ | Якщо метод ''__call()'' описаний в певному класі, тоді він автоматично переловлює виклики до неіснуючих методів цього класу. В якості параметрів він отримує ім'я і параметри методу що викликається. | ||
Приклад: | Приклад: | ||
− | <?php | + | |
− | + | <syntaxhighlight lang="php"> | |
− | function __call($name, $params) { | + | <?php |
− | + | class SomeClass | |
− | + | { | |
− | + | function __call($name, $params) | |
− | + | { | |
+ | echo "Помилка: викликано неіснуючий метод $name з параметром[ами]: "; | ||
+ | foreach($params as $val) | ||
+ | { | ||
+ | echo $val.' | '; | ||
+ | } | ||
+ | } | ||
} | } | ||
− | |||
− | + | $obj = new SomeClass; | |
− | + | $obj->WrongMethodOne(1, 2, 'param'); // Виводить: 'Помилка: викликано неіснуючий метод | |
− | + | // WrongMethodOne з параметром[ами]: 1 | 2 | param |' | |
− | ?> | + | $obj->WrongMethodTwo(123); // Виводить: 'Помилка: викликано неіснуючий метод WrongMethodOne з параметром[ами]: 123 |' |
+ | ?> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | [[category:Інтернет-програмування|*]] | ||
+ | |||
+ | [[category:Навчальні проекти]] |
Поточна версія на 09:42, 9 вересня 2014
В програмуванні на PHP в основному використовуються такі парадигми програмування як процедурне і об'єктно-орієнтоване програмування.
Розглянемо ці парадигми детальніше.
Зміст
- 1 Процедурне програмування.
- 2 Об'єктно-орієнтовне програмування (ООП).
- 3 Області видимості методів і властивостей класів.
- 4 Константи класу
- 5 Конструктори и деструктори.
- 6 Абстрактні методи і класи.
- 7 Інтерфейси.
- 8 Фінальні методи і класи.
- 9 Обробка винятків (помилок).
- 10 Функція __autoload()
- 11 Перевантаження доступу до властивостей об'єкту.
- 12 Перевантаження викликів методів класу.
Процедурне програмування.
Робота цієї концепції заснована на виклику так званих процедур (методи, функції, ...). Кожна процедура містить певну логіку для виконання тих чи інших операцій і може бути викликана з будь-якого місця програми.
Об'єктно-орієнтовне програмування (ООП).
В даній парадигмі основою є певний об'єкт чи сукупність об'єктів, їхні властивості, методи і події. Власне з появою ООП і з'явилися такі терміни як клас, наслідування, поліморфізм, інкапсуляція.
Якщо розглядати поняття об'єкту концептуально, то об'єкт є лише екземпляром певного класу об'єктів.
Об'єкти представляють собою часткову інформацію про певну сутність, а власне певну модель, що адекватна завданню що треба вирішити. Цей варіант представлення називається абстракція даних. При такому представленні з об'єктом працювати набагато простіше, ніж з низькорівневим представленнями з описом всіх можливих властивостей і методів.
Кожен об'єкт має свій певний тип (клас), що об'єднає в собі наступні елементи:
1. Властивості – певні параметри і характеристики об'єкту 2. Методи – дії, що можна виконувати над даним об'єктом, чи які може виконувати він сам 3. Події – повідомлення що виникають при зміні стану об'єкта
ООП функціонує за наступними принципами:
1. Наслідування – це можливість породжувати один клас від іншого, при чому всі методи і властивості батьківського класу передаються дочірньому, дочірній клас в свою чергу може набувати нових методів і властивостей, яких не було в батьківському і також передавати їх в похідні від себе класи. 2. Поліморфізм – це можливість дочірнього класу змінювати реалізацію тих чи інших дій батьківського класу. 3. Інкапсуляція – це властивість об'єкта мати спеціальний інтерфейс (певний метод), через який і здійснюється взаємодія зовнішнього середовища з внутрішніми методами класу. При чому зовнішнє середовище може і не підозрювати про структуру і логіку внутрішніх методів.
Якщо розглядати практичне застосування парадигм програмування стосовно PHP, то в попередніх до PHP 5 версіях використовується в основному процедурне програмування, так як об'єктна схема там вимальована достатньо умовно (тільки для виділення окремих сутностей, їх методів і властивостей в певні класи). Вже в 5-й версії PHP механізм взаємодії з об'єктами зазнав еволюційних змін.
Області видимості методів і властивостей класів.
В PHP 5 введені специфікатори доступу до методів і властивостей класів:
* public – доступний без обмежень * protected – тільки в середині класу, в якому вони оголошені і похідних від нього класах * private – тільки в середині класу, в якому вони оголошені
По замовчуванню виставляється тип доступу public.
Розглянемо приклад з методами і властивостями різних типів доступності.
<?php // оголошуємо основний клас class SomeClass { private $privateName = 'Private Name'; protected $protectedName = 'Protected Name'; public $publicName = 'Public Name'; private function PrivateFunction() { echo 'PrivateFunction()'; } protected function ProtectedFunction() { echo 'ProtectedFunction()'; } public function PublicFunction() { echo 'PublicFunction()'; } public function GetPrivate() { echo $this->privateName; } public function GetProtected() { echo $this->protectedName; } public function GetPublic() { echo $this->publicName; } } // оголошуємо похідний клас від SomeClass class SomeClass1 extends SomeClass { public function GetPrivateFromParent() { echo $this->privateName; } } $someObj1 = new SomeClass; $someObj2 = new SomeClass1; // Доступ до private методів і властивостей echo $someObj1->privateName; // Виводить помилку echo $someObj2->privateName; // Виводить помилку $someObj1->PrivateFunction(); // Виводить помилку $someObj2->PrivateFunction(); // Виводить помилку $someObj1->GetPrivate(); // Виводится 'Private Name' $someObj2->GetPrivate(); // Виводится 'Private Name'*/ $someObj2->GetPrivateFromParent(); // Нічого не виводиться // Доступ до protected методів і властивостей echo $someObj1->protectedName; // Виводить помилку echo $someObj2->protectedName; // Виводить помилку $someObj1->ProtectedFunction(); // Виводить помилку $someObj2->ProtectedFunction(); // Виводить помилку $someObj1->GetProtected(); // Виводится 'Protected Name' $someObj2->GetProtected(); // Виводится 'Protected Name' // Доступ до public методів і властивостей echo $someObj1->publicName; // Виводиться 'Public Name' echo $someObj2->publicName; // Виводиться 'Public Name' $someObj1->PublicFunction(); // Виводиться 'PublicFunction()' $someObj2->PublicFunction(); // Виводиться 'PublicFunction()' $someObj1->GetPublic(); // Виводиться 'Public Name' $someObj2->GetPublic(); // Виводиться 'Public Name' ?>
Є ще також статичні (static) методи і властивості. Їхньою особливістю є те, що вони не належать певному об'єктові, вони єдині для цілого класу, і можуть викликатися без створення об'єкту. Зміна статичної властивості в одному з об'єктів класу призводить до його зміни для всіх об'єктів цього класу.
Приклад:
<?php // оголошуємо основний клас class SomeClass { static $staticVar = 'Static Variable'; static function StaticFunction() { echo 'StaticFunction()'; } } echo SomeClass::StaticFunction(); // Виводить StaticFunction() echo SomeClass::$staticVar; // Виводить Static Variable ?>
Константи класу
При описі класу в PHP 5 можна задавати властивості-константи (ключове слово const). Викликати константи можна і без створення об'єкту на основі класу, в якому оголошені константи.
Приклад:
<?php class SomeClass { const SOME_CONSTANT = "SOME CONSTANT"; } echo SomeClass::SOME_CONSTANT; // Виводить "SOME CONSTANT" ?>
Конструктори и деструктори.
Конструктор (__construct()) і деструктор (__destruct()) це методи що викликаються автоматично при створенні і знищенні об'єкту відповідно:
<?php class SomeClass { function __construct() { echo 'Create object'; } function __destruct() { echo 'Destroy object'; } } $someObj = new SomeClass; // Виводиться Create object unset($someObj); // Виводиться Destroy object ?>
Абстрактні методи і класи.
Абстрактні (abstract) методи і класи тільки оголошуються, клас який містить абстрактні методи повинен оголоситися як абстрактний. На основі абстрактного класу можна тільки створювати інші класи, а вже від них об'єкти. Абстрактний клас може містити і звичайні (не абстрактні) елементи.
Приклад:
<?php abstract class SomeAbstractClass { // оголошення абстрактної функції abstract public function abstractFunction(); // оголошення неабстрактної функції public function GeneralFunction() { } } class SomeClass extends SomeAbstractClass { // перевантаження абстрактного методу public function abstractFunction() { echo 'abstractFunction()'; } } $someObj = new SomeAbstractClass; // Помилка створення об'єкта $someObj1 = new SomeClass; $someObj1->abstrFunc(); // Виводить 'abstractFunction()' ?>
Інтерфейси.
В PHP 5 немає множинного наслідування, тобто один клас не може бути створений на основі кількох інших класів. Але клас може бути створений на основі кількох інтерфейсів. Інтерфейс – це фактично абстрактний клас, який містить тільки абстрактні методи і не містить ніяких властивостей.
Оголошуються інтерфейси з використанням ключового слова interface, а всі функції оголошуються стандартно, з використанням ключового слова function.
Приклад:
<?php // оголошення інтерфейсів interface InterfaceOne { function SomeFunctionOne(); } interface InterfaceTwo { function SomeFunctionTwo(); } // оголошення класу на основі інтерфейсів class SomeClass implements InterfaceOne, InterfaceTwo { public function SomeFunctionOne() { echo 'SomeFunctionOne()'; } public function SomeFunctionTwo() { echo 'SomeFunctionTwo()'; } } $object = new SomeClass; $object->SomeFunctionOne(); // Виводить 'SomeFunctionOne()' $object->SomeFunctionTwo(); // Виводить 'SomeFunctionTwo()' ?>
Фінальні методи і класи.
В PHP 5 є можливість задати таку властивість класу і методу як фінальний (final). На основі фінальних класів неможливо створити класи нащадки. Також не можна перевизначити фінальний метод в класах нащадках.
Приклад:
<?php final class FinalClass { } class ClassWithFinalMethod { final public function FinalFunction() { echo 'FinalFunction()'; } } // наступне оголошення класу викликає помилку class SomeClass1 extends FinalClass { // опис класу } // створюємо клас на основі класу з фінальним методом class SomeClass1 extends ClassWithFinalMethod { // наступне перевизначення методі викликає помилку public function FinalFunction() { } } ?>
Обробка винятків (помилок).
Найцікавішим нововведенням в PHP 5 є методи для обробки винятків. Для цього використовуються конструкції try/catch/throw.
Розглянемо простий приклад використання цих методів:
<?php try { // відкриваємо файл для читання $fp = @fopen("somefile.txt", "r"); // якщо файл відсутній, створюємо виключення if (!$someFile) throw new Exception(" Помилка відкриття файлу!"); fclose($someFile); } catch (Exception $exception) { // метод $exception->getLine() повертає номер рядка даного скрипта, в якому виникла помилка echo "Помилка в рядку ", $exception->getLine(); echo $exception->getMessage(); // Выводит "Помилка відкриття файлу!" } ?>
Ключове слово instanceof. Метод instanceof дозволяє визначити походження об'єкта, його приналежність до певного класу, або чи є він нащадком якогось об'єкта. Також за допомогою instanceof можна визначити чи об'єкт екземпляром класу, створеного на основі певного інтерфейсу.
Приклад:
<?php interface SomeInterfaceOne { } interface SomeInterfaceTwo { } class SomeClassTypeOne { } class SomeClassTypeTwo extends SomeClassTypeOne {} class SomeClassTypeThree implements SomeInterfaceOne, SomeInterfaceTwo {} $objOne = new SomeClassTypeOne; $objTwo = new SomeClassTypeTwo; $objThree = new SomeClassTypeThree; $clonedObj = clone $objThree; // наступний блок виводить: об'єкт $objOne належить до класу SomeClassTypeOne if($objOne instanceof SomeClassTypeOne) echo 'об\'єкт $objOne належить до класу SomeClassTypeOne'; // наступний блок виводить: об'єкт $objTwo належить до класу SomeClassTypeTwo if($objTwo instanceof SomeClassTypeTwo) echo 'об\'єкт $objTwo належить до класу SomeClassTypeTwo'; // наступний блок виводить: об'єкт $objThree належить до класу SomeClassTypeThree if($objThree instanceof SomeClassTypeThree) echo 'об\'єкт $objThree належить до класу SomeClassTypeThree'; // наступний блок виводить: об'єкт $objTwo є екземпляром класу створеного на основі класу SomeClassTypeOne if($objTwo instanceof SomeClassTypeOne) echo 'об\'єкт $objTwo є екземпляром класу створеного на основі класу SomeClassTypeOne'; // наступний блок виводить: об'єкт $objThree є екземпляром класу створеного на основі інтерфейсу SomeInterfaceOne if($objThree instanceof SomeInterfaceOne) echo 'об\'єкт $objThree є екземпляром класу створеного на основі інтерфейсу SomeInterfaceOne'; // наступний блок виводить: об'єкт $objThree є екземпляром класу створеного на основі інтерфейсу SomeInterfaceTwo if($objThree instanceof SomeInterfaceTwo) echo 'об\'єкт $objThree є екземпляром класу створеного на основі інтерфейсу SomeInterfaceTwo'; // наступний блок виводить: об'єкта $clonedObj створений на основі об'єкту $objThree if($clonedObj instanceof $objThree) echo 'об\'єкта $clonedObj створений на основі об\'єкту $objThree'; ?>
Функція __autoload()
Функція __autoload() викликається в випадку коли створюється об'єкт на основі неіснуючого або неописаного в даному конкретному файлі з кодом класу
Приклад:
<?php function __autoload($class) { echo "спроба створити об'єкт невизначеного класу ", $class; } // спроба створити об'єкт невизначеного класу MyClass // Fatal error: Class 'MyClass' not found in C:\wamp\www\test.php on line 5 $someObj = new SomeWrongClass; // наступна стрічка трохи практичніша // (екрануємо створення об'єту символом "@") // вона виводить: // спроба створити об'єкт невизначеного класу MyClass $someObj = @new SomeWrongClass; ?>
Перевантаження доступу до властивостей об'єкту.
Методи доступу __get() і __set() дозволяють динамічно визначати властивості об'єктів. __get() в якості параметра отримує ім'я властивості, а __set() окрім імені ще і нове значення властивості, яке відповідно і присвоює.
Приклад:
<?php class SomeClass { private $classPropertys; function __set($name, $value) { echo "__set: присвоювання властивості $name = $value"; $this->classPropertys[$name]=$value; } function __get($name) { echo "__get: читання властивості $name: "; echo $this->classPropertys[$name]; } } $obj = new SomeClass; $obj->name = 'New Value'; // Виводить "__set: присвоювання властивості name=New Value" $value = $obj->name; // Виводить "__get: читання властивості name: New Value" ?>
Перевантаження викликів методів класу.
Якщо метод __call() описаний в певному класі, тоді він автоматично переловлює виклики до неіснуючих методів цього класу. В якості параметрів він отримує ім'я і параметри методу що викликається.
Приклад:
<?php class SomeClass { function __call($name, $params) { echo "Помилка: викликано неіснуючий метод $name з параметром[ами]: "; foreach($params as $val) { echo $val.' | '; } } } $obj = new SomeClass; $obj->WrongMethodOne(1, 2, 'param'); // Виводить: 'Помилка: викликано неіснуючий метод // WrongMethodOne з параметром[ами]: 1 | 2 | param |' $obj->WrongMethodTwo(123); // Виводить: 'Помилка: викликано неіснуючий метод WrongMethodOne з параметром[ами]: 123 |' ?>