Классы и объекты в PHP
Объект – это структурированная переменная, содержащая всю информацию о некотором физическом предмете или реализуемом в программе понятии, класс – это описание таких объектов и действий, которые можно с ними выполнять.
В PHP класс определяется с помощью следующего синтаксиса:
class Имя_класса{ var $имя_свойства; /*список свойств*/ function имя_метода( ){ /* определение метода */ } /*список методов*/ } |
Внутри определения класса можно использовать ключевое слово this для обращения к текущему представителю класса.
Пример
Определение класса, описывающего категории статей, имеющих такие свойства, как название, автор и краткое содержание.
<? class Articles { // Создаем класс Статей var $title; var $author; var $description; // метод, который присваивает значения атрибутам класса function make_article($t, $a, $d){ $this->title = $t; $this->author = $a; $this->description = $d; } //метод для отображения экземпляров класса function show_article(){ $art = $this->title . "<br>" . $this->description . "<br>Автор: " . $this->author; echo $art; } } ?> |
Инициализация переменных
В PHP4 можно инициализировать значения с помощью оператора var или с помощью функции-конструктора. С помощью var можно инициализировать только константные значения. Для задания не константных значений используют функцию-конструктор, которая вызывается автоматически, когда объект конструируется из класса. Функция-конструктор должна иметь имя, совпадающее с именем всего класса, в котором она определена.
Пример
При создании объекта «статья» установим его свойства следующим образом: автора – равным строке «Иванов», название и краткое содержание – соответствующим элементам глобального массива $_POST, а дату публикации статьи – текущей дате.
<? class Articles { // Создаем класс Статей var $title; var $author = "Иванов"; var $description; var $published; // метод, который присваивает значения атрибутам класса function Articles(){ $this->title = $_POST["title"]; $this->description = $_POST["description"]; $this ->published = date("Y-m-d"); } } ?> |
В PHP5 конструктор класса именуется _construct. Кроме того, в PHP5 появились и деструкторы – функции, которые вызываются автоматически перед уничтожением объекта. В PHP5 функция-деструктор должна быть названа _destruct.
Объекты
Класс – это описание данных одного типа, данных типа объект. Классы являются как бы шаблонами для реальных переменных. Переменная нужного типа (объект) создается из класса с помощью оператора new. Создав объект, мы можем применять к нему все методы и получать все свойства, определенные в описании класса. Для этого используют такой синтаксис:
$имя_объекта->название_свойства или $имя_объекта->название_метода(список аргументов).
Заметим, что перед названием свойства или метода знака $ не ставят.
<?php $art = new Articles; // создаем переменную (объект) $art echo ($art ->title); // выводим свойство (название) переменной (объекта) $art $another_art = new Articles; // создаем объект $another_art $another_art->show_article(); // вызываем метод для отображения объекта в браузер ?> |
Переменная в PHP имеет только один знак доллара перед именем, поэтому нельзя писать $art->$title. Эта конструкция будет рассмотрена не как обращение к свойству title объекта $art, а как обращение к свойству, имя которого задано переменной $title (например, $art->»").
<?php $art->title = "Введение в Internet"; // так можно установить значение свойства объекта $art->$title = "Введение в Internet"; // так нельзя установить значение свойства объекта $property = "title"; $art->$property = "Введение в Internet"; // так можно установить значение свойства объекта ?> |
Создавая класс, мы не можем знать, какое имя будет иметь объект этого класса, тем более что объектов может быть много и все могут иметь разные имена. Соответственно мы не знаем, как обращаться к объекту внутри определения класса. Для того чтобы иметь доступ к функциям и переменным внутри определения класса, нужно использовать псевдопеременную $this. Например, $this->title возвращает значение свойства title у текущего объекта данного класса.
Наследование
Любой класс может быть расширением другого класса. Расширяющий (или производный) класс, кроме тех свойств и методов, которые описаны в его определении, имеет все функции и свойства основного (базового класса). В нашем примере класс программистов – расширяющий, а класс всех людей – базовый. Из класса нельзя удалить никакие существующие свойства и функции, класс можно только расширить. Расширяющий класс в PHP4 всегда зависит только от одного базового класса, поскольку множественное наследование
в PHP не поддерживается. Расширяются классы в PHP с помощью ключевого слова extends.
<?php class Person { // определяем класс Личности var $first_name; // имя личности var $last_name; // фамилия личности function make_person($t,$a){ // метод устанавливает значения имени и фамилии объекта $this->first_name = $t; $this->last_name = $a; } function show_person(){ // метод отображает информацию о личности echo ("<p>" . $this->first_name . " " . $this->last_name . "</p>"); } } class Programmer extends Person{ // определяем класс Programmer, расширяющий Person var $langs = array ("Lisp"); // константным массивом задать переменную в var можно function set_lang($new_lang){ // метод добавляет еще один язык к списку известных $this->langs[] = $new_lang; } } ?> |
Создадим объекта класса programmer с помощью конструкции new и используем функции, заданные для класса Person, т.е. устанавливать и получать имя и фамилию программиста и отображать сведения о нем в браузере:
<?php $progr = new Programmer; $progr -> set_lang("PHP"); // методы, определенные для класса Programmer print_r ($progr->langs); // методы, определенные для класса Person $progr->make_person("Bill","Gates"); $progr->show_person(); ?> |
Конструкторы
<?php class Programmer extends Person{ // определяем класс Programmer, расширяющий Person var $langs = array ("Lisp"); function Programmer(){ // этот конструктор будет работать и в PHP3, и в PHP4 $this->make_person("Иван","Петров"); } } ?> |
Здесь функция Programmer() является конструктором, т.е. выполняется сразу после создания любого представителя класса Programmer, задавая ему имя «Иван» и фамилию «Петров».
<?php class Programmer extends Person{ // определяем класс Programmer, расширяющий Person var $langs = array ("Lisp"); function Programmer($n = "Иван", $f = "Петров"){ // это конструктор $this->make_person($n,$f); } } $default_progr = new Programmer(); // создаст программиста Ивана Петрова $new_progr = new Programmer("Вася", "Сидоров"); // создаст программиста Васю Сидорова print_r($new_progr); /* выведет информацию о переменной $new_progr, т.е. свойства объекта и их значения */ ?> |
Оператор ::
Иногда внутри описания класса возникает необходимость сослаться на функции или переменные из базового класса или ссылаться на функции в классе, ни один представитель которого еще не создан. В PHP4 для этого существует специальный оператор «::»
Например, вот так можно вызвать в описании класса Programmer функцию show_name() из базового класса Person и функцию say_hello(), заданную в описании класса Programmer, когда ни один объект этого класса еще не был создан:
<?php class Person { // определяем класс Личности var $first_name; var $last_name; function Person($t,$a){ // конструктор $this->first_name = $t; $this->last_name = $a; } function show_name(){ // метод отображает информацию о личности echo ("Меня зовут, " . $this->first_name . " " . $this->last_name . "!<br>"); } } class Programmer extends Person{ // определяем класс Programmer, расширяющий Person function set_lang($new_lang){ // метод добавляет еще один язык к списку известных $this->langs[] = $new_lang; Person::show_name(); // правильнее писать parent::show_name(); // вызываем функцию из базового класса echo "И я знаю теперь еще и " . $new_lang; } function show_name(){ echo ("Я программист, " . $this->first_name . " " . $this->last_name . "!<br>"); } function say_hello(){ echo "Привет!<br>"; } } Programmer::say_hello(); // вызываем функцию, когда ни один объект ее класса еще не создан $new_progr = new Programmer("Вася","Сидоров"); $new_progr->set_lang("PHP"); ?> |
В результате работы этой программы получим следующее:
Привет!
Меня зовут Вася Сидоров!
И я знаю теперь еще и PHP
С помощью команды Programmer::say_hello(); мы вызываем функцию say_hello класса Programmer как таковую, а не как метод, применяемый к объекту данного класса. В этот момент переменных класса нет. Поэтому функции, вызываемые до создания объекта, не могут пользоваться переменными класса и конструкцией this, но могут пользоваться локальными и глобальными переменными.
В определении класса Programmer мы переопределили функцию show_name(), поэтому вызвать функцию show_name()
из базового класса Person можно только с помощью оператора «::» Вообще говоря, внутри определения класса мы можем вызывать любые методы и свойства, заданные в его базовом классе с помощью обычного $this, если только порожденный класс не переопределяет эти свойства и методы, как в нашем примере.
Объектная модель PHP5
Кроме нового названия для конструкторов и появления деструкторов в PHP5 произошло еще достаточно много изменений.
Некоторые из них:
- Передача значений параметров класса и присвоение объектов происходит по ссылке, а не по значению, как это было в PHP4.
- В PHP5 если создаются две равные переменные типа объект, то они указывают на одно значение и изменяются одновременно
- механизм создания копий — клонирование. - В PHP4 все методы и переменные класса доступны извне, т.е. они всегда являются открытыми.
В PHP5 переменные и методы можно делать открытыми (доступными отовсюду),
закрытыми (доступными только внутри класса) и защищенными (доступными внутри класса и в его производных классах)
Решение задачи
Для начала создадим форму, где пользователь выбирает, что он хочет создать,
– описание статьи или человека (точнее, это будут две формы):
<form action="task1.php"> Создать описание статьи: <input type=submit name=art_create value="Create Article"> </form> <form action="task1.php"> Создать описание личности: <input type=submit name=pers_create value="Create Person"> </form> |
Теперь напишем файл для обработки этих форм. В нем создадим два класса – статьи и личности. У каждого класса имеется метод для инициализации его переменных и метод для отображения объектов данного класса. При решении задачи будут использованы две функции, встроенные в PHP для работы с классами и объектами. Это функция get_class(объект), возвращающая имя класса, экземпляром которого является объект, переданный ей в качестве параметра. И функция get_class_vars(имя класса), которая возвращает массив всех свойств класса и их значений по умолчанию. Аналогично можно получить массив имен всех методов класса: get_class_methods(имя класса)
<?php // Создаем классы Статей и Личностей. Статья имеет заголовок, автора и // описание. Личность имеет имя, фамилию и e-mail class Article { var $title; var $author; var $description; // метод, который присваивает значения атрибутам класса, функция-конструктор function Article($t="Название отсутствует", $a="Автор отсутствует", $d="Описание отсутствует"){ $this->title = $t; $this->author = $a; $this->description = $d; } //метод для отображения экземпляров класса function show(){ $art = "<h2>$this->title</h2><font size=-1>$this->description</font><p>Автор: $this->author</p>"; echo $art; } } // Определение класса Личностей class Person { var $first_name; var $last_name; var $email; //метод, который присваивает значения атрибутам класса, функция-конструктор function Person($t="Имя не введено", $a="Фамилия не введена",$d="Email не указан"){ $this->first_name = $t; $this->last_name = $a; $this->email = $d; } //метод для отображения экземпляров класса function show(){ $art = "<h2>$this->first_name</h2><font size=-1>$this->last_name</font><p>Автор: $this->email</p>"; echo $art; } } // Далее следует собственно создание и отображение экземпляров выбранного класса if (isset($_GET["art_create"])){ //Если была выбрана статья $art = new Article; // создаем представителя класса статей $art_vars = get_class_vars(get_class($art)); //какие аргументы этого класса нужно задать Make_form($art,$art_vars,"art_create"); //вызов функции // создания формы if (isset($_GET["create_real"])){ Show_($art_vars); } // если данные этой формы отправлены, то вызываем функцию показа } //то же самое, если была выбрана личность if (isset($_GET["pers_create"])){ $art = new Person; $art_vars = get_class_vars(get_class($art)); Make_form($art,$art_vars,"pers_create"); if (isset($_GET["create_real"])){ Show_($art_vars); } } // функция создания формы function Make_form($art,$art_vars,$glob){ $str = "<form>"; // html код формы записывается в строчную переменную $str //перебираем список переменных класса объекта $art foreach ($art_vars as $var_name => $var_value){ $str .="$var_name<input type=text name=$var_name><br>"; //создаем элемент формы с именем свойства класса } $str .= "<input type=hidden name=$glob>"; // чтобы не забыть, что мы создаем $str .= "<input type=submit name=create_real value='Create and Show'></form>"; echo "$str"; // выводим форму } // функция показа объекта function Show_($art_vars){ global $art; //используется глобальное имя объекта $k = count($art_vars); //число свойств класса (переменных в форме) $p=0; //вспомогательная переменная foreach ($art_vars as $name => $value){ $p++; if ($_GET["$name"]=="") $val= $art->$name; else $val = $_GET["$name"]; if ($p<>$k) $par .='"'. $val.'",'; else $par .='"'. $val.'"'; } $const=get_class($art); $par = '$art->'.$const ."(" .$par.");"; // теперь $par представляет собой php-код для вызова // метода класса $art, изначально записанного в $par например, // $art->Person('Vasia','Petrov','vas@intuit.ru'); eval($par); // функция eval выполняет код, // содержащийся в $par $art->show(); } ?> |
Мегареспект Вам, братья! Даже не представляете, что за чудо эта статья!
зачем простые вещи объяснять так сложно?
зачем такие сложные примеры?..
не понятно.
тема статьи — Объекты и классы в PHP
а примеры включают в себя кучу тем. От инициализации переменных до выполнения кода в коде. мрак.
не понравилось.
Андрей, статья позаимствована с интуита сто лет назад, мне и самому она сейчас «не очень» , так что держу в паблике можно сказать для истории.
Очень запутанное и заумное определение объекта. А вот еще определение «Объект — это совокупность данных (свойств) и функций (методов) для их обработки. Данные и методы называются членами класса. Вообще, объектом является все то, что поддерживает инкапсуляцию.»- с PHP.su. Тоже еще не дано определение инкапсуляции, а уже оно встречается в определении неизвестного понятия.
А как передать две переменные из инпута в функцию класса на другой страничке?
Замечательная, вразумительная статья. Автору спасибо!