Открыть меню    

Классы и объекты PHP, основы

Инициализация класса (создание объекта)

Объект класса - представитель класса, который имеет свое уникальное состояние и поведение.
Для объявления объекта необходимо использовать оператор new:

    Объект = new Имя_класса;

PHP

$myObj = new newClass();

Свойства класса

Свойство – это переменные, хранимые в классе; перед именем свойства ставится один из следующих модификаторов (public, protected, private). Также есть ключевое слово var, но его время ушло (остался в 4-й версии PHP).

Описание свойств

PHP

class newClass {
    public $property1;
    protected $property2 = "value2";
    private $property3;
}

Доступ к свойствам класса

Доступ к свойствам класса за пределами класса реализуется так: объект->имя_свойства; (знак доллара у свойства не ставится!)

PHP

$myObj = new newClass();
$myObj->property1;

Изменение значения свойств

PHP

$myObj->property2 = "Тут меняем значение";

Методы класса

Метод – это функция, определенная внутри класса. У функции по умолчанию стоит модификатор public (то есть его можно не писать перед функцией).

Описание методов

PHP

class newClass {
    function myMethod($var1,$var2){ // по умолчанию это
                                    // общедоступный метод (public)
        // операторы
    }
}

Вызов метода

PHP

$myObj = new newClass();
$myObj->myMethod('v1','v2');

$this

Доступ к свойству класса внутри класса реализуется при помощи оператора($this):
$this-> имя_свойства; (знак доллара у свойства не ставится!)

Доступ к методу класса из другого метода класса также осуществляется с помощью ключевого слова $this.

PHP

class newClass {
    public $property1;
    function myMethod(){
        echo($this->property1); // Вывод значения свойства
    }
    function callMethod(){
        $this->myMethod();  // Вызов метода
    }
}

Конструкторы и деструкторы

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

Деструктор – специальный метод, который автоматически вызывается при удалении объекта. P.s. Порядок удаления объектов не определен, но стоит отметить, что объекты удалятся по завершении кода (порядок удаления объектов определить нельзя), и вызовется метод __destruct. Объект можно удалить принудительно: unset(имя_объекта).

PHP

class newClass {
    public $property;

    function __construct($var){
        $this->property = $var;
        echo "Вызываем конструктор";
    }

    function __destruct(){
        echo "Вызываем деструктор";
    }
}

$obj = new newClass("Значение"); //Вызываем конструктор
unset($obj); //Вызываем деструктора (принудительно)

Псевдо-константы __METHOD__ и __CLASS__

Псевдо-константы __METHOD__ и __CLASS__ . Вместо __METHOD__ будет подставлено: имя_класса::имя_метода; __CLASS__ будет подставлено имя_класса.

PHP

class newClass {
    function myMethod(){
        echo __METHOD__;
    }
    function getClassName(){
        echo __CLASS__;
    }
}
$obj = new newClass();
$obj->myMethod();// newClass::myMethod
$obj->getClassName();// newClass

Новые принципы работы с объектами

Объекты передаются по ссылке, а не по значению

PHP

class newClass {
    public $property;
}
$myObj = new newClass();
$myObj->property = 1;
$myObj2 = $myObj;
$myObj2->property = 2;
print($myObj->property); // Выведет 2
print($myObj2->property); // Выведет 2

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

При клонировании (clone) конструктор не вызывается. Существует специальный метод __clone, который вызывается при клонировании объекта.

Явное копирование объектов

PHP

class newClass {
    public $property;
}

$myObj = new newClass();
$myObj->property = 1;
$myObj2 = clone $myObj; // создаем копию объекта, в 4-й версии php было так: $myObj2 = &$myObj;
// в 5-й версии PHP & с объектами не работает
$myObj2->property = 2;
print($myObj->property); // Печатает 1
print($myObj2->property); // Печатает 2

Наследование(полиморфизм)

Один класс может наследовать другой класс. Для этого существует специальное ключевое слово - extends.

PHP

class Machine {
    public $numWheels = 4;
    function printWheels() { echo $this->numWheels; }
}

class Toyota extends Machine {
    public $country = 'Japan';
    function printCountry() { echo $this->country; }
}

