• Как внедрять зависимость (композиция), и зависеть от интерфейса?

    @galliard
    Для реализации композиции нужно не чтобы B создавался внутри A, а чтобы B удалялся вместе с A.

    То есть, например
    function factoryA(): A {
        $b = new B();
        
        return new A($b);
    }


    Таким образом после создания A единственная ссылка на B будет внутри него у удалится вместе с ним.
    Ответ написан
    Комментировать
  • Почему IDE не видит методы такого объекта?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    IDE не могут знать, какие элементы в массиве, коллекция = массив так или иначе, если коллекция объект, то элементы все равно хранятся в массиве класса коллекции. А массивы не типизированные в PHP по части конкретного элемента.

    Потому и подсветить не может, мало ли, что от туда придет...

    Можно так обозначить:
    /** @return MemberEntity[] */
    public function getMembers() {}

    Тогда не нужно будет во всех вызывающих местах проставлять тип для каждой переменной в цикле
    Ответ написан
    3 комментария
  • Правильное ли использование принципов DDD, и чем заменить Repository?

    @dimuska139
    Backend developer
    Вообще-то как раз Repository - это тот слой абстракции, который нужен, чтобы на уровне бизнес-логики (слой сервисов) абстрагироваться от способа хранения данных. То есть, очевидно, нужно использовать Repository.

    Контроллер должен работать только с сервисным слоем. Моделью (Entity) является тот класс, на который вы маппите пользователей, прочитанных из XML-файла. То есть в репозитории надо сделать метод, читающий XML, формирующий коллекцию из Entity (юзеры) и возвращающий ее. На уровне выше (в сервисном слое) надо сделать метод, который как раз вызывает этот метод репозитория. Методы сервиса в свою очередь надо дергать из контроллера, либо из класса консольной команды, если код кроном вызывается. То есть из контроллера дергать репозиторий не принято. А сервисный слой нужен, чтобы в нем держать всю бизнес-логику.
    Ответ написан
  • Правильное ли использование принципов DDD, и чем заменить Repository?

    Compolomus
    @Compolomus Куратор тега PHP
    Комполом-быдлокодер
    Ну пусть репозиторий работает с файлом, какая разница какое хранилище, пусть читает файлы и собирает сущности в коллекцию
    Ответ написан
    2 комментария
  • MVC, ООП - какие должны быть сущности и связи, для такой задачи?

    dmitriylanets
    @dmitriylanets
    веб-разработчик
    понадобятся:
    Controller
    NewsService
    NewsRepository
    NewsEntity
    NewsCollection
    SearchCriteria

    1. Реализуем Domain
    Domains/News
    - Contracts/SearchCriteriaInterface.php имеет методы навигации, фильтров, сортировки getLimit, getPage, getFilterById и тд
    - Contracts/NewsRepositoryInterface.php имеет методы работы с хранилищем findById, findByCriteria и тд
    - NewsService.php , бизнес логика тут, создаем методы
    __construct(NewsRepositoryInterface $repository)
    getById(int $id): NewsEntity
    getBySearchCriteria(SearchCriteriaInterface $criteria): NewsCollection

    - NewsEntity.php , обычная DTO с сеттерами и геттерами (все что осталось от модели)
    - NewsCollection.php, коллекция содержащая список NewsEntity с методами интерфейсов Iterator,ArrayAccess,Countable

    2. Реализуем Application
    Application/Controllers
    - HomeController.php содержит методы списка новостей и одной новости, но моно создать два контроллера со списком и с детальной инфой, все на ваше усмотрение.
    __construct(NewService $service, Request $request)
    index() - метод основной или на ваше усмотрение, который получает коллекцию новостей пример
    $criteria = new \Infrastructure\Repositories\News\SearchCriteria;
    $criteria->setLimit(10);
     
    $newsCollection = $this->service->getBySearchCriteria($criteria);
    //далее куда угодно отправляем $newsCollection или в шаблон или в JsonResponce и тд

    - show(int $id), реализация страницы новости
    $newsEntity = $this->service->getById($id);

    3. Реализуем Infrastructure
    Infrastructure/Repositories/News/
    - SearchCriteria.php реализация интерфейса SearchCriteriaInterface
    - NewsRepository.php реализация интерфейса NewsRepositoryInterface

    3 этап на момент тестирования можно реализовать функционал не работая с источниками данных, то есть можно использовать заранее созданный сущности в специальных Mock репозиториях. Инжектить можно через DI, такая схема позволить покрыть код unit тестами
    Плюс такого подхода что код разрабатываем не от слоя хранения а от бизнес сущностей, SOLID и все такое
    Ответ написан
    2 комментария
  • MVC, ООП - какие должны быть сущности и связи, для такой задачи?

    @synapse_people
    Контроллер как-то так:
    class News {
    function index($page) {}
    function show($id) {}
    }

    Если используете Entity+Repository, то советую сделать еще Service, который будет доставать данные из Repositry (и содержать всю логику). Сам этот Service будет доступен из Controller. (так сделано в Spring Framework).

    Если только Model, то в ней должна быть логика вся и доставания записей из БД, обработка и тд.

    В контроллере формируются данные для View, например, массив. А View только его отрисовывает.

    Как-то так..
    Ответ написан
    2 комментария
  • Что такое mvc-паттерн на самом деле?

    php666
    @php666
    PHP-макака
    Поставь на базе фреймворка Laravel это решение - laravel-boilerplate.com
    Это каркас приложения с некоторым готовыми модулями, легче понимать будет по уже написанному коду модулей. У нас коллеги, которые с Битриксом всю жизнь работали и про MVC ничего не знали, за неделю принцип поняли, опираясь на примеры кода.

    Что бы понимать MVC, надо понимать суть ООП. Для понимания сути ООП надо читать соответсвующую литературу. Это важно. Нужно научиться мыслить объектами, забыть как страшный сон всё, что ты знал до этого и заново учиться писать код.

    Что бы понимать, что такое разделение системы на слои, надо читать это (начни сразу с части 1, главы 1).

    Ну и на, мою статью на более "человеческом" варианте понимания МВС.
    Ответ написан
    9 комментариев
  • Как правильно конфигурировать логгер и внедрять зависимость?

    dmitriylanets
    @dmitriylanets
    веб-разработчик
    5. внедрять логер в зависимости от интерфейса. В DI есть возможность вызвать метод setLogger в зависимости от интерфейса.
    Например вы создаете интерфейсы:
    FileLoggerAware extends LoggerAwareInterface 
    MysqlLoggerAware extends LoggerAwareInterface


    теперь конфигурирует DI
    $container->share(FileLogger::class,function(){
           return new NullLogger;//тут реализация file логера
    });
    $container->share(MysqlLogger::class,function(){
          return new NullLogger;//тут реализация Mysql логера
    });
    $container
        ->inflector(FileLoggerAware::class)
        ->invokeMethod('setLogger', [FileLogger::class]) 
    ;
    $container
        ->inflector(MysqlLoggerAware::class)
        ->invokeMethod('setLogger', [MysqlLogger::class]) 
    ;


    и все в нужном классе делаешь, (но все классы должны работать через awaring di, прилетать автоматом через конструктор)
    class MyClass implements FileLoggerAware
    {
    
    use LoggerAwareTrait;
    
    }


    ссылки:
    https://github.com/php-fig/log/blob/master/Psr/Log...
    https://container.thephpleague.com/3.x/inflectors/
    Ответ написан
    2 комментария
  • Для чего в конфиге logstash при связке с очередь rabbitmq как источника логов - указывают exchange?

    @vitaly_il1
    DevOps Consulting
    Я пробую писать конфиг сюда: /etc/logstash/conf.d/rabbitmq.conf
    Файл конфига я создал самостоятельно. Система сама его найдет ?

    да, это очень популярный и удобный метод добавления конфигов - в главном конфиге стоит 'include conf.d/*.conf' - загляните в /etc/logstash/logstash.conf.

    Нужно ли по умолчанию описывать output для elasticserach ? Или они по умолчанию из logstash'a туда поступят ?

    нужно.
    Ответ написан
    Комментировать
  • Kibana: как выбрать поле объекта для визуализации на вкладке Discover?

    akelsey
    @akelsey
    По всей видимости никак. Не спроста в кибане возле типа - стоит вопросик, эластик и кибана не знают что с этим делать. Этот context нужно было допарсить на logstash вероятно, что бы это был не объек с несколькими уровнями вложенности, а более менее понятное кибане.
    Ответ написан
    1 комментарий
  • Стоит ли переносить с крона в очереди?

    stanislav-belichenko
    @stanislav-belichenko
    Backend PHP Developer
    Про нагрузку:

    Нет, ничего критического не произойдет, если только вы не работаете с серверами из 80-х. Конкретно кролик держит огромные нагрузки отлично.

    Про целесообразность:

    Во-первых, выше верно пишут, пока работает - не трогай.
    Во-вторых, опять же выше верно пишут, что на такое количество задач затея сомнительна.
    В-третьих, очереди - это обычно нечто событийное. К тебе пришел клиент на сайт, загрузил свое фото, ты родил сообщение в очередь на бекенде сайта, что фото должно быть проверено саппортами, это событие получила CRM-система саппортов и они выполнили какие-то действия. А в описанной в вопросе модели кто будет рождать такие события? Некий таймер? Он же опять скорее всего на кроне будет, смысл городить огород тогда с кроликом? Если не на таймере, а на каком-то событии, возникающим в приложении в нужный момент времени - ну ок. Но скорее всего, будет все-таки иначе.
    Ответ написан
    3 комментария
  • Принцип DIP из SOLID и Autowiring из DI-контейнеров?

    syamskoy
    @syamskoy
    Dependency injection - это когда в класс A мы передаем класс B через конструктор или сеттер, что бы он с ним работал, а не создавал его в своих нутрях.
    Dependency Inversion - это когда мы в классе A работаем не с конкретной реализацией, а с интерфейсами: указываем интерфейсы в конструкторе, в методах, в возвращаемых типах и т.д.
    Это два разных понятия, которые иногда объединяют в одно, и иногда их путают.
    Так вот, autowiring - это про Dependency injection, а D в solid - это про Dependency Inversion. Одно другому не мешает и не нарушает.
    Ответ написан
    1 комментарий
  • Принцип DIP из SOLID и Autowiring из DI-контейнеров?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Как это не будет? Может быть вы не правильно используете или не знаете как использовать?

    В DI контейнере мы «привязываем» класс, который реализует интерфейс. Таким образом везде, где есть этот интерфейс будет работать созданный и «привязанный» нами класс.

    Вроде бы там достаточно просто и понятно.
    Ответ написан
    9 комментариев
  • Альтернатива Singleton?

    serginhold
    @serginhold
    Единственный вариант, который мне известен, это через внедрение зависимостей.
    Но я не представляю в какой части приложения это делают. Нужно создать подключение к БД в front-controller и поместить в DI-контейнер, и в дальнейшем использовать ? Или как ?

    почитай что-нибудь нормальное про di.

    контейнер создается при старте приложения,
    в нем создаешь экземпляр подключения к бд:
    $container->set('db', function () use ($container) {
        return new DbConnection($container->get('config')['db']);
    });

    потом подключение передаешь в те сервисы, где оно нужно:
    $container->set('MyService', function () use ($container) {
        return new MyService($container->get('db'));
    });


    как пример где это происходит: www.slimframework.com/docs/v4/concepts/di.html
    Ответ написан
    2 комментария
  • Паттерны проектирования в популярных Open Source проектах?

    @bins
    PHP программсит
    Ответ написан
    Комментировать
  • Symfony или Slim framework?

    rusya_mahin_page
    @rusya_mahin_page
    WiRight - это все
    Сам работаю на Symfony 4

    Перешел на него с Yii2
    Мне после Yii2 на Symfony было намного проще. Как-то меньше костылей что-ли

    Slim тоже посматривал
    Но не вызывал бурных аваций

    И для себя решил, что если что-то серьезное - Symfony
    Накидать и другу показать - Slim

    И да, Symfony - модульный. Так что из коробки он "пустой"..)

    ПыСы - чистая субъективщина
    Ответ написан
    4 комментария
  • Как контролировать жизнь php-консюмеров?

    akubintsev
    @akubintsev
    Опытный backend разработчик
    И как решают это другие?

    У меня такое решение в голову приходит:
    Каждый консюмер периодически обязан подать признаки жизни - в некую таблицу БД записывать дату и время активности.
    И по крону, другой скрипт проверяет записи в таблице, если какой-то консюмер долго не обновлял запись - убить процесс по pid.


    В принципе, вам уже ответили. Хочу только добавить немного.
    Обратите внимание на systemd. В нём есть механизм проверки признаков жизни watchdog. Можно пингать самого себя тестовым сообщением, например. И рестартить по отказу.
    [Service]
    ...
    WatchdogSec=30s
    Restart=on-failure

    И конечно же прикрутить мониторинг, чтобы смотреть через Grafana или т.п.
    Ответ написан
    2 комментария
  • Контейнеризация для локальной разработки?

    Правильно понимаю, что docker можно также спокойно использовать локально на windows?
    Правильно.

    Как вы локально разворачиваете докер ?
    Под Mac или Windows cкачать Docker Desktop.
    Разворачивать проект – так же как заворачивали ) Скорее всего клонировать репку с файлом docker-compose.yml вашего проекта и docker-compose up А потом заходить внутрь контейнеров, или запускать дополнительные временные – со всякими git clone, composer install, npm i, mysql -p${MYSQL_ROOT_PASSWORD} < database_init.sql и пр.

    При разворачивании проекта через docker, создается некая виртуализация.
    Не совсем. Docker не виртуализация, а контейнеризация. Отсутствует виртуальная машина, в отличие от, например, VirtualBox. На бытовом уровне, есть некие изолированные виртуальные коробки-контейнеры, из которых наружу торчит, может, порт. И друг дружку эти коробки видят как компы в локальной сети.

    Как тогда работать с проектом через IDE ? Если все окружение проекта на linux, а мы работаем на windows, как вообще люди работают через IDE в таких случаях ?
    Как вариант, работать как с удалённым Linux сервером. Подключаться к нему по SSH, тот же VS Code умеет через расширение Remote-SSH.

    Файлы копировать с компа в контейнеры (или наоброт) через
    docker cp ./local.file  containerName://var/www/remote.file


    За «роскошь» локальной-обычной работы с файлами прямо на компе с любым IDE, какой предпочитает любой из разработчиков, придётся расплачиваться докручиванием конфигов, которые будут отличаться от продакшена. И тогда, наверное, пропадает весь кайф докеризации-для-разработки.

    В целом я бы не рекомендовал докер для локальной разработки, хотя сам пользуюсь в некоторых проектах.
    Ответ написан
    Комментировать