работа с классом php
Работа с классом php
Если класс можно рассматривать как тип данных, то объект — как переменную (по аналогии). Скрипт может одновременно работать с несколькими объектами одного класса, как с несколькими переменными.
Внутри объекта данные и код (члены класса) могут быть либо открыты, либо нет. Открытые данные и члены класса являются доступными для других частей программы, которые не являются частью объекта. А вот закрытые данные и члены класса доступны только внутри этого объекта.
Описание классов в PHP начинаются служебным словом class:
Для объявления объекта необходимо использовать оператор new:
Объект = new Имя_класса;
Данные описываются с помощью служебного слова var. Метод описывается так же, как и обыкновенная пользовательская функция. Методу также можно передавать параметры.
Подведем промежуточные итоги: объявление класса должно начинаться с ключевого слова class (подобно тому, как объявление функции начинается с ключевого слова function). Каждому объявлению свойства, содержащегося в классе, должно предшествовать ключевое слово var. Свойства могут относиться к любому типу данных, поддерживаемых в РНР, их можно рассматривать как переменные с небольшими различиями. После объявлений свойств следуют объявления методов, очень похожие на типичные объявления пользовательских функций.
По общепринятым правилам имена классов ООП начинаются с прописной буквы, а все слова в именах методов, кроме первого, начинаются с прописных букв (первое слово начинается со строчной буквы). Разумеется, вы можете использовать любые обозначения, которые сочтете удобными; главное — выберите стандарт и придерживайтесь его.
Пример класса на PHP:
Доступ к класам и объектам в PHP
Мы рассмотрели, каким образом описываются классы и создаются объекты. Теперь нам необходимо получить доступ к членам класса, для этого в PHP предназначен оператор —>. Приведем пример:
Чтобы получить доступ к членам класса внутри класса, необходимо использовать указатель $this, которы всегда относится к текущему объекту. Модифицированный метод Getname():
Таким же образом, можно написать метод Setname():
Теперь для изменения имени можно использовать метод Setname():
А вот и полный листинг кода:
Указатель $this можно также использовать для доступа к методам, а не только для доступа к данным:
Конструкторы
Раньше создание объекта и инициализация свойств выполнялись раздельно. Конструкторы позволяют выполнить эти действия за один этап.
Интересная подробность: в зависимости от количества передаваемых параметров могут вызываться разные конструкторы. В рассмотренном примере объекты класса Webpage могут создаваться двумя способами. Во-первых, вы можете вызвать конструктор, который просто создает объект, но не инициализирует его свойства:
Во-вторых, объект можно создать при помощи конструктора, определенного в классе, — в этом случае вы создаете объект класса Webpage и присваиваете значение его свойству bgcolor:
$page = new Webpage(«brown»);
Деструкторы
Эта команда удаляет из памяти все содержимое $Webpage. Действуя в духе инкапсуляции, можно поместить вызов unset() в метод с именем destroy() и затем вызвать его:
Необходимость в вызове деструкторов возникает лишь при работе с объектами, использующими большой объем ресурсов, поскольку все переменные и объекты автоматически уничтожаются по завершении сценария.
Инициализация объектов
Главное не забыть вызвать функцию сразу после создания объекта, либо вызвать какой-нибудь метод между созданием (оператор new) объекта и его инициализацией (вызовом Init).
Для того, чтобы PHP знал, что определенный метод нужно вызывать автоматически при создании объекта, ему нужно дать имя такое же, как и у класса (Coor):
Метод, инициализирующий объект, называется конструктором. Однако, PHP не имеет деструкторов, поскольку ресурсы освобождаюся автоматически при завершении работы скриптов.
Обращение к элементам классов
Обращение к элементам классов осуществляется с помощью оператора :: «двойное двоеточие». Используя «двойное двоеточие», можно обращаться к методам классов.
При обращении к методам классов, программист должен использовать имена этих классов.
class A <
function example () <
echo «Это первоначальная функция A::example().
» ;
>
>
class B extends A <
function example () <
echo «Это переопределенная функция B::example().
» ;
A :: example ();
>
>
// Не нужно создавать объект класса A.
// Выводит следующее:
// Это первоначальная функция A::example().
A :: example ();
// Создаем объект класса B.
$b = new B ;
В PHP5, используя эту лексему, программист может обращаться к константам, статическим или перегруженным свойствам или методам класса. Подробнее об этом здесь.
Функции работы с классами и объектами
Содержание
User Contributed Notes 19 notes
[Editor’s note: If you are trying to do overriding, then you can just interrogate (perhaps in the method itself) about what class (get_class()) the object belongs to, or if it is a subclass of a particular root class.
You can alway refer to the parent overriden method, see the «Classes and Objects» page of the manual and comments/editor’s notes therein.]
There is no function to determine if a member belongs to a base class or current class eg:
class foo <
function foo () < >
function a () < >
>
class bar extends foo <
function bar () < >
function a () < >
>
lala = new Bar ();
?>
——————
how do we find programmatically if member a now belongs to class Bar or Foo.
To pillepop2003 at yahoo dot de:
I have the same issue. I have a base class that manages database tasks for a number of child classes. One of the functions in the base class is a find() method that returns instances of the child classes. Since find() is usually called as a static method, it needs to know the name of the child class. As you’ve found, this appears to be impossible to get in an easy fashion.
The only way I’ve found to get the child class name is to use the debug_traceback() function. This requires me to have a find() method in every child class, but it does work.
function find () <
return parent :: find ();
>
>
function find () <
return parent :: find ();
>
>
FYI: if you want to split your class into manageble chunks, what means different files for you, you can put you functoins into includes, and make include() have a return value. Like this:
And your included file:
Then your function call will be:
$instance = new Some_class ();
$instance->add_value (3);
And this will return
6
hopefully 😛
Keep in mind though, that the scope in the included file will be identical to the scope the function ‘add_value’ has.
And if you want to return the outcome, you should also have a return statement made in your include as well.
Something I found out just now that comes in very handy for my current project:
it is possible to have a class override itself in any method ( including the constructor ) like this:
in this case assuming that class b is already defined and also has the method ha ( )
note that the code after the statement to override itself is still executed but now applies to the new class
i did not find any information about this behaviour anywhere, so i have no clue wether this is supposed to be like this and if it might change. but it opens a few possibilities in flexible scripting!!
Re: Looking for an uninstantiated class
Why would I do this? Because I have my class layouts the same as their respective tables; the factory then selects the data (making sure that the variables match) and plugs in the data. (I’ve left out the actual code to do the selection/insertion).
To pillepop2003 at yahoo dot de:
It seems to me if there really is no nice way to get the class name in an un-instanciated class, there is a workaround in PHP5 though using static/class variables.
?>
However, you’ll need to have at least instanciated an object of the class myFooExtended before calling getClassName or introduce some other initialization (the class variable will need to be set at some point to __CLASS__ in the sub-class).
If you want to be able to call an instance of a class from within another class, all you need to do is store a reference to the external class as a property of the local class (can use the constructor to pass this to the class), then call the external method like this:
or if the double ‘->’ is too freaky for you, how about:
This is handy if you write something like a general SQL class that you want member functions in other classes to be able to use, but want to keep namespaces separate. Hope that helps someone.
I wanted to dynamically choose an extender for a class. This took awhile of playing with it but I came up with a solution. Note that I can’t verify how safe it is, but it appears to work for me. Perhaps someone else can shed light on the details:
Practical application: I have a database abstraction system that has individual classes for mysql, pgsql, et al. I want to be able to create a global db class that extends one of the individual db classes depending on the application configuration.
I know that there are probably much better ways of doing this but I haven’t reached that level when it comes to classes.
to covertka at muohio dot edu and pillepop2003 at yahoo dot de:
There’s a much easier solution to getting a class’ name for working with a factory function. Let’s assume you’re doing something like this:
?>
Now, consider the named parameter idiom and remember that PHP uses hashes for everything; as a result make the following changes:
?>
Nice ‘n simple. It seems that what the original poster wanted was something like C++ static data members; unfortunately as PHP4 has no static variables at all, there would need to be significant language change to support static-like behavior. If you move to PHP5, the static keyword solves your problem cleanly.
To access an object member with an illegal character in the name, use this syntax:
This is particularly relevant with the dynamically-generated classes used by, for instance, database objects and the SoapClient class.
Subject: using «sql_calc_found_rows» in a MySQL query while exploiting result in a PHP db class object.
There is a nice function in MySQL that allows to know how many records would have been returned if no «where» clause were set : SQL_CALC_FOUND_ROWS.
If you have create a db object to collect the returned lines, you will be a little perplex when trying to call the result of this function.
Then, the only way to get the right result seems to be the use of a class function, like :
A small function that allows finding all references to the object. Written in 3 minutes and may be buggy (for ex pass object as reference in some places?)
Why do u want to know the classname of an non-existant object?
The only possible explanation for this question seems to me u want to know the class before u instantiate the object. Well, this is of no use since u always instantiate a class of ur choice.
When the class is instantiated into an object u can find the class of the object by means of get_class(). This is all u need. In case of inheritance u can use get_class($this) to get the class of the instantiated object. Now u can differentiate according to which class the object belongs to.
$object1 = new A ();
$object2 = new B ();
?>
When u run this code-snippet the output will be:
Object is an instance of class A which is the parent-class.
Object is an instance of class B which is the child-class.
We have an array with many objects in a style like
Because there is no function in php api, we made the following function.
Warning: function is very slow and should only be called if it’s necessary for debugging reasons:
// clean the output-buffer
ob_end_clean ();
// cache the last match
$lastMatch = array();
// the return value
$return = array();
?>
I know, it’s not that elegant but I hope it’s useful for a few people.
Объекты и классы в PHP
Объекты
Объекты в PHP — это просто ещё один тип данных. Объект позволяет хранить в переменной набор из свойств и их значений, а также встроенные функции. Это делает объекты похожими по своей структуре на ассоциативные массивы. Но отличие от массивов всё-таки есть, и при этом достаточно важное — объекты могут иметь внутреннее состояние.
Особенности объектов и их отличия от массивов
Давайте разберёмся, что такое PHP-объект. Как сказано выше, объекты похожи на массивы, но со своими особенностями. Объекты могут содержать отдельные значения, каждое под своим ключом. Эти значения называются свойствами объекта.
Также объекты могут иметь внутри себя функции — их называют методами объекта. Методы могут обращаться к любым свойствам объекта, читать и записывать туда данные.
Значение свойства объекта может быть любого типа: число, строка, массив, другой объект. Но, в отличие от массива, объекты не позволяют добавлять в себя новые значения. То есть объект всегда имеет конечное число своих свойств и методов. Менять значения существующих свойств можно, а удалять и заменять их — нельзя. Что в корне отличается от поведения массива, ведь там добавлять и удалять значения можно в любое время.
Но самая большая особенность объектов — это то, как они создаются. Если массив создается либо пустым, либо сразу с набором значений, то объекты устроены иначе. Дело в том, что объекты не существуют сами по себе. Чтобы создать новый объект, вам придётся вначале создать его описание — класс.
Класс — это как бы чертёж объекта. Класс описывает то, из чего состоит объект. Мы разберёмся с классами чуть позже.
Анатомия объекта
Как же устроен объект изнутри? Его содержимое можно поделить на две группы: свойства и методы.
Свойства могут быть двух видов: публичные и скрытые. К публичным свойствам можно обращаться за пределами объекта, точно так же, как вы обращаетесь к элементам массива по его ключам.
Скрытые свойства не имеют аналогов в массиве. Они доступны для чтения и изменения только внутри самого объекта — и это могут делать его методы.
Вторая группа — это методы объекта.
Набор методов также называется поведением объекта. Как и свойства, методы бывают публичными и скрытыми. Публичные методы объекта можно вызывать из внешнего кода, а скрытые только из самого объекта. Методы способны обращаться к свойствам объекта также просто, как если бы это были их внутренние переменные или аргументы.
Классы
Класс — это шаблон, по которому создаются объекты.
Напомню, что классы — это описания объектов. Мы не можем создать объект «на лету», как это происходит с массивами. Объект может быть создан только на основе своего описания — класса. Этим, кстати, реализация объектов в PHP отличается от JavaScript. В JS объектам не нужны никакие классы, и они могут быть созданы и модифицированы когда угодно и как угодно.
Класс как чертёж
Зачем же нужны классы, и почему объекты не могут существовать без них?
Здесь аналогия очень простая: класс – это чертёж, максимально подробное описание того, как должно выглядеть изделие. Сам по себе класс не является чем-то физическим и осязаемым, то есть мы не можем использовать его в коде непосредственно. Вместо этого класс является схемой, структурой, на основе которой будет создан объект.
Жизненный цикл объекта
Любая работа с объектами в PHP состоит из следующих этапов.
Начинается всё с создания класса. В классе мы фиксируем из каких свойств и методов будет состоять каждый его экземпляр. Также в классе можно задать начальные значения для каждого свойства.
Имея класс, возможно создать его экземпляр — объект.
Классы в PHP принято сохранять в отдельных файлах, поэтому вначале вы подключаете этот сценарий там, где он необходим. Затем вызываете процедуру создания нового объекта на основе этого класса.
Чтобы использовать объект в дальнейшем, его следует, как всегда, назначить переменной. Затем вы будете работать с объектом через переменную: вызывать методы и обращаться к свойствам.
Пример создания объекта на основе класса
Создание объекта на основе класса:
Разбор примера
Разберёмся с тем, что здесь происходит.
Начнём с целей создания данного класса. Его задача — хранить в объекте данные о погоде за конкретный день, а также предоставлять сводку за этот день в текстовом виде.
В классе определено четыре скрытых свойства. Это значит, что к ним не будет доступа за пределами объекта. Читать и записывать эти свойства могут только внутренние методы объекта. Сами свойства хранят температурные параметры (температуру, осадки), дату и дополнительный комментарий к записи. Некоторым свойствам задано значение по умолчанию.
Что такое конструктор объекта
Методы объекта вызываются из внешнего кода, при явном обращении к ним с указанием имени. Но если назвать один метод __construct то он будет вызываться автоматически в момент создания объекта на основе класса.
Конструкторы объектов используются для инициализации каких-либо значений и выполнении других подготовительных операций. В нашем примере конструктор устанавливает содержимое скрытых свойств.
Обращение к свойствам и методам объекта
Посмотрим, как внутри метода происходит обращение к его свойствам.
Во-первых, для этого используется специальная переменная this, которая всегда присутствует внутри объекта и ссылается на него самого.
Во-вторых, для обращения к методам и свойствам объекта нужен специальный синтаксис: «стрелочка». Такая стрелочка отделяет имя свойства или метода от имени объекта. Это аналог квадратных скобок при работе с массивами.
Метод с именем isCold() нужен, чтобы узнать было ли холодно в тот день, основываясь на показаниях температуры в градусах.
Метод setRainStatus() устанавливает логическое значение, которое показывает статус осадков в день наблюдения.
Метод getDayDescription() формирует текстовое описание погоды на заданную дату.
Создание объекта на основе класса
В коде мы передаём в конструктор почти все параметры погодных наблюдений. Затем для созданного объекта вызываются его методы: первый устанавливает значения осадков, а второй возвращает текстовое описание погоды.
Впервые базовая поддержка классов в PHP была введена в 4 версии языка, но затем для более полной поддержки ООП повторно реализована для 5 версии. Сегодня PHP пригоден для работы с классами, но в то же время библиотека языка до сих пор в основном состоит из функций, классы теперь добавляются в различных целях. Тем не менее, основным средством PHP является использование своих собственных классов.
Классы можно рассматривать как совокупность методов, переменных и констант. Они часто отражают реальные предметы, как класс автомобиля или класс фруктов. Вы объявляете класс только один раз, но можете создать множество его экземпляров, которые могут храниться в памяти. Экземпляр класса обычно называют объектом. Если вы все еще немного путаетесь в том, какие классы и зачем они нужны, не волнуйтесь. В этой статье мы напишем наш самый первый класс и используем его.
Классы в PHP — определение и использование
После введения в классы в PHP мы готовы написать наш собственный класс. Он будет содержать информацию об основном пользователе, например, вашего сайта.
На данный момент этот класс PHP ничего не может сделать. Мы можем создать экземпляр, это делается с помощью ключевого слова new :
Попробуем использовать наш новый класс php. Следующий код должен идти после того, как класс был объявлен или подключен:
Результат должен выглядеть следующим образом:
Конструкторы и деструкторы
Конструктор и деструктор — специальные функции, которые автоматически вызываются, когда объект создается и уничтожается. Из них наиболее полезным является конструктор, потому что позволяет при создании нового объекта передавать ему параметры, которые затем используются для инициализации переменных объекта. Вот пример класса с простым конструктором:
Конструктор выглядит как обычная функция, за исключением того, что начинается с двух символов нижнего подчеркивания. В PHP так указывается волшебная функция, которая обладает дополнительной функциональностью по сравнению с обычными функциями. Таким образом, функция типа « __construct «, является конструктором класса и будет вызываться автоматически при создании объекта. Давайте попробуем сделать это в следующем PHP class примере:
С помощью этой строки кода будет создан объект, вызван конструктор и в нем выполнится код, что приведет к выводу строки “ I’m alive! ”. Но как уже упоминалось ранее, основным преимуществом конструктора является возможность передавать параметры, которые могут быть использованы для инициализации переменных – членов класса.
Давайте попробуем сделать это:
Объявление конструктора с параметрами такое же, как объявление функции, и передача параметров очень похожа на вызов обычной функции, но с ключевым словом “ new ”. Конструктор может иметь столько параметров, сколько вам хочется.
Деструкторы
Деструктор вызывается при уничтожении объекта. В некоторых языках программирования нужно вручную избавиться от созданных объектов, но в PHP это делает сборщик мусора, который следит за объектами и автоматически уничтожает их, когда они больше не нужны. Посмотрите на следующий пример, который является расширенной версией предыдущего PHP class :
Как видите, деструктор такой же как конструктор, только имя отличается. Если попробуете запустить этот пример, то сначала увидите сообщение конструктора, а затем название животного, которое мы вручную выводим в последней строке. После этого сценарий заканчивается, объект уничтожается деструктором, и выводится сообщение о нашем бедном умершем животном.
Работа с классом php
Класс может содержать собственные константы, переменные (называемые свойствами) и функции (называемые методами).
Пример #1 Простое определение класса
Результат выполнения данного примера в PHP 7:
Результат выполнения данного примера в PHP 8:
Если с директивой new используется строка ( string ), содержащая имя класса, то будет создан новый экземпляр этого класса. Если имя находится в пространстве имён, то оно должно быть задано полностью.
В случае отсутствия аргументов в конструктор класса, круглые скобки после названия класса можно опустить.
Пример #3 Создание экземпляра класса
Когда происходит присвоение уже существующего экземпляра класса новой переменной, то эта переменная будет указывать на этот же экземпляр класса. То же самое происходит и при передаче экземпляра класса в функцию. Копию уже созданного объекта можно создать через её клонирование.
Пример #4 Присваивание объекта
Результат выполнения данного примера:
Создавать экземпляры объекта можно двумя способами:
Пример #5 Создание новых объектов
class Test
<
static public function getNew ()
<
return new static;
>
>
class Child extends Test
<>
Результат выполнения данного примера:
Обратиться к свойству или методу только что созданного объекта можно с помощью одного выражения:
Пример #6 Доступ к свойствам/методам только что созданного объекта
Результатом выполнения данного примера будет что-то подобное:
Замечание: До PHP 7.1 аргументы не имели значения, если не определена функция конструктора.
Свойства и методы
Пример #7 Доступ к свойству vs. вызов метода
public function bar () <
return ‘метод’ ;
>
>
Результат выполнения данного примера:
Это означает, что вызвать анонимную функцию, присвоенную переменной, напрямую не получится. Вместо этого свойство должно быть назначено, например, переменной. Можно вызвать такое свойство напрямую, заключив его в скобки.
Пример #8 Вызов анонимной функции, содержащейся в свойстве
Результат выполнения данного примера:
extends
Класс может наследовать константы, методы и свойства другого класса используя ключевое слово extends в его объявлении. Невозможно наследовать несколько классов, один класс может наследовать только один базовый класс.
Наследуемые константы, методы и свойства могут быть переопределены (за исключением случаев, когда метод класса объявлен как final) путём объявления их с теми же именами, как и в родительском классе. Существует возможность доступа к переопределённым методам или статическим свойствам путём обращения к ним через parent::
Пример #9 Простое наследование классов
class ExtendClass extends SimpleClass
<
// Переопределение метода родителя
function displayVar ()
<
echo «Расширенный класс\n» ;
parent :: displayVar ();
>
>
Результат выполнения данного примера:
Правила совместимости сигнатуры
Пример #10 Совместимость дочерних методов
Результат выполнения данного примера:
Следующие примеры демонстрируют, что дочерний метод, который удаляет параметр или делает необязательный параметр обязательным, несовместим с родительским методом.
Пример #11 Фатальная ошибка, когда дочерний метод удаляет параметр
class Extend extends Base
<
function foo ()
<
parent :: foo ( 1 );
>
>
Результат выполнения данного примера в PHP 8 аналогичен:
Пример #12 Фатальная ошибка, когда дочерний метод делает необязательный параметр обязательным.
Результат выполнения данного примера в PHP 8 аналогичен:
Переименование параметра метода в дочернем классе не является несовместимостью сигнатуры. Однако это не рекомендуется, так как приведёт к Error во время выполнения, если используются именованные аргументы.
Пример #13 Ошибка при использовании именованных аргументов и параметров, переименованных в дочернем классе
Результатом выполнения данного примера будет что-то подобное:
::class
Пример #14 Разрешение имени класса
namespace NS <
class ClassName <
>
Результат выполнения данного примера:
Разрешение имён класса с использованием ::class происходит на этапе компиляции. Это означает, что на момент создания строки с именем класса автозагрузки класса не происходит. Как следствие, имена классов раскрываются, даже если класс не существует. Ошибка в этом случае не выдаётся.
Пример #15 Отсутствует разрешение имени класса
Результат выполнения данного примера:
Начиная с PHP 8.0.0, константа ::class также может использоваться для объектов. Это разрешение происходит во время выполнения, а не во время компиляции. То же самое, что и при вызове get_class() для объекта.
Пример #16 Разрешение имени объекта
Результат выполнения данного примера:
Методы и свойства Nullsafe
Пример #17 Оператор Nullsafe
Оператор nullsafe лучше всего использовать, когда null считается допустимым и ожидаемым значением для возвращаемого свойства или метода. Для индикации ошибки предпочтительнее выбрасывать исключение.
User Contributed Notes 11 notes
I was confused at first about object assignment, because it’s not quite the same as normal assignment or assignment by reference. But I think I’ve figured out what’s going on.
First, think of variables in PHP as data slots. Each one is a name that points to a data slot that can hold a value that is one of the basic data types: a number, a string, a boolean, etc. When you create a reference, you are making a second name that points at the same data slot. When you assign one variable to another, you are copying the contents of one data slot to another data slot.
Now, the trick is that object instances are not like the basic data types. They cannot be held in the data slots directly. Instead, an object’s «handle» goes in the data slot. This is an identifier that points at one particular instance of an obect. So, the object handle, although not directly visible to the programmer, is one of the basic datatypes.
What makes this tricky is that when you take a variable which holds an object handle, and you assign it to another variable, that other variable gets a copy of the same object handle. This means that both variables can change the state of the same object instance. But they are not references, so if one of the variables is assigned a new value, it does not affect the other variable.