Відмінності між версіями «ООП в PHP»

Матеріал з Вікі ЦДУ
Перейти до: навігація, пошук
(Створена сторінка: PHP rulez)
 
Рядок 1: Рядок 1:
 
PHP rulez
 
PHP rulez
 +
 +
Як відомо в програмуванні в середовищі PHP в основному використовуються такі парадигми програмування як процедурне і об'єктно-орієнтовне програмування.
 +
 +
Розглянемо ці парадигми детальніше:
 +
 +
Процедурне програмування.
 +
Робота цієї концепції заснована на виклику так званих процедур (методи, функції, ...).  Кожна процедура містить певну логіку для виконання тих чи інших операцій і може бути викликана з будь-якого місця програми. 
 +
 +
Об'єктно-орієнтовне програмування (ООП).
 +
В даній парадигмі основою є певний об'єкт чи сукупність об'єктів, їхні властивості, методи і події. Власне з появою ООП і з'явилися такі терміни як клас, наслідування, поліморфізм, інкапсуляція.
 +
 +
Якщо розглядати поняття об'єкту концептуально, то об'єкт є лише екземпляром певного класу об'єктів.
 +
 +
Об'єкти представляють собою  часткову інформацію про певну сутність, а власне певну модель, що адекватна завданню що треба вирішити. Цей варіант представлення називається абстракція даних. При такому представленні з об'єктом працювати набагато простіше, ніж з низькорівневим представленнями з описом всіх  можливих властивостей і методів.
 +
 +
Кожен об'єкт має свій певний тип (клас), що об'єднає в собі наступні елементи:
 +
 +
  1. Властивості – певні параметри і характеристики об'єкту
 +
  2. Методи – дії, що можна виконувати над даним об'єктом, чи які може виконувати він сам
 +
  3. Події – повідомлення що виникають при зміні стану об'єкта
 +
 +
 +
ООП функціонує за наступними принципами:
 +
 +
  1. Наслідування – це можливість породжувати один клас від іншого, при чому всі методи і властивості батьківського класу передаються дочірньому, дочірній клас в свою чергу може набувати нових методів і властивостей, яких не було в батьківському і також передавати їх в похідні від себе класи.
 +
  2. Поліморфізм – це можливість дочірнього класу змінювати реалізацію тих чи інших дій батьківського класу.
 +
  3. Інкапсуляція – це властивість об'єкта мати спеціальний інтерфейс (певний метод), через який і здійснюється взаємодія зовнішнього середовища з внутрішніми методами класу. При чому зовнішнє середовище може і не підозрювати про структуру і логіку  внутрішніх методів.
 +
 +
Якщо розглядати практичне застосування парадигм програмування стосовно PHP, то в попередніх до PHP 5 версіях використовується в основному процедурне програмування, так як об'єктна схема там вимальована достатньо умовно (тільки для виділення окремих сутностей, їх методів і властивостей в певні класи). Вже в 5-й версії PHP механізм взаємодії з об'єктами зазнав еволюційних змін.
 +
Вказівники і клонування.
 +
Одною з базових змін є передача об'єкту як параметр функції по вказівнику а не по значенню, тобто всі функції, яким параметром передався об'єкт, працюють з одним і тим самим об'єктом, а не з його копіями. Це дозволяє уникати появи дублікатів об'єктів. Похідною від цього нововведення є вища продуктивність при обробці сценаріїв де активно використовуються об'єкти.
 +
 +
Для створення копії об'єкта в PHP 5 використовується спеціальний метод __clone().
 +
До цього методу неможна звернутись безпосередньо. Для безпосереднього використання використовується ключове слово  clone.
 +
 +
Розглянемо приклад використання цього методу в PHP 5:
 +
<?php
 +
class SomeClass{
 +
  var $name;
 +
}
 +
 +
// створюємо клас  someObj1 і присвоюємо властивісті “name” значення “Object 1”
 +
$someObj1 = new SomeClass;
 +
$someObj1->name = 'Object 1';
 +
 +
// копіюємо клас  someObj1 в  someObj2
 +
$someObj2 = clone $someObj1;
 +
 +
echo $someObj1->name; // Виводить “Object 1”
 +
echo $someObj2->name; // Виводить “Object 1”
 +
 +
// присвоюємо властивісті класу  someObj2 “name” значення “Object 2”
 +
$someObj2->name = 'Object 2';
 +
 +
echo $someObj1->name; // Виводить “Object 1”
 +
echo $someObj2->name; // Виводить “Object 2”
 +
?>
 +
 +
В PHP 4 для копіювання об'єкту замість $someObj2 = clone $someObj1 треба було б використати $someObj2 = $someObj1.
 +
 +
На перший погляд все зручніше виглядало в PHP 4, але не будемо поспішати з висновками. Метод  __clone() не обов'язково описувати (перезавантажувати) в класі. Але якщо ми це зробимо, то зможемо  наперед задати поведінку об'єкта під час його клонування.
 +
 +
Приклад:
 +
<?php
 +
class SomeClass{
 +
  var $name;
 +
 +
  // перезавантаження методу __clone()
 +
  function __clone() {
 +
    $this->name = 'Copy';
 +
  }
 +
}
 +
 +
// створюємо клас  someObj1 і присвоюємо властивісті “name” значення “Original”
 +
