Статические поля класса
Мы рассмотрели статические переменные в статье PHP Variable Scope: All You Need to Know. Как обычная локальная переменная, статическая переменная доступна только в пределах функции. Тем не менее, в отличие от обычных локальных, статические переменные сохраняют значения между вызовами функции.
Статические поля класса работают по такому же принципу. Статическое поле класса связано со своим классом, однако оно сохраняет свое значение на протяжении всей работы скрипта. Сравните это с обычными полями: они связаны с определенным объектом, и они теряются при удалении этого объекта.
Статические поля полезны в случаях, когда вам нужно хранить определенное значение, относящееся ко всему классу, а не к отдельному объекту. Они похожи на глобальные переменные класса.
Чтобы создать статическую переменную, добавьте ключевое слово static в ее задании:
class MyClass { public static $myProperty; }
Вот пример того, как работают статические переменные:
class Member { private $username; public static $numMembers = 0; public function __construct( $username ) { $this->username = $username; self::$numMembers++; } } echo Member::$numMembers . "<br>"; // отобразит "0" $aMember = new Member( "fred" ); echo Member::$numMembers . "<br>"; // отобразит "1" $anotherMember = new Member( "mary" ); echo Member::$numMembers . "<br>"; // отобразит "2"
Есть несколько интересных вещей, так что давайте разберем данный скрипт:
- В классе Member два поля: частное поле $username и статическое $numMembers, которое изначально получает значение 0;
- Конструктор получает в качестве параметра аргумент $username и устанавливает полю только что созданного объекта значение этого параметра. В то же время, он инкрементирует значение поля $numMembers, тем самым давая понять, что число объектов нашего класса увеличилось на 1.
Отметьте, что конструктор обращается к статическому полю так: self::$numMembers. Ключевое слово self похоже на $this, которое мы рассмотрели в прошлом уроке. Тогда как $this ссылается на текущий объект, self — на текущий класс. Также тогда как для получения доступа к полям и методам объекта вы используете ->, то в этом случае используйте :: для получения доступа к полям и методам класса.
В завершении скрипт создает несколько объектов класса Member и отображает на странице их количество, т.е. значение статической переменной $numMembers. Отметьте, что данная переменная сохраняет свое значение на протяжении всей работы скрипта, несмотря на объекты класса.
Итак, чтобы получить доступ к статическому полю класса, применяйте оператор ::. Здесь мы не можем воспользоваться ключевым словом self, так как код находится за пределами класса, поэтому мы пишем имя класса, затем ::, а затем имя поля (Member::$numMembers). В пределах конструктора тоже нужно использовать именно такую структуру, а не self.
На заметку: нашему скрипту ничего не стоило получить доступ к полю класса $numMembers перед тем, как создался первый объект данного класса. Нет необходимости создавать объекты класса для того, чтобы пользоваться его статическими полями.
Как создать класс и объект?
В классе мы сгруппируем код, который обрабатывает определенную тему. Таким образом, для именования класса мы должны использовать единственное существительное типа Car, которое будет обрабатывать логику об автомобилях.
Синтаксис создания класса очень прост и понятен. Вы должны использовать ключевое слово class для объявления класса, за которым следует имя класса.
<?php class Car { // Свойства и методы класса } ?>
- Объявите класс, используя ключевое слово class.
- Используйте существительное единственного числа и используйте первую букву.
- Если имя класса содержит более одного слова, тогда каждое слово пишется с заглавной буквы, используя написание в так называемом стиле CamelCase. Например: JapaneseCar, AmericanCar.
- Экземпляр класса — это объект, созданный из существующего класса.
- new используется для создания объекта из класса.
Теперь вы можете очень легко создать объект из класса, используя ключевое слово new.
Таким образом, сложив все это вместе:
<?php class Car { // Свойства и методы класса } $bmw = new Car; ?>
PHP для мобильных приложений
Главная цель мобильного приложения — вовлечение пользователей или партнеров в ваш бизнес. Здесь персонализация клиентского опыта и создание правильного контекста имеют огромное значение. Поэтому сегодня можно встретить мало самодостаточных приложений, и большинство из них опираются на бэк-энд сервисы. Серверная часть приложения отвечает за объединение различных данных с мобильного устройства, паттернов поведения пользователей, за сохранение настроек пользователей и т.д. Несколько фреймворков PHP, среди которых Symfony и Laravel, весьма неплохо подходят для создания бэк-энда мобильных приложений.
Например, создавая приложение для студентов, желающих подготовиться к экзаменам SAT и ACT, мы использовали Symfony в качестве основы для разработки. Такое решение было принято, поскольку этот фреймворк лучше всего подходит для разработки REST API, который в нашем случае был разработан на архитектуре HATEAOS. В комбинации с несколькими другими техниками, которые базируются на разных языках был создан хорошо работающий продукт.
15.13. Namespace
В PHP пространства имён используются для решения двух проблем, с которыми сталкиваются авторы библиотек и приложений при создании повторно используемых элементов кода, таких как классы и функции:
- Конфликт имён между вашим кодом и внутренними классами/функциями/константами PHP или сторонними.
- Возможность создавать псевдонимы (или сокращения) для Ну_Очень_Длинных_Имён, чтобы облегчить первую проблему и улучшить читаемость исходного кода.
Пространства имён PHP предоставляют возможность группировать логически связанные классы, интерфейсы, функции и константы.
Пример
Для класса Page из файла укажем пространство имен Admin:
<?php namespace Admin; class Page { }
А для класса Page из файла файл укажем пространство имен Users:
<?php namespace Users; class Page { }
Давайте теперь в файле создадим объект одного и второго класса Page:
<?php require_once '/admin/page.php'; require_once '/users/page.php'; $adminPage = new \Admin\Page(); $usersPage = new \Users\Page();
Конструкция
Конструкция позволяет подключить класс по его полному имени, и после этого можно будет обращаться к этому классу просто по имени класса.
Можно использовать псевдонимы для классов с помощью конструкции . Это полезно, если вы хотите использовать классы с одинаковыми именами из разных неймспейсов
Пример
<?php namespace \Core\Admin; class Data { public function __construct($num) { } }
<?php namespace Users; use \Core\Admin\Data; // подключаем класс use \Core\User\Data as UserData; // подключаем класс class Page extends Controller { public function __construct() { $data1 = new Data('1'); // вызываем просто по имени $data2 = new UserData('2'); // вызываем просто по имени } }
0.1.2 Объявление переменных
Есть два объявления,Один — это окончательное объявление для краткого определения, а другой — объявление,Обязательно объявляйте переменные перед их использованием (специально для компилятора), Чтобы объявить переменную, вы должны сначала указать переменнуюСпецификатор декларациис участиемЗаявитель,Иногда также присваивается начальное значение, А затем добавьте точку с запятой.Обратите внимание, что оператор должен быть помещен перед оператором, использующим переменную. Стандарт c более строгий и должен быть помещен в начало программы.
Рассмотрим следующий пример:
Розовый — спецификатор объявления, серый — декларатор (можно записать в правилах).
0.1.2.0 спецификатор объявления Существует три типа спецификаторов объявления: 1、Тип хранилища : Авто, статика, внешний, регистр
(Обратите внимание, что в объявлении указано не более одного типа хранилища, если он есть, его нужно разместить первым) 2、Квалификатор типа:const,volatile,restrict(c99). 3、Спецификатор типа:void,char,float,int,double… На что именно влияют эти символы? Да, это природа переменной, см
Следующую картинку: тип хранилища Тип ограничен спецификатор типа (пустое поле не определено)0.1.2.1 ЗаявительДекларатор включает идентификатор, знак *, который может стоять перед идентификатором, и [] и (), которые могут быть сзади.. Взгляните на следующие примеры.
Выше приведены несколько более распространенных объявлений, давайте посмотрим на следующий пример.
Для этого невидимого утверждения я изучил в книге хороший метод. Этот метод имеет два основных момента: 1、Всегда читайте декларатора изнутри. 2、Делая выбор, всегда делайте [] и () больше, чем* Давайте проанализируем приведенный выше пример: Конечно, для удобства написания также предусмотрено ключевое слово typedef, поэтому я ничего не скажу всем.
Доступ к свойствам
Чтобы получить доступ к объекту нужно использовать оператор «->», следующим образом:
<?php $Объект -> ИмяСвойства ?>
Попробуйте так сделать. Давайте создадим скрипт, который объявляет класс User и его свойства, создает новые объекты User, а затем устанавливает и считывает свойство username:
<?php class User { public $username = ""; } $User = new User(); $User->username = "Петя"; echo $User->username; // Выводит "Петя" ?>
Если вы запустите указанный выше код, то в результате будет выведена строка «Петя», которая является значением свойства $User->username. Как можно заметить, свойство объекта используется обычная переменная. Можно прочитать его значение и присвоить ему новое.
Константы языка PHP для чайников
- Константой называется именованная величина, которая не изменяется в процессе выполнения программы (скрипта).
- В отличие от переменных, вы не можете изменять значения констант, которые были им присвоены при их объявлении. Константы удобно использовать для хранения значений, которые не должны изменяться во время работы программы. Константы могут содержать только скалярные данные (логического, целого, плавающего и строкового типов).
- В РНР константы определяются функцией define(). Вот ее синтаксис:
define($name, $value, $case_sen);
$name — имя константы.
$value — значение константы.
$case_sen — необязательный параметр логического типа, указывающий, следует ли учитывать регистр букв (true) или нет (false).
define("pi",3.14,true); echo pi; //Выводит 3.14
- Для проверки существования константы можно использовать функцию defined(). Данная функция возвращает true, если константа объявлена. Пример:
//Объявляем константу pi define("pi",3.14,true); if (defined("pi")==true) echo "Константа pi объявлена!"; //Скрипт выведет 'Константа pi объявлена!'
Как определить свойства в классе?
Для добавления и сохранения данных в классе используются свойства или переменные-члены. Свойства могут хранить значения типов данных — строковые, целые и десятичные числа, логические значения и т. д. Они точно так же, как обычные переменные, но они связаны с экземпляром объекта, и, таким образом, вы можете получить доступ к переменной только с помощью объекта.
Давайте добавим некоторые свойства в класс Car.
<?php class Car { public $color = 'Красный'; public $numberOfTires = 4; } $bmw = new Car; ?>
- Мы использовали ключевое слово перед свойством класса, чтобы определить видимость свойства, о котором мы поговорим позже.
- Свойство класса может иметь значение по умолчанию. Также вы можете пропустить значение по умолчанию.
Здесь вы можете видеть, что мы добавили некоторые свойства, которые необходимы для каждого объекта автомобиля. Очевидно, что классу автомобиля нужно намного больше свойств, чем это, но для примера думаю этого достаточно.
Теперь, чтобы прочитать любое свойство, получите доступ к свойству, используя объект. Например:
echo $bmw->color;
Стрелка () является конструкцией ООП, которая обращается к свойствам и методам данного объекта.
Как объявить параметр по умолчанию в конструкторе?
Как вы читали выше, конструктор может иметь несколько параметров, которые предоставляются при создании объекта с его использованием. Но если вы хотите сделать параметры необязательными для предоставления при создании объекта, вы можете установить значение по умолчанию для параметра конструктора. Например.
- В приведенном выше примере $ y присвоено значение по умолчанию 0.
- Если объект $ obj = new class (2) создан, значение y по умолчанию будет установлено конструктором равным 0.
разрушитель
Основная цель деструктора — уничтожить или удалить объект из памяти после остановки выполнения программы или завершения процесса.
В PHP вам не нужно вызывать деструктор для освобождения памяти, занятой объектами, потому что он автоматически вызывает деструктор для удаления всех объектов после того, как скрипт останавливает свое выполнение.
Однако вы можете объявить деструктор, чтобы напечатать какое-то сообщение, которое поможет вам проверить или проверить, когда деструктор вызовет и какая обработка выполняется внутри деструктора.
Посмотрите на следующий пример объявления деструктора в PHP
В приведенном выше примере. создаем объект с помощью конструктора.
Мы печатаем какое-то сообщение внутри метода desctruct.
Протестируйте, запустив скрипт
Обратите внимание на вывод сценария для сообщения внутри деструкта.
15.7. Магические методы
Метод будет выполнен при записи данных в недоступные (защищённые или приватные) или несуществующие свойства.
Метод будет выполнен при чтении данных из недоступных (защищённых или приватных) или несуществующих свойств.
Метод запускается при вызове недоступных методов в контексте объект.
Метод позволяет классу решать, как он должен реагировать при преобразовании в строку. Например, что вывести при выполнении .
Полный список магических методов:
Пример
<?php class Test { //установка значения методом __set сработает и если поля совсем не объявлены, //и если они объявлены приватными private $prop1; private $prop2; public function __set($property, $value) { $this->$property = $value; // устанавливаем значение } // Магический геттер свойств: public function __get($property) { return $this->$property; } public function __call($arg) { } public function __toString() { return "Test class"; } }
<?php $test = new Test; $test->prop1 = 1; // запишем 1 $test->prop2 = 2; // запишем 2 echo $test->prop1; // выведет 1 echo $test->prop2; // выведет 2 $test->myMethod(); echo $test;//выведет "Test class"
Основы
Когда вы попытаетесь создать экземпляр класса с приватным конструктором, вы получите фатальную ошибку, аналогично тому, если бы вы пытались вызвать любой другой приватный метод объекта.
Однако, при таком подходе, путём наследования, можно переопределить родительский конструктор, и открыть его для клиентского кода. Это означает, что класс может по-прежнему создаваться людьми, использующими его снаружи, если он только не объявлен как , что подразумевает отсутствие возможности наследования.
Если унаследованный класс определяет свой собственный конструктор, оригинальный, приватный, не будет вызван.
Поскольку приватный метод всё ещё можно вызвать из исходного класса, в котором он определён, единственный способ вызвать приватный конструктор — это создать статический метод, который не требует экземпляра объекта для его выполнения.
Теперь, когда мы ознакомились с фундаментальными понятиями того, как мы можем взаимодействовать с приватными конструкторами в PHP, давайте наконец-то узнает, зачем нужен приватный конструктор в PHP и рассмотрим некоторые шаблоны, в которых он используется, и которые, благодаря ему, можно реализовать.
Конструктор:
Это предопределённый метод, который вызывается во время создания объекта класса, вы можете, к примеру, выводить на экран надпись или свойство.
Важно:
Конструктор и деструкторr они вызываются автоматически, при создание и удаление объекта.
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Создаём класс User classUser{ // Объявление свойства name public$name=»Ваня»; // Конструктор класса publicfunction__construct(){ echo$this->name; } } $user=newUser(); |
Как видите, мы больше не какой метод для вывода не используем или само свойство тоже не выводим, оно выводится во время объявления метода класса, так как именно в конструкторе прописали, что должно выводится свойство .
Также конструкторы созданы для того, что бы давать значение свойствам, для этого в круглых скобках конструктора пишем параметры, как у функции, в самом конструкторе, свойствам присваиваем эти параметры.
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Создаём класс User classUser{ // Объявление свойства name public$name; // Конструктор класса publicfunction__construct($name,$surname){ $this->name=$name; $this->surname=$surname; $this->show_name(); } // Метод для вывода имени publicfunctionshow_name(){ echo»Имя: «.$this->name.»</br>»; echo»Фамилия: «.$this->surname.»</br>»; } $user=newUser(«Вова»,»Пупкин»); |
Как видите, внутри конструктора могут работать и методы, мы туда поместили метод, который выводит на экран имя и фамилию, он тоже будет запускаться во время объявления объекта, вот результат программы.
Как видите всё работает.
В принципе, на этом этапе учебника про конструкторы особо не чего сказать, ещё подробнее о них будет в других частях про ООП.
«Волшебные» константы
И в заключении вспомним про особые константы PHP…
В PHP есть девять волшебных констант, которые меняют свое значение в зависимости от контекста, в котором они используются. Например, значение __LINE__ зависит от строки в скрипте, на которой эта константа указана. Все «волшебные» константы разрешаются во время компиляции, в отличии от обычных констант, которые разрешаются во время исполнения. Специальные константы нечувствительны к регистру и их список приведен ниже:
Константа | Описание |
---|---|
__LINE__ | Текущий номер строки в файле. |
__FILE__ | Полный путь и имя текущего файла, в котором вызывается константа. |
__DIR__ | PHP 5.3.0. Директория файла, в котором используется константа. То же самое что dirname(__FILE__). Не имеет слэша в конце, кроме корневой директории. |
__FUNCTION__ | Имя функции. |
__CLASS__ | Имя класса. Это имя содержит название пространства имен, в котором класс был объявлен (например, Foo\Bar). Также работает в трейтах. При использовании в методах трейтов является именем класса, в котором эти методы используется. |
__TRAIT__ | PHP 5.4.0. Имя трейта. Это имя содержит название пространства имен, в котором трейт был объявлен (например, Foo\Bar). |
__METHOD__ | Имя метода класса. |
__NAMESPACE__ | PHP 5.3.0. Имя текущего пространства имен. |
ClassName::class | PHP 5.5.0. Полное имя класса (с указанием пространства имен). Также смотрите ::class. |
Конструктор и деструктор
В PHP есть несколько методов, известных как магические методы. Среди них два наиболее важных магических метода — и . Эти два метода создания конструктора и деструктора для класса. Помните, магические методы всегда начинаются с двух подчеркиваний.
Что такое конструктор и деструктор?
Метод — это метод, который вызывается классом при создании объекта. Он используется для подготовки нового объекта к использованию. Конструкторы можно использовать для назначения значений параметров свойствам объекта.
Метод — это функция, которая вызывается классом при уничтожении объекта. Обычно используется для очистки памяти при уничтожении объекта.
Мы создадим конструктор для установки значения свойства .
<?php class Car { public $color = 'Красный'; public $numberOfTires = 4; public function __construct($color) { $this->color = $color; } public function setColor($val) { $this->color = $val; } public function getColor() { return $this->color; } } $bmw = new Car("Белый"); echo $bmw->getColor(); // это напечатает "белый", потому что наш конструктор присвоил значение "Белый" свойству color $bmw->setColor("Черный"); // это заменит свойство color на черный echo $bmw->getColor(); ?>
В приведенном выше примере мы создали конструктор, который принимает один аргумент для цвета и устанавливает его для свойства цвета. Мы также изменили наш код создания объекта и передали значение для свойства .
Помните, что когда мы создали конструктор для переопределения конструктора PHP по умолчанию, нам нужно передать параметр конструктору.
Если вы попробуете — это выдаст ошибку, потому что наш конструктор ожидает один параметр.
Теперь мы создадим деструктор, который будет печатать сообщение при уничтожении объекта.
<?php class Car { public $color = 'Красный'; public $numberOfTires = 4; public function __construct($color) { $this->color = $color; } Public function __destruct() { echo "Объект уничтожен"; } public function setColor($val) { $this->color = $val; } public function getColor() { return $this->color; } } $bmw = new Car("Белый"); echo $bmw->getColor(); // это напечатает "белый", потому что наш конструктор присвоил значение "Белый" свойству color $bmw->setColor("Черный"); // это заменит свойство color на черный echo $bmw->getColor(); ?>
- Метод конструктора — это специальный магический метод, представленный в PHP 5, который позволяет инициализировать свойства объекта или выполнять некоторые действия во время создания объекта.
- Метод деструктора — это особый магический метод, который позволяет выполнять некоторые действия во время разрушения объекта.
- Классы, имеющие метод конструктора, выполняются автоматически при создании или создании объекта.
- Классы, которые имеют метод деструктора, выполняются автоматически при уничтожении объекта.
- Конструктор и деструктор не требуются. Каждый класс PHP имеет конструктор и деструктор по умолчанию. Если вы создаете конструктор или деструктор, он по умолчанию игнорируется автоматически.
- PHP выполняет только один конструктор и один деструктор.
- Метод и начинается с двух подчеркиваний.
15.8. Наследование
Пример
<?php class Person { private $name; private $age; public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function getAge() { return $this->age; } public function setAge($age) { $this->age = $age; } }
<?php class Student extends Person { private $university; public function getUniversity() { return $this->university; } public function setUniversity($university) { $this->university = $university; } }
Обращение к родительскому классу из наследника
Например, мы хотим устанавливать возраст студента только если он больше 16 лет. Для этого мы можем переопределить родительский метод
<?php class Student extends Person { private $university; public function setAge($age) { if ($age >= 16) { parent::setAge($age); // Вызываем метод родителя: } } public function getUniversity() { return $this->university; } public function setUniversity($university) { $this->university = $university; } }
Перезапись конструктора родительского класса
<?php class Person { private $name; private $age; public function __construct($name, $age) { $this->name = $name; $this->age = $age; } }
<?php class Student extends Person { private $university; public function __construct($name, $age, $university) { parent::__construct($name, $age); $this->university = $university; } }
Заключение
В этом уроке вы углубили свои знания по ООП в PHP, рассмотрев более детально поля и методы. Вы изучили:
- Конструкторы и деструкторы, полезные для инициализации полей и очистки памяти после удаления объектов;
- Статические поля и методы, которые работают на уровне класса, а не на уровне объекта;
- Классовые константы, полезные для хранения фиксированных значений, необходимых на уровне класса;
- Явное указание типов, с помощью которого можно лимитировать типы аргументов, передаваемых в метод;
- Волшебные методы __get(), __set() и __call(), которые служат для получения доступа к частным полям и методам класса. Реализация этих методов позволяет вам создавать “виртуальные” поля и методы, которые не существуют в классе, но в то же время, могут быть вызваны.
Со знаниями, полученными в этом и предыдущем уроках, вы можете начать писать на ООП. Но на этом все только начинается! В следующем уроке мы поговорим о силе ООП — способности классов наследовать функциональность от других классов.
Удачного программирования!