php class called class

Использование ключевого слова ::class в PHP

php class called class. Смотреть фото php class called class. Смотреть картинку php class called class. Картинка про php class called class. Фото php class called class

Если вы уже достаточно продолжительное время работаете с PHP и современными PHP фреймворками, то скорее всего вы уж не раз встречались с ключевым словом ::class. В данной статье мы поговорим, о том, что означает это ключевое слово и где его можно использовать.

При работе с пространствами имен в PHP, часто приходится писать полные имена классов. Особенно это проявляется при работе с современными MVC фреймворками, которые вовсю используют новомодные фишки PHP. Давайте посмотрим на реальный пример.

Ключевое слово класс ::class

Начиная с PHP версии 5.5 ключевое слово ::class используется для разрешения имени класса. Это означает, что оно возвращает полное имя класса, что особенно полезно, при работе с длинными именами классов. Посмотрим на пример:

Реальные примеры применения

Как работает ключевое слово ::class мы увидели. Но где оно может быть применено? Есть несколько случаев, где это ключевое слово может быть полезно. Если вы поищете этого ключевое слово во фреймворке Laravel, вы получите сотни результатов.

Давайте посмотрим, как это ключевое слово может быть применено:

Здесь нам необходимо передать имя класса в метод belongsTo. Здесь-то мы и можем использовать ключевое слово ::class.

Таким образом, мы получаем два преимущества. Во-первых, нужно меньше писать. Во-вторых, поскольку мы не пишем имя класса, как строку, наша среда разработки предоставляет нам мощное средство – автодополнение кода.

Заключение

Когда это уместно, используйте ключевое слово class. Во-первых, ваша работа ускорится и повысится ее качество. Во-вторых, если вы видите что-то, что вы, не совсем понимаете, попробуйте это выяснить. Потратьте некоторое время и покопайтесь в своем фреймворке, проекте или просто языке программирования.

php class called class. Смотреть фото php class called class. Смотреть картинку php class called class. Картинка про php class called class. Фото php class called class

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Комментарии ( 0 ):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

Copyright © 2010-2021 Русаков Михаил Юрьевич. Все права защищены.

Источник

Difference static::class vs get_called_class() and __CLASS__ vs get_class() vs self::class

I’ve seen several threads where people ask how to get the name of a class or an object in PHP. However, I can’t see anywhere the difference between the various possibilities explained. I hope somebody here can help me.

So in order to get the class name of the called class, I know two possibilities:

( get_class($this) for non-static classes)

And for getting the class name of the class in which you put the code, I know these three possibilities:

Are there any differences which I may to overlook right now? What are potential adventages and disadvantages of one way over the other?

2 Answers 2

Differences between

returns the name of the class of an object

It returns a classname including its qualified namespace for the current class (without parameter) or for any specified object instance, when you pass the object instance pointer as the first and only parameter.

A magic constant that returns the qualified namespace and the current class name. Here you can not test for class names of other objects. As per PHP 5.4 it works in traits. That is, when the trait is used in a class it will return the namespace and name of that class.

Only available since PHP 5.5. It uses class name and namespace resolution to obtain the info, as a result it does not need the class to be instantiated beforehand. Also note:

The class name resolution using ::class is a compile time transformation. That means at the time the class name string is created no autoloading has happened yet. As a consequence, class names are expanded even if the class does not exist. No error is issued in that case.

Источник

Подробно об объектах и классах в PHP

Сегодня объекты используются очень активно, хотя это трудно было предположить после выхода PHP 5 в 2005 году. Тогда я ещё мало что знал о возможностях этого языка. Пятую версию PHP сравнивали с предыдущей, четвёртой, и главным преимуществом нового релиза стала новая, очень мощная объектная модель. И сегодня, десять лет спустя, около 90% всего PHP-кода содержит объекты, не изменившиеся со времени PHP 5.0. Это убедительно говорит о том, какую роль сыграло внедрение объектной модели, неоднократно улучшавшейся на протяжении последующих лет. В этом посте я хотел бы рассказать о том, как всё устроено «под капотом». Чтобы люди понимали суть процессов — почему сделано так, а не иначе — и лучше, полнее использовали возможности языка. Также я затрону тему использования памяти объектами, в том числе в сравнении с эквивалентными массивами (когда это возможно).