$myMachine = new Toyota();
$myMachine->printWheels();
$myMachine->printCountry();

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

Перегрузка методов – в классе, который наследует другой класс, можно описать такой же метод, который есть в родительском классе, причем вновь описанный метод перезапишет метод родительского класса. Пример:

PHP

class Machine {
    public $numWheels = 4;
    function printWheels() { echo $this->numWheels; }
}
class Toyota extends Machine {

    public $country = 'Japan';
    function printCountry() { echo $this->country; }

    function printWheels() {
        echo "Перегруженный метод printWheels() ";
    }
}
$myMachine = new Toyota();
$myMachine->printWheels();

Parent

parent::имя_метода, данная конструкция позволяет обратиться к родительскому методу.

PHP

class Machine {
    public $numWheels = 4;
    function printWheels() { echo $this->numWheels; }
}
class Toyota extends Machine {
    public $country = 'Japan';

    function printWheels() {
        echo "Перегруженный метод printWheels() ";
        parent:: printWheels();
    }
}

$myMachine = new Toyota();
$myMachine->printWheels();

Модификаторы доступа: public, protected, private

Модификатор Описание
public (общедоступный) позволяет иметь доступ к свойствам и методам классам из любого места
protected (защищенный) позволяет иметь доступ и родительскому (в котором определен сам член класса), и наследуемым классам
private (закрытый) ограничивает область видимости так, что доступ к нему имеет только тот класс, в котором объявлен сам элемент

Модификаторы доступа: как это работает?

PHP

$obj = new newClass();
                echo $obj->public; //ДА
                echo $obj->protected; //НЕТ!
                echo $obj->private; //НЕТ
                $obj->myMethod();

PHP

class newClass {
                    public $public = 1;
                    protected $protected = 2;
                    private $private = 3;
                    function myMethod(){
                        echo $this->public; //ДА
                        echo $this->protected; //ДА
                        echo $this->private; //ДА
                    }
                }

PHP

$obj1 = new NewClass();
                echo $obj1->public; //ДА
                echo $obj1->protected; //НЕТ!
                echo $obj1->private; //НЕТ
                $obj1->newMethod();

PHP

class NewClass extends newClass {
                    function newMethod(){
                        echo $this->protected; //ДА
                        echo $this->private; //НЕТ
                        $this->myMethod();
                    }
                }

Обработка исключений

У нас есть кусок кода, в котором может произойти какая-нибудь ошибка; данный кусок кода помещается в блок под названием try; в том месте, где-может произойти ошибка, ставится ключевое слово throw; для отлова произошедшей ошибки описывается блок catch (ловушка), туда приходит ошибка, с которой мы можем работать.

PHP

try {
    $a = 1;
    $b = 0;
    if($b == 0) throw new Exception("Деление на 0!");
    echo $a/$b;
}
catch(Exception $e){
    echo "Произошла ошибка - ",
    $e->getMessage(), // Выводит сообщение  " в строке ",
    $e->getLine(), // Выводит номер строки " файла ",
    $e->getFile(); // Выводит имя файла
}

Создание собственных исключений

PHP

сlass MathException extends Exception {
    function __construct($message) {
        parent::__construct($message);
    }
}
try {
    $a = 1;
    $b = 0;
    // MathException - имя класса  для создания собственного исключения
    if ($b == 0) throw new MathException("Деление на 0!");
    echo $a / $b;
} catch (MathException $e) {
    echo "Произошла математическая ошибка ",
    $e->getMessage(),
    " в строке ", $e->getLine(),
    " файла ", $e->getFile();
}

Перебор свойств объекта

PHP

class Person {
    public $name;
    public $yearOfBorn;
    function __construct($name, $yearOfBorn){
        $this->name = $name;
        $this->yearOfBorn = $yearOfBorn;
    }
}
$billGates = new Person(‘Bill Gates’,1955);
foreach($billGates as $name=>$value){
    print($name.’: ’.$value.’
’); }

Константы класса

Константы – это константы класса, то есть они не принадлежат ни одному объекту. За пределами кода к константе можно обратиться следующим образом: имя_класса::имя_константы. Если мы хотим обратиться к константе в пределах класса, то нужно использовать ключевое слово self: self::имя_константы.

