php trait private method

Примеси в PHP (trait) // PHP

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

С версии 5.4 в PHP появился такой интересный механизм как примеси (trait), который по задумке разработчиков должен помочь разруливать ситуации когда уж очень хочется применить множественное наследование, но нельзя. Вот о некоторых подобных ситуациях я и расскажу далее.

Примеры не надуманные, а вполне рабочие из фреймворка Bluz 😉

Теория

Тут будет краткий пересказ официальной документации в моей интерпретации, если не интересно — промотайте чуть дальше…

Хотя нет, лучше останьтесь и прочитайте, ведь мне абсолютно не нравится подача этого материала в официальной документации, для понимания примесей надо разговор начинать с необходимости данного нововведения в PHP. Начну издалека, вот один из классических примеров ООП: есть следующие классы – абстрактный класс Мебель, который лишь знает что у мебели есть размеры, Стол с площадью столешницы и Стул с некой максимально-возможной нагрузкой, в довесок есть Диван, пока просто диван:

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

Давайте-ка распишем данный подход в коде:

Да тут невооруженным взглядом видно копипасту, и очень хотелось бы избавится от неё, хотелось бы реализацию требований 3 и 4 закинуть в отдельный класс, и наследовать его, но в PHP нет множественного наследования, может быть только один класс предок. И вот в PHP 5.4 на сцену выходят примеси (trait), чем-то они схожи на классы, но лишь издалека, примеси лишь группируют некий набор функционала под одной вывеской, но не более. Давайте таки опишем необходимый функционал в примесях:

Теперь данный примеси легко можно подключить в наших классах:

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

Реализация шаблона Singleton

Можно много спорить о данном шаблоне, есть у него и плюсы и минусы, но речь не об этом, а о его реализации, при чём так, в один use 😉

Чтобы это стало возможным следует реализовать вот такую примесь:

Полный листинг класса можно найти в репозитории – Bluz/Common/Singleton.php. Пример не претендует на универсальность, но он юзабелен и имеет право на жизнь.

Обратите внимание, реализация шаблона Singleton никоим образом не обязует вас на хоть какие-то объединения классов под одним предком, т.к. это выглядило бы очень странно, а вот для избавления от практики копирования функционала из класса в класс нам и нужен данный trait

Реализация интерфейса инициализации

Теперь попробуем заюзать данную примесь в простом шаблонизаторе:

А вот и пример использования:

Примеси нам дают возможность не только описать интерфейс, но и фактически реализовать его, без необходимости копировать идентичный код из класса в класс

Реализация помощников класса

О чём это я, да о достаточно популярном приёме, когда функционал одного класса разделяют по различным классам и функциям с ленивой инициализацией, самый наглядный пример — это помощники View в Zend Framework. В фреймворке Bluz данный подход реализован в одном trait:

Для примера будем использовать всё тот же шаблонизатор:

В качестве ленивого помощника у нас будет анонимная функция:

Теперь можно пользоваться:

Код сокращён и упрощён для наглядности

Выводы

Как можно заметить, trait’ы можно и нужно использовать, ведь таким образом мы сокращаем объём кода, который нам потребуется поддерживать, да и метод копи-пасты уже давно должен был кануть в лету, а с появлением примесей вам уж не будет оправдания 🙂

Если у вас есть примеры использования примесей, прошу — оставляйте ссылки.

Источник

Использование трейтов в PHP

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

Языки, подобные C++ и Python, позволяют нам наследоваться от нескольких классов, которые в какой-то мере решают эту проблему, а mixins в Ruby позволяет смешивать функциональность одного или нескольких классов без использования наследования. Но множественное наследование имеет свои проблемы.

Что представляет трейт

Трейт похож на абстрактный класс, который не может быть создан сам по себе (хотя чаще он сравнивается с интерфейсом). Документация PHP определяет трейты следующим образом:

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

Допустим, оба класса должны быть синглтонами. Поскольку PHP не поддерживает множественное наследование, каждый класс должен будет реализовать необходимый код для поддержки шаблона Singleton. Трейты предлагают решение именно такого рода проблем.

Трейт Singleton содержит реализацию шаблона Singleton со статическим методом getInstance(), который создает объект класса с использованием этого трейта (если он еще не создан) и возвращает его.

Попробуем создать объекты этих классов с помощью метода getInstance().

Мы можем видеть, что $a является объектом DbReader, а $b является объектом FileReader, но оба теперь ведут себя как объекты реализующие шаблон Singleton. Метод от класса Singleton был введен в классы, использующие его трейт.

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

Если мы просто расширим класс DbReader из родителя со скрытым свойством $instance, свойство не будет отображаться в дампе ReflectionClass::export().

Использование нескольких трейтов

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

Здесь у нас есть два трейта: «Привет» и «Мир». Трейт Hello может только сказать «Привет», а трейт World может сказать «Мир». В классе MyWorld мы применили Hello и World, чтобы объект MyWorld получал методы от обоих черт и мог сказать «Hello World».

В одной из следующих статей мы продолжим обсуждать трейты. А сегодня на этом все. Спасибо за внимание!

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

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

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

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

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

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

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

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

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

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

Источник

Прочитал про новую штуку в php trait

Сделал первый пример

Работа понятна, вопрос чем отличается вышепоказанный пример, от

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

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

