protected $two;
protected $three;
public function __construct()
{
$this->one = "get user profile from database"
}
}
=======================================
namespace App\Http\Controllers;
class Second extends First
{
public function handle()
{
$abc = $this->one;
}
}
=======================================
namespace App\Http\Controllers;
class Third extends First
{
public function handle()
{
$cde = $this->one;
}
}
=======================================
Есть 3 класса выше описанных.
порядок выполнения кода:
$newClassSecond = new Second(); /*при создании экземпляра этого класса, выполняется метод __construct() класса First, и в свойство $one - загружается профиль пользователя из базы данных*/
$newClassThird = new Third();
/*при создании экземпляра этого класса, опять выполняется метод __construct() класса First, и в свойство $one - повторно загружается профиль пользователя из базы данных*/
Вопрос - как при создании экземпляра класса Third - избежать повторного выполнения метода __construct() класса First, избежать повторной загрузки данных из БД.
И в тоже время из класса Third - использовать уже загруженные из БД данные в свойство one, при создании класса Second ?
не делать через наследование, а делать через композицию желательно избегать наследования классов, это очень трудно потом поддерживать а за обращение к базе данных в конструкторе, нужно гнать санной тряпкой из программистов
мне пофиг кого откуда гнать. я на такие вещи не реагирую. А вот про композицую, сейчас прочитаю))
Бесполезный совет. А как же арегация? Наследование на композицию не будет меняться. Надо конкретно решение в данной ситуации. Без изменения кода всего проекта.
приведенный тобой пример кода, тем более если это контролер не будет работать в текущей реализации, так как в момент создания класса контролера, нет еще данных об авторизации пользователя и загрузить профиль ты не сможешь, т.к. данных о текущем пользователе еще нет.
Егор, бросьте там про другое, нету никакой авторизации. Не хочу вдаваться в детали. Поэтому упростил пример. Пока другим немного занят, позже разберусь. Код и архитектура- могут быть не идеальны. Это приемлемо. Сейчас весь код проекта ради стремления к совершенству никто менять не будет.
ок, но как минимум уйти от выборки из базы в конструкторе стоит, например выборку перенести в отдельный класс (Service, Repository назвать можно как угодно) и сделать только тогда когда она действительно понадобиться
Ок, спасибо за совет.
Если для Вас критично держать выборку в конструкторе то вы можете обойти этот кейс не самым конечно адекватным образом. Создайте в конструкторе first опциональный параметр для нужных вам свойств и присвойте null. Передавайте данные из third при вызове parent::__construct. Это костыль костыль. Но насколько я помню просто так скипнуть родительский конструктор нельзя(поправьте если что)
Просто весь поток выполнения кода, начинается с класса first , в нем прописаны свойства, которые потом используют наследники этого класса . И в том числе свойство one в котором должна быть выборка. Эта выборка потом много раз в большом количестве наследников используется. Поэтому так и сделано. Самым простым решением было бы скипнуть конструктор родительского класса. Пока не нашел как это делать. То что Егор предложил - слишком радикально в текущей ситуации.
Условие с проверкой на налл для этого нового параметра конструктора
Я полностью понимаю о чем вы, приходилось работать на одном супер легаси проекте, не всегда можно что то исправить, главное хуже не сделать
В самом конструкторе? Родительского класса ? Похоже это решение 👏.
Как я и описала, это костыль)
Нет, я про другое подумал. В конструкторе родительского класса - пишем : если one = null , тогда грузим профиль из базы данных, иначе - ничего не делаем. Наследники потом хоть сколько раз запускай родительский конструктор. Он не будет больше избыточных обращений к бд делать.
Как вариант) тем не менее, composition over inheritance.
Всем участвующим в решении - спасибо. Пошел конструктор переписывать. Сэкономлю несколько миллионов запросов к БД ))). За 3 строки кода. Это то что я искал.
Не столкнитесь только с ситуацией что где то будет тоже инититься переменная one до вызова родительского конструктора
Это уже есть, надо оптимизировать код. Времени на все не хватает.
зачем наследники несколько раз конструктор выполняют?
Конструктор родителя выполняется автоматически при создании нового экземпляра наследника. Это в примере наследника 2 а в реальности их - больше
забыл. что в чятике ларавели, у них такое прям в мануале советуют
Могу предложить менее радикально, это сделать на подобии модели, через магические методы. Т.е. получиться, что свойства будут формироваться по мере обращения. А обращения из __get() делать к методу get{имя поля} предварительно проверив что метод существует. И со временем переходить на прямой вызов этих методов, без поредничества магии.
Доброго времени подскажите пожалуйста. у меня есть scout и столкнулся с таким моментом что в структуре базы данных есть 2 кея по которым определяется сущность но скаут индексирует ток по ключу 1 как можно сделать что бы он определял 2 'link_type' => ['type' => 'integer'], 'cached_id' => ['type' => 'integer'], 'name' => ['type' => 'text'], 'keywords' => ['type' => 'text'], нужно что бы по уникальнсть записи он понимал link_type и cached_id
как вариант вижу сделать public function getScoutKey(): mixed { return $this->link_type. "_".$this->cached_id ; } /** * Get the key name used to index the model. */ public function getScoutKeyName(): mixed { return 'uuid'; }
но я не знаю насколько это будет работать
и добавить в миграцию скаута поле uuid
Ребят, всем спасибо за участие 👍. Завтра уже протестирую все варианты и подберу рабочее решение. Сегодня другое доделал.
ты забыл указать какой драйвер scout-а ты используешь
https://github.com/RomanStruk/manticore-scout-engine
почему вдруг стало два ключа?
База от очень старого проекта и там первичных ключей на таблице нету. для того что бы кэш в базе данных хранить из разных сущностей получая глобальный поиск в црм
а например добавить виртуальную колонку, которая будет равно конкатенации двух колонок и уже эту виртуальную колонку использовать как id записи
атрибут получается бахнуть ? ибо я же скаут кей конкатинирую в примере ?
нет не атрибут модели, а на уровне базы данных добавить виртуальную колонку https://dev.mysql.com/doc/refman/8.0/en/create-table-generated-columns.html
Не варик таблица уже на 40 милионов записей
как я понял это таблица, когда еще не было scout, т.е. это некий пережиток прошлого может быть если уже перешли на scout, то и от таблицы можно избавиться хотя эта таблица наверное как агрегатор всех имеющихся таблиц и она уже индексируется scout или нет
Это настолько пережиток прошлого что это ещё на пхп 3 пилилось
нет мы строим карапт леер не задевая старый функционал
т.е. за 23 года даже не подумали переписать на что-то более подходящее или найти инструменты индексации документов, вот это поворот
Нет там есть старый сфинкс он работает. но перенос на новые рельсы требует вот таких вот
а по скольким таблицам собираются данные если это не секрет
и еще вопрос, при поиске данных есть что-то вроде проверки на доступ к данным по которым происходит поиск?
но это на уровне выше происходит после поиска в мантикоре
Я совсем зеленый, только начал учить лару, читаю топик, вижу что-то новое, гуглю. И вот зацепился за scout. Я так понял это глобальная надстройка для полнотекстового поиска в базе? А можете по простому объяснить где ее применяют и в чем отличие от встроенного full-index?
Ну ответьте блин ему, мне тоже интересно
Gpt мне уже ответил ))
Ну поделись чтоли) ну а вообще интересно мнение людей и опыт больше, чем просто факты (конечно и то и другое важно)
Scout в Laravel действительно представляет собой мощное средство для полнотекстового поиска в базе данных. Это пакет, который позволяет вам интегрировать поиск на основе поисковых движков, таких как Elasticsearch и Algolia, в ваше приложение Laravel. Scout упрощает создание и обслуживание индексов для вашей базы данных, делая полнотекстовый поиск более эффективным и масштабируемым. Вот несколько ключевых моментов: Интеграция поисковых движков: Scout позволяет интегрировать поисковые движки, такие как Elasticsearch и Algolia, с вашим приложением Laravel. Эти поисковые движки специализируются на полнотекстовом поиске и обеспечивают высокую производительность и точность результатов. Индексирование данных: Scout автоматически создает и обновляет индексы для ваших моделей Laravel. Это упрощает процесс подготовки данных к полнотекстовому поиску. Удобство использования: Вы можете выполнять поиск в своих моделях с помощью простого и понятного синтаксиса Laravel, что делает его удобным для разработчиков. Расширенные возможности: Scout позволяет выполнять различные операции с результатами поиска, такие как сортировка, фильтрация и дополнительная обработка результатов. Сквозной поиск: Этот вид поиска позволяет искать данные в разных таблицах и моделях вашей базы данных, что может быть полезно, когда вам нужно объединить данные из нескольких источников. Отличие от встроенного полнотекстового поиска зависит от того, какой конкретный поиск вы реализуете. Laravel имеет встроенную поддержку полнотекстового поиска с использованием SQL-запросов и индексации через MySQL и другие базы данных. Однако эта реализация может быть менее масштабируемой и менее мощной по сравнению с поисковыми движками, которые поддерживаются Scout, такими как Elasticsearch и Algolia. Скажем, если вам нужен высокопроизводительный полнотекстовый поиск с возможностью ранжирования результатов, фильтрации и другими продвинутыми функциями, то Scout с поисковыми движками может быть лучшим выбором. Встроенный полнотекстовый поиск в Laravel подходит для более простых задач, но может быть ограниченным в функциональности по сравнению с Scout и поисковыми движками.
Привет, мне нравится твое критичное мышление. Задачу ту в итоге решил через применение singleton. То что искал, зарегистрировал класс в сервис провайдере, загрузил в свойства синглтона - профиль пользователя. Все остальные классы далее используют это свойство. Без повторных обращений к БД.
Обсуждают сегодня