PHP

class Person {
    const HANDS = 2;
    function printHands(){
        print (self::HANDS);// NOT $this! Обращаемся к константе внутри класса
    }
}
print ('Количество рук: '.Person::HANDS); // Обращаемся к константе за пределами класса

Абстрактные методы и классы

Абстрактный класс в php - это так называемый базовый класс, не предназначенный для создания его экземпляров (объектов). Основной смысл и назначение абстрактных классов заключается в расширении возможностей его дочерних классов.

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

В абстрактном классе могут быть абстрактные методы (перед function стоит ключевое слово abstract). Абстрактный метод – это метод без реализации (отсутствуют фигурный скобки).

Абстрактный метод обязательно должен быть описан (перезагружен) в классе-наследнике. Преимущество в использовании абстрактных методов: для каждого класса-наследника можно описать свое уникальное поведение абстрактного метода.

PHP

abstract class Machine {  // абстрактный класс
    public $petrol;
    function startEngine(){
        print('Двигатель зав?лся!');
    }
    abstract function stopEngine();
}
class InjectorMachine extends Machine {
    public function stopEngine(){
        print('Двигатель остановился!');
    }
}
$myMegaMachine = new Machine();//Ошибка!
$myMegaMachine = new InjectorMachine();
$myMegaMachine->startEngine();
$myMegaMachine->stopEngine();

Интерфейсы

Существует еще один тип абстрактного класса – интерфейс. Интерфейс – это абстрактный класс, который содержит только абстрактные методы. Перед таким классом вместо слова abstract пишется interface. От интерфейса наследование происходит не через ключевое слово extends, а через ключевое слово implements.

PHP

interface Hand {
    function useKeyboard();
    function touchNose();
}
interface Foot {
    function runFast();
    function playFootball();
}

class Person implements Hand
{
    public function useKeyboard(){
        echo 'Use keyboard!';
    }
    public function touchNose(){
        echo 'Touch nose!';
    }
    public function runFast(){
        echo 'Run fast!';
    }
    public function playFootball(){
        echo 'Play football!';
    }
}
$vasyaPupkin = new Person();
$vasyaPupkin->touchNose();

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

Перед методом ставится ключевое слово final, этим мы запрещаем перезагружать (перезаписывать) данный метод. Класс также можно объявить финальным.

PHP

class Mathematics {
    final function countSum($a,$b){
        print('Сумма: ' . $a + $b);
    }
}
class Algebra extends Mathematics {
    // Возникнет ошибка
    public function countSum($a,$b){
        $c = $a + $b;
        print("Сумма $a и $b: $c");
    }
}

PHP

final class Breakfast { // финальный класс
    function eatFood($food){
        print("Скушали $food!");
    }
}
// Возникнет ошибка
class McBreakfast extends Breakfast
{
    // Описание класса
}

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

Статические методы и свойства класса (плюс константы класса) принадлежат классу, то есть они общие для всех объектов класса. К ним нельзя обратиться посредством ‛стрелки‛, а только через :: (внутри класса используется: self::$имя_свойства; за пределами класса: имя_класса::$имя_свойства). Статическое свойство, как и метод, объявляется через ключевое слово static. Как вы догадываетесь, внутри статического метода this использовать нельзя (такие методы не связаны с объектами).

PHP

class CookieLover {
    static $loversCount = 0; // это статическое свойство, и компилятор не
                             // будет его удалять после завершения работы  функции __construct

    function __construct(){
        ++self::$loversCount;
    }

    static function welcome(){
        echo 'Добро пожаловать в клуб любителей булочек!';
        //Никаких $this внутри статического метода!
    }
}

$vasyaPupkin = new CookieLover();
$frosyaBurlakova = new CookieLover();
print ('Текущее количество любителей булочек: '.CookieLover::$loversCount);
print (CookieLover::welcome());

Ключевое слово instanceof

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

PHP

class Person {}
$myBoss = new Person();
if($myBoss instanceOf Person) print('Мой Босс – человек!');
// вернет true, если класс Person есть в предках объекта $myBoss

class Woman extends Person {}
$englishQueen = new Woman();