При таком подходе вы всегда класс логгера можете заменить, просто отредактировав всего один файл трейта, а не 100500 классов.

Еще пример:
В трейт можно вынести функцию isAjaxPost, для проверки, что запрос в контроллер пришел ajax post, и подключать в нужные контроллеры.

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

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

@Fesor всмысле когда, например модуль Блог хочет написать личное сообщение пользователю (Тесная связь модуля Блог и модуля Сообщения).

Берем модуле блог делаем трейт, который знает про модуль сообщения и везде в модуле блог работает с трейтом.

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

@Fesor Не соглашусь насчет макроса и того, что код вставляется в место use TraitName, в PHP это реализовано, почти так же, как extend, за исключением приоритетов, кто кого перекрывает. ну и да одноименные функции из трейтов друг друга перекрыть не могут, будет ошибка, но есть механизм выбора.

Насчет множественного наследования, это было в качестве примера, множественное наследование вообще штука не очень хорошая, но при грамотном и острожном использование пойдет 🙂

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

@nepster09 Сходу так прям не ответить, всего скорей это не удачное решение, т.к получаем связь блога и сообщений, с другой стороны если система не сложна, то вполне себе решение.

Если делать через трейты, я бы наверное сделал следующем образом, трейт отвечал бы за получение экземпляра конкретного модуля, ну через какой-нить контейнер зависимостей, подключал в него все зависимости т.д.

trait UserModuleTrait
<
protected function getUserModule() < // логика создания >
>

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

Но тут получается такая страшная штука, если условия отправления сообщений сменить с 10, на к примеру каждого 3 отправленное в субботу утром, то получается постоянно лезть в модель блога для исправления.

Всего скорей тут лучше сделать через эйвент по факту создания новой записи, это эйвент отлавливать и уже в обработчики реализовать всю логику по отправки сообщений. А сами связи на модуле получать через контейнер сервисов, ну так будет правильнее.

Хотя еще раз повторюсь, если проект не сложный, то первый вариант вполне себе рабочее решение 🙂

Источник

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private methodТрейты в PHP

Нужные для использования в классе трейты можно указать через запятую:

Приоритет методов при работе с трейтами.

— члены из текущего класса переопределяют одноименные методы в трейте,
— члены из трейта переопределяют унаследованные классом методы. То есть трейт имеет преимущество перед классом который наследуем.

Конфликты трейтов.

Ошибки могут быть когда подключается несколько трейтов, содержащие одни и те же методы. Или когда класс наследует у другого класса с подключением трейта, который уже был подключен в родительском классе.
Для разрешения конфликтов необходимо использовать оператор insteadof при подключении трейтов для того, чтобы точно выбрать один из конфликтных методов.
Внутри тела «use» мы использовали ключевое слово insteadof, слева от которого указывается трейт, метод которого будем использовать и имя самого метода, которые разделяются двойным двоеточием. В правой части указывается имя трейта, метод которого должен быть заменён.

Если же второй одноименный метод (из другого трейта) нам тоже нужен, то можно применить псевдоним имени используя ключевое слово as :

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

Используются так же как и в классах:

Доступ к свойствам базового класса.

В трейтах для доступа к свойствам базового класса можно использовать псевдопеременную $this.

Изменения прав доступа к методам трейта.

Внутри трейта мы можем использовать любой модификатор доступа (public, private, protected) для методов. Но, кроме этого, есть возможность в классе менять этот модификатор на другой. Для этого в теле use после слова as можно указать новый модификатор.

Источник

Traits in PHP: Proper way of implementation

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

Trait is very useful concept in OOP PHP. Although it is very similar to php class but it has so many different uses in OOP approach. In this article i will try to describe how to use trait in a proper way & when we use trait instead of class and common trait scopes.

The main benefit of traits is its re-usable nature. The PHP language is a single inheritance language. This means that any given class can only extend a single other class. As an example, let’s say you have two base classes:

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

Unfortunately, as it stands in PHP, you cannot perform multiple inheritance by extending classes. You can extend either BaseA or BaseB, but not both at the same time:

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

But what if you want the functionality of both of these in a single class? Traits can solve this problem:

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

This method of inheritance is known as “Horizontal Reuse”. It is intended to reduce code duplication and share code horizontally.

Using Traits

As described above, traits are very easy to use. In their most basic form, you declare a trait using the trait keyword:

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

You can then have classes which use this trait:

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

Traits can also contain class properties:

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

Basically, when a trait is used in a class, it is more or less directly copied into the class. I’ll go over some basic properties of traits, and some common use cases.

Trait Scope

Private

Unlike single inheritance, private scope in a trait will be available to the extending classes. Take this example:

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

Protected

Protected scope for a trait means that any class which extends the trait, or the children of the trait are able to access the function or variable. In the previous example, if privateFunc were a protected function, then ExtendingClass would be valid.

Public

Anyone can access the variable or function. Simple as that.

Naming Conflicts

Sometimes, it is possible that you need to import a trait into a class, but there is a conflicting function or variable name. This can be solved using either the as or insteadof operator:

php trait private method. Смотреть фото php trait private method. Смотреть картинку php trait private method. Картинка про php trait private method. Фото php trait private method

In above i try to describe using of trait in a proper manner.

Источник

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

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