Я буду рассказывать на примере версии PHP 5.4, и описываемые мной вещи справедливы для 5.5 и 5.6, потому что устройство объектной модели там почти не претерпело изменений. Обратите внимание, что в версии 5.3 всё не так хорошо с точки зрения возможностей и общей производительности.

В PHP 7, который пока ещё активно разрабатывается, объектная модель переработана не сильно, были внесены лишь незначительные изменения. Просто потому что всё и так хорошо работает, а лучшее — враг хорошего. Были добавлены возможности, не затрагивающие ядро, но здесь об этом речи не пойдёт.

В качестве демонстрации начну с синтетических бенчмарков:

Здесь объявляется простой класс с тремя атрибутами, а затем в цикле создаётся 1000 объектов этого класса. Обратите внимание, как в этом примере используется память: при создании объекта класса Foo и переменной для его хранения выделяется 262 байт динамической памяти PHP.

Давайте заменим объект на эквивалентный массив:

Вот ещё один пример:

Теперь давайте разберём, как всё это устроено в недрах PHP, подкрепив теорией практические наблюдения.

Всё начинается с классов

Внутри PHP класс представляется с помощью структуры zend_class_entry:

Важно знать ещё об одном моменте, связанном с zend_class_entry — о PHP-комментариях. Они также известны как аннотации. Это строковые переменные (в языке С — буферы char* ), которые тоже надо разместить в памяти. Для языка С, не использующего Unicode, в отличие от PHP, правило очень простое: один символ = один байт. Чем больше у вас в классе аннотаций, тем больше памяти будет использовано после парсинга.

У zend_class_entry поле doc_comment содержит аннотации класса. У методов и атрибутов тоже есть такое поле.

Пользовательские и внутренние классы

Пользовательский класс — это класс, заданный с помощью PHP, а внутренний класс задаётся либо благодаря внедрению исходного кода в сам PHP, либо с помощью расширения. Самое большое различие между этими двумя видами классов заключается в том, что пользовательские классы оперируют памятью, выделяемой по запросу, а внутренние — «постоянной» памятью.

Это означает, что когда PHP заканчивает обработку текущего HTTP-запроса, он убирает из памяти и уничтожает все пользовательские классы, готовясь к обработке следующего запроса. Этот подход известен под названием «архитектура без разделения ресурсов» (the share nothing architecture). Так было заложено в PHP с самого начала, и изменять это пока не планируется.

Итак, каждый раз при формировании запроса и парсинге классов происходит выделение памяти для них. После использования класса уничтожается всё, что с ним связано. Так что обязательно используйте все объявленные классы, в противном случае будет теряться память. Применяйте автозагрузчики, они задерживают парсинг/объявление во время выполнения, когда PHP нужно задействовать класс. Несмотря на замедление выполнения, автозагрузчик позволяет грамотно использовать память, поскольку он не будет запущен, пока действительно не возникнет потребность в классе.

С внутренними классами всё иначе. Они размещаются в памяти постоянно, вне зависимости от того, использовали их или нет. То есть они уничтожаются только тогда, когда прекращается работа самого PHP — после завершения обработки всех запросов (подразумеваются веб SAPI, например, PHP-FPM). Поэтому внутренние классы более эффективны, чем пользовательские (в конце запроса уничтожаются только статические атрибуты, больше ничего).

Обратите внимание, что даже при кешировании опкодов, как OPCache, создание и уничтожение класса осуществляется при каждом запросе, как и в случае с пользовательскими классами. OPCache просто ускоряет оба этих процесса.

Как вы заметили, если активировать много PHP-расширений, каждое из которых объявляет много классов, но при этом использовать лишь небольшое их количество, то теряется память. Помните, что PHP-расширения объявляют классы во время запуска PHP, даже если в последующих запросах эти классы использоваться не будут. Поэтому не рекомендуется держать расширения активными, если они не применяются в данный момент, иначе вы будете терять память. Особенно если эти расширения объявляют много классов — хотя они могут забить память и чем-нибудь другим.