if($englishQueen instanceOf Person) print('Английская королева – тоже человек!');

interface LotsOfMoney {}
class ReachPeople implements LotsOfMoney {}
$billGates = new ReachPeople();

if($billGates instanceOf LotsOfMoney) print('У Билла Гейтса много денег!');

Функция __autoload()

Если PHP натыкается на несуществующий класс, при инициализации объекта, то он ищет функцию __autoload, передавая в функцию __autoload имя неназванного класса. И PHP вызовет эту функцию перед выводом ошибки об отсутствии класса.

PHP

function __autoload($cl_name){ // $cl_name - имя не найденного класса
    print('Попытка создать объект класса '.$cl_name);
}
$obj = new undefinedClass();

Методы доступа к свойствам объекта

Метод __set() будет выполнен при записи данных в недоступные свойства (которых нет в классе).

Метод __get() будет выполнен при чтении данных из недоступных свойств (которых нет в классе).

PHP

class newClass {
    private $properties;
    function __get($name){
        print("Чтение значения свойства $name");
        return $this->properties[$name];
    }
    function __set($name,$value){ // в нашем случае $name это property, $value равно 1
        print("Задание нового свойства $name = $value");
        $this->properties[$name] = $value;
    }
}

$obj = new newClass;
$obj->property = 1; // Запись нового свойства
$a = $obj->property; // Чтение значения свойства
print $a; // 1

Перегрузка вызова несуществующих методов

Если мы обращаемся к методу которого нет, то PHP ищет метод __call (1-й параметр – это имя несуществующего метода, 2-й – массив аргументов).

PHP

class newClass {
    function __call($name, $params){
        print("Попытка вызова метода $name со следующими параметрами: ");
        print_r($params);
    }
}

$obj = new newClass();
$obj->megaMethod(1,2,3,"четыре");

Метод __toString()

Метод __toString() позволяет классу решать самостоятельно, как он должен реагировать при преобразовании в строку. Например, что напечатает echo $obj;. Этот метод должен возвращать строку, иначе выдастся неисправимая ошибка E_RECOVERABLE_ERROR.

PHP

class newClass {
    function __toString(){
        return 'Вызван метод __toString()';
    }
}

$obj = new newClass();
// Вызван метод __toString()
echo $obj;

Комментарии к статье

аватарка пользователя
2014-04-16
lavrik-v.ru

Зачетище!!!! Статья краткая, но безумно содержательная... В закладки!!!

аватарка пользователя
2014-04-16
lavrik-v.ru

Хотя подумал сейчас и понял что не хватает информации о трейтах....

аватарка пользователя
2015-12-09
Logan22

Отличная статья, всё очень кратно и по полочкам.
Хорошо подана информация, мне понравилось, добавил в закладки.

аватарка пользователя
2016-05-19
Evhenii

Спасибо, кратко и понятно

аватарка пользователя
2016-08-08
Zamir

Респект за статью!

аватарка пользователя
2017-02-18
maks

круто!!! можно дополнять статью еще чем-нибудь новым.

аватарка пользователя
2017-04-21
bmcoder

отличная статья, Автору зачёт :)

аватарка пользователя
2017-12-03
Djo

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

аватарка пользователя
2018-02-05
cldr.ru

спасибо, все что нужно в одном месте

аватарка пользователя
2018-02-10
Руслан

Лучшая статья которую я видел в поиске. Спасибо автору!

аватарка пользователя
2018-02-10
Руслан

Лучшая статья которую я видел в поиске. Спасибо автору!

аватарка пользователя
2018-02-21
уставший мустанг

крутая статья - четко грамотно и понятно

аватарка пользователя
2018-08-17
Влад

Неплохо, спасибо!

аватарка пользователя
2018-11-02
Robert

В интерфейсах неточность. Может ввести в заблуждение. Интерфейса два (hand,foot) а в имплементах только hand.

аватарка пользователя
2019-12-25
Robert

В интерфейсах неточность. Может ввести в заблуждение. Интерфейса два (hand,foot) а в имплементах только hand.

аватарка пользователя
2020-12-18
Сергей

СПАСИБО! БОЛЬШОЕ ЧЕЛОВЕЧЕСКОЕ!

заказать сайт