$someObj1 = new SomeClass;
 +
$someObj1->name = 'Original';
 +
 +
// створюємо клас  someObj2
 +
// автоматично властивості “name” присвоюється значення “Copy”
 +
$someObj2 = clone $someObj1;
 +
 +
echo $someObj1->name; // Виводить “Original”
 +
echo $someObj2->name; // Виводить “Copy”
 +
?>
 +
Області видимості методів і властивостей класів.
 +
В 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 |'
 +
?>

Версія за 12:08, 12 квітня 2010

PHP rulez

Як відомо в програмуванні в середовищі PHP в основному використовуються такі парадигми програмування як процедурне і об'єктно-орієнтовне програмування.

Розглянемо ці парадигми детальніше:

Процедурне програмування. Робота цієї концепції заснована на виклику так званих процедур (методи, функції, ...). Кожна процедура містить певну логіку для виконання тих чи інших операцій і може бути викликана з будь-якого місця програми.

Об'єктно-орієнтовне програмування (ООП). В даній парадигмі основою є певний об'єкт чи сукупність об'єктів, їхні властивості, методи і події. Власне з появою ООП і з'явилися такі терміни як клас, наслідування, поліморфізм, інкапсуляція.

Якщо розглядати поняття об'єкту концептуально, то об'єкт є лише екземпляром певного класу об'єктів.

Об'єкти представляють собою часткову інформацію про певну сутність, а власне певну модель, що адекватна завданню що треба вирішити. Цей варіант представлення називається абстракція даних. При такому представленні з об'єктом працювати набагато простіше, ніж з низькорівневим представленнями з описом всіх можливих властивостей і методів.

Кожен об'єкт має свій певний тип (клас), що об'єднає в собі наступні елементи:

  1. Властивості – певні параметри і характеристики об'єкту
  2. Методи – дії, що можна виконувати над даним об'єктом, чи які може виконувати він сам
  3. Події – повідомлення що виникають при зміні стану об'єкта


ООП функціонує за наступними принципами:

  1. Наслідування – це можливість породжувати один клас від іншого, при чому всі методи і властивості батьківського класу передаються дочірньому, дочірній клас в свою чергу може набувати нових методів і властивостей, яких не було в батьківському і також передавати їх в похідні від себе класи.
  2. Поліморфізм – це можливість дочірнього класу змінювати реалізацію тих чи інших дій батьківського класу.
  3. Інкапсуляція – це властивість об'єкта мати спеціальний інтерфейс (певний метод), через який і здійснюється взаємодія зовнішнього середовища з внутрішніми методами класу. При чому зовнішнє середовище може і не підозрювати про структуру і логіку  внутрішніх методів.

Якщо розглядати практичне застосування парадигм програмування стосовно PHP, то в попередніх до PHP 5 версіях використовується в основному процедурне програмування, так як об'єктна схема там вимальована достатньо умовно (тільки для виділення окремих сутностей, їх методів і властивостей в певні класи). Вже в 5-й версії PHP механізм взаємодії з об'єктами зазнав еволюційних змін. Вказівники і клонування. Одною з базових змін є передача об'єкту як параметр функції по вказівнику а не по значенню, тобто всі функції, яким параметром передався об'єкт, працюють з одним і тим самим об'єктом, а не з його копіями. Це дозволяє уникати появи дублікатів об'єктів. Похідною від цього нововведення є вища продуктивність при обробці сценаріїв де активно використовуються об'єкти.

Для створення копії об'єкта в PHP 5 використовується спеціальний метод __clone(). До цього методу неможна звернутись безпосередньо. Для безпосереднього використання використовується ключове слово clone.

Розглянемо приклад використання цього методу в PHP 5: <?php class SomeClass{

 var $name;

}

// створюємо клас someObj1 і присвоюємо властивісті “name” значення “Object 1” $someObj1 = new SomeClass; $someObj1->name = 'Object 1';

// копіюємо клас someObj1 в someObj2 $someObj2 = clone $someObj1;

echo $someObj1->name; // Виводить “Object 1” echo $someObj2->name; // Виводить “Object 1”

// присвоюємо властивісті класу someObj2 “name” значення “Object 2” $someObj2->name = 'Object 2';

echo $someObj1->name; // Виводить “Object 1” echo $someObj2->name; // Виводить “Object 2” ?>

В PHP 4 для копіювання об'єкту замість $someObj2 = clone $someObj1 треба було б використати $someObj2 = $someObj1.

На перший погляд все зручніше виглядало в PHP 4, але не будемо поспішати з висновками. Метод __clone() не обов'язково описувати (перезавантажувати) в класі. Але якщо ми це зробимо, то зможемо наперед задати поведінку об'єкта під час його клонування.

Приклад: <?php class SomeClass{

 var $name;

 // перезавантаження методу __clone()
 function __clone() {
   $this->name = 'Copy';
 }

}

// створюємо клас someObj1 і присвоюємо властивісті “name” значення “Original” $someObj1 = new SomeClass; $someObj1->name = 'Original';

// створюємо клас someObj2 // автоматично властивості “name” присвоюється значення “Copy” $someObj2 = clone $someObj1;

echo $someObj1->name; // Виводить “Original” echo $someObj2->name; // Виводить “Copy” ?> Області видимості методів і властивостей класів. В 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 |'

?>