Классы, интерфейсы или трейты — без разницы

Не слишком хорошо, что здесь используется 912 байт всего лишь для декларирования интерфейса BarException.

Привязка класса

Многие разработчики не вспоминают о привязке класса, пока не начинают задавать вопросом, а как же всё устроено на самом деле. Привязку класса можно описать как «процесс, в ходе которого сам класс и все связанные с ним данные подготавливаются для полноценного использования разработчиком». Этот процесс очень прост и не требует много ресурсов, если речь идёт о каком-то одном классе, не дополняющем другой, не использующем трейты и не внедряющим интерфейс. Процесс привязки для таких классов полностью протекает во время компиляции, а в ходе выполнения ресурсы на это уже не тратятся. Обратите внимание, что речь шла привязке класса, задекларированного пользователем. Для внутренних классов тот же самый процесс выполняется, когда классы зарегистрированы ядром или расширениями PHP, как раз перед запуском пользовательских скриптов — и делается это лишь один раз за всё время работы PHP.

Всё сильно усложняется, если речь заходит о внедрении интерфейсов или наследовании классов. Тогда в ходе привязки класса у родительских и дочерних объектов (будь то классы или интерфейсы) копируется абсолютно все.

Тут добавить нечего, простой случай.

Для каждой из таблиц функций (методов) используется do_inherit_method :

Что касается наследования, то здесь, в принципе, всё то же самое, что и при внедрении интерфейса. Только вовлечено ещё больше «участников». Но хочу отметить, что если PHP уже знает о классе, то привязка осуществляется во время компилирования, а если не знает — то во время выполнения. Так что лучше объявлять так:

Кстати, рутинная процедура привязки класса может привести к очень странному поведению:

В первом варианте привязка класса В отложена на время выполнения, потому что когда компилятор доходит до объявления этого класса, он ещё ничего не знает о классе А. Когда начинается выполнение, то привязка класса А происходит без вопросов, потому что он уже скомпилирован, будучи одиночным классом. Во втором случае всё иначе. Привязка класса С отложена на время выполнения, потому что компилятор ещё ничего не знает о В, пытаясь скомпилировать его. Но когда во время выполнения начинается привязка класса С, то он ищет В, который не существует, поскольку не скомпилирован по причине того, что В является дополнением. Вылетает сообщение “Class B doesn’t exist”.

Объекты

Итак, теперь мы знаем, что:

Теперь поговорим об объектах. В первой главе показано, что создание «классического» объекта («классического» пользовательского класса) потребовало очень мало памяти, около 200 байт. Всё дело в классе. Дальнейшая компиляция класса тоже потребляет память, но это к лучшему, потому что для создания одиночного объекта требуется меньше байт. По сути, объект представляет собой крохотный набор из крохотных структур.

Управление методами объекта

Вы могли заметить интересную вещь, посмотрите на первые строки:

Во время компиляции функции/метода происходит немедленный перевод в нижний регистр. Вышеприведённая функция BAR() превращается в bar() компилятором при добавлении метода таблице классов и функций.

В приведённом примере первый вызов статический: компилятор вычислил key для строковой “bar”, а когда приходит время вызова метода, ему нужно делать меньше работы. Второй вызов уже динамический, компилятор ничего не знает о “$b”, не может вычислить key для вызова метода. Затем, во время выполнения, нам придётся перевести строковую в нижний регистр и вычислить её хеш ( zend_hash_func() ), что не лучшим образом сказывается на производительности.

Управление атрибутами объекта

Вот что происходит:

php class called class. Смотреть фото php class called class. Смотреть картинку php class called class. Картинка про php class called class. Фото php class called class

php class called class. Смотреть фото php class called class. Смотреть картинку php class called class. Картинка про php class called class. Фото php class called class

Так что, создавая объект, мы «всего лишь» создаём структуру zend_object весом 32 байта:

Далее движок создаёт вектор признаков нашего объекта:

Вероятно, у вас возникли два вопроса:

Пока вы не пишете в объект, его потребление памяти не меняется. После записи он занимает уже больше места (пока не будет уничтожен), поскольку содержит все записанные в него атрибуты.

Объекты, ведущие себя как ссылки благодаря хранилищу объектов

Объекты не являются ссылками. Это демонстрируется на маленьком скрипте:

Все сейчас скажут, что «в PHP 5 объекты являются ссылками», об этом упоминает даже официальный мануал. Технически это совершенно неверно. Тем не менее, объекты могут вести себя так же, как и ссылки. Например, когда вы передаёте переменную, являющуюся объектом функции, эта функция может модифицировать тот же объект.

object(MyClass)#1 (0) < >/* #1 is the object handle (number), it is unique */

php class called class. Смотреть фото php class called class. Смотреть картинку php class called class. Картинка про php class called class. Фото php class called class

Когда мы вызываем метод, движок изменяет область видимости:

Вот так можно получать доступ к приватным членам объектов, не принадлежащим вам, но являющимся дочерними по отношению к вашей текущей области видимости:

Эта особенность стала причиной большого количества баг-репортов от разработчиков. Но так устроена объектная модель в PHP — на самом деле, мы задаём область видимости на основе не объекта, а класса. В случае с нашим классом “Foo”, вы можете работать с любым приватным Foo любого другого Foo, как показано выше.

О деструкторе

Деструкторы опасны, не полагайтесь на них, поскольку PHP их не вызывает даже в случае фатальной ошибки:

А что насчёт порядка вызова деструкторов в том случае, если они всё-таки вызываются? Ответ хорошо виден в коде:

Здесь продемонстрированы три стадии вызова деструктора:

PHP не вызывает деструкторы в случае возникновения какой-либо фатальной ошибки. Дело в том, что в этом случае Zend работает нестабильно, а вызов деструкторов приводит к выполнению пользовательского кода, который может получить доступ к ошибочным указателям и, в результате, к падению PHP. Уж лучше сохранять стабильность системы — поэтому вызов деструкторов и блокируется. Возможно, в PHP 7 что-то и поменяется.

Суммируя вышесказанное: не доверяйте деструкторам критически важный код, например, управление механизмом блокировки (lock mechanism), поскольку PHP может и не вызвать деструктор или вызвать его в неконтролируемой последовательности. Если всё-таки важный код обрабатывается деструктором, то как минимум самостоятельно контролируйте жизненный цикл объектов. PHP вызовет деструктор, когда refcount вашего объекта упадёт до нуля, а это значит, что объект больше не используется и его можно безопасно уничтожить.

Источник

I’m developing a club membership register web application and I am a fairly newbie when it comes to oop. The problem I’m having is that I would need to call a function outside a class, but I know you can’t do that in PHP and I need to solve it somehow.

This code will demonstrate what my problem is:

I’ve written the code for database actions in a separate file called database_functions.php, but I can’t include that file inside a class. What I need to know is how can I access those functions without having to write them again inside the class? (I have written applications before with VB.Net and in it I can use functions of the current project inside classes.)

5 Answers 5

you can use require_once() with exact path of that class after that you should use the object of the included class and function name for calling the function of outer class.

php class called class. Смотреть фото php class called class. Смотреть картинку php class called class. Картинка про php class called class. Фото php class called class

If you have a main file that calls different files (via include or require ), then you can use any function that will exist in global namespace just fine in that class, provided the function you call will always exist in global namespace.

The other options is to wrap the other functions you have inside another class, provided that it makes sense. Class A could then hold a field with a class B object and call B ‘s functions as it pleases.

The benefit of this is that everything is abstracted in classes. Once you’re outside of the class, all you have to know is what methods (functions) you can use of a class and you won’t have to worry about the implementation details. A direct advantage of this is that you don’t have to pass the same parameter to same functions all the time, say, if you need a database handler to execute SQL code within a function. A class could just hold such an instance and you won’t have to repeat the same parameter all the time.

An additional advantage is that your global namespace won’t be polluted with specific functions.

Источник

Функции работы с классами и объектами

Содержание

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.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *