• Как symfony загружает классы через входные данные?

    @Flying
    Этому посвящена добрая часть документации компонента Dependency Injection и Service Container'а, который является центральной частью этого компонента.

    Если совсем вкратце - то вы либо описываете сервисы вручную через конфигурацию (есть несколько поддерживаемых форматов, включая аннотации, хотя они вроде реализуются внешним пакетом) либо используете преимущества autowiring'а, предоставляя Symfony всё описать за вас (с помощью compiler pass'ов, если потребуется). Собственно основная "магия" преобразования всех источников данных в кучу компилированного PHP находится как раз в compiler pass'ах, их много и можно писать свои.

    Поскольку у вас в примере - controller's action - то здесь вся магия реализуется через обработку тега controller.service_arguments, который по-умолчанию добавляется ко всем контроллерам в конфиге сервисов.
    Ответ написан
    5 комментариев
  • Как правильно использовать Symfony + Gulp + БЭМ?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    И не найдёте. Это вопрос из серии «Как правильно использовать дрель + холодильник + ноутбук» — согласно документации каждого. Вы или не знаете, чего хотите, или одно из двух.
    Ответ написан
    3 комментария
  • Как правильно конфигурировать сторонний бандл в своём?

    @Flying
    Переопределение конфигурации в Symfony вне основного процесса загрузки конфигурационных файлов - не самое простое дело. Этот процесс закрыт от прямой кастомизации т.к. основной процесс загрузки и обработки конфигурации bundles целиком отдан на откуп им самим. Причина подобных ограничений в том что загрузка конфигурации - один из самых ранних этапов работы и, как и для всех подобных частей кода - там довольно мало пространства для манёвров. В связи с этим путь (и сама возможность) переопределения конфигурации будет очень сильно зависеть от того что же именно вы хотите переопределить.

    Для того чтобы лучше понять как это происходит - вам стоит подробнее изучить вопрос того как именно организована загрузка и обработка конфигурации в Symfony.

    Если вкратце:
    1. В процессе конфигурации контейнера происходит сбор данных конфигурации из конфигурационных файлов. Эти данные сохраняются в container'е через ContainerBuilder::loadFromExtension().
    2. Далее, собранные данные передаются в качестве основы в bundle extension (через метод load()). То, как именно bundle extension будет работать с собранными данными - целиком зависит от кода bundle'а, так что в целом с ними может произойти всё что угодно.

    Как вы, надеюсь, понимаете - из-за п.2 какого-то общего подхода к переопределению данных в Symfony не существует. Поэтому, как я уже писал выше, вам необходимо определиться с тем что именно вы хотите переопределить, а дальше смотреть на код загрузчика соответствующего bundle (вот он для LiipImagineBundle).

    Как видно - в случае LiipImagineBundle в целом ничего страшного не происходит, полученная конфигурация сразу отправляется в processing и потом используется для регистрации сервисов и параметров.

    Поскольку процесс сборки контейнера начинается с merge pass, то вы не можете вмешаться в этот процесс через compiler pass, как это делается обычно, однако вы можете воспользоваться вот этим куском логики для того чтобы добиться своей цели: вам достаточно определить в своём bundle собственный extension и отметить что он реализует PrependExtensionInterface. Это позволит вашему extension получить экземпляр ContainerBuilder до того как будут загружаться остальные extensions, именно это позволит вам воспользоваться ContainerBuilder::loadFromExtension() для добавления параметров конфигурации к нужному вам bundle.

    Несколько нетривиально, но должно работать :)
    Ответ написан
  • Как задать зависимые параметры для маршрутов в аннотациях Symfony?

    @y_bitko
    PHP Symfony
    Укажите page тоже как {slug}. И задайте для него значение по умолчанию и обязательное значение только page.
    @Route("/products/{page}/{pageNum}", name="product_paged_index", defaults={"page":"page", "pageNum": "1"}, requirements={"page"="page", "pageNum"="\d+"})
    Ответ написан
    Комментировать
  • Symfony - в чём разница между listener и subscriber, и что означает теговать (tags)?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Listener — слушатель одного или более событий, некий такой атомарный исполнитель. Не знает на что он подписан, но легко управляется через конфигурацию. Если разные слушает — нужно самому логику разделения обработки писать.
    Subscriber — подписчик имеет реализацию интерфейса SubscriberInterface с методом getSubscribedEvents(), то есть сам объект слушателя знает, на что он подписан и какие методы какие события будут отрабатывать

    По сути одно и тоже, но такая разница иногда пригождается. Иногда нужно иметь контроль снаружи, иногда наоборот.

    Теги — отдельный механизм контейнера. Проставляя тег на набор сервисов — мы во время компиляции контейнера можем достать помеченные определенным тегом сервисы и заинжектить в др сервис (очень часто используется мной например), отсортировать по допатрибутам или сделать любую иную логику
    https://symfony.com/doc/current/service_container/...
    Ну например есть десяток сервисов, которые обрабывают каждый свой тип файла, еще и лежат в разных бандлах. Как получить их в одной фабрике? Правильно — проставить им тег, в компиляторе приложения достать все и в фабрику засунуть. При появлении нового сервиса с тегом - он автоматом будет в фабрике.

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

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    С такими задачами СУРБД справляются плохо. Обычно их реализуют движками полнотекстового поиска, типа Elasticsearch.
    Ответ написан
    2 комментария
  • Альтернатива 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 комментария
  • Где описан api symfony?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Самый плоный api symfony - это и есть symfony
    Ответ написан
    Комментировать
  • Каким способом можно сделать PARSER в Symfony?

    @Flying
    Парсинг больших файлов осуществляется в потоковом режиме. Для XML существует стандарт потокового парсинга - SAX. В PHP есть стандартный модуль, реализующий SAX через libxml2.

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

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

    Также хочу заметить что парсинг 200мб XML - не та задача которая требует отображения прогресса т.к. сам процесс парсинга будет занимать максимум единицы секунд, а скорее ещё быстрее. Больше времени может уйти на загрузку этого файла, или сохранение / обработку данных, полученных из XML, возможно вы это имели в виду?
    Ответ написан
    4 комментария
  • Как организовать структуру Symfony проекта для взаимодействия со сторонним API?

    bitniks
    @bitniks
    Go/PHP/Symfony developer
    Структура Entity -> Repository -> Service -> Controller универсальна и не завязана на БД.

    Entity это ваши сущности (посты, клиенты, заказы). Repository позволяют изолировать логику хранения данных. На каждую сущность создаем репозиторий, который будет иметь зависимость от ApiClient (а лучше от интерфейса клиента) через DI. Основная идея репозиториев впоследствии безболезненно переходить на другие способы хранения/получения данных, поэтому следует создать для них интерфейсы и сделать реализацию этих интерфейсов для API. В Service описываем бизнес логику, используем репозитории. Контроллеры оставляем тонкими — получение сервисов и вызов их методов. Можно пойти дальше и взаимодействие сервисов перенести в специальные сервисы. Это полезно, если потребуется использовать данную логику в других частях приложения, например, в командах

    Надеюсь, ответил на все вопросы. Если что-то неясно, спрашивайте
    Ответ написан
    5 комментариев
  • Как использовать proxy для рассылки в telegram с помощью RabbitMQ?

    @imsha
    RabbitMQ - это сервер сообщений между "вашими кусками кода". С помощью какого-то кода вы туда шлете данные в какой-то структуре. "Каким-то куском кода" вы слушаете RabbitMQ, получаете эти данные. Вот там где получаете - там и смотрите, что там за софт, который отправляет сообщения в телеграм. Там и смотрите как настроить прокси, и нужно ли его каждый раз отправлять в данных для очереди RabbitMQ.
    Ответ написан
    Комментировать
  • Подключение css в MVC системе на PHP?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Используйте нормальный шаблонизатор, Twig.

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

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

    Я понимаю что без примера сложно.
    Вот простейший пример того, о чем я писал выше:

    main.twig.html
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
    {% block stylesheets %}
        <link href="/css/main.css" rel="stylesheet">
    {% endblock %}
            <title>{% block title %}Twig Example{% endblock %}</title>
        </head>
        <body>
            {% block content %}{% endblock %}
        </body>
    </html>

    index.twig.html
    {% extends "main.twig.html" %}
    
    {% block content %}
    <h1> index page </h1>
    <li><a href=/page1.php>Page 1</a>
    <li><a href=/page2.php>Page 2</a>
    {% endblock %}

    page1.twig.html
    {% extends "main.twig.html" %}
    
    {% block stylesheets %}
        {{ parent() }}
        <link href="/css/page1.css" rel="stylesheet">
    {% endblock %}
    
    {% block title %}Page 1{% endblock %}
    
    {% block content %}
    <h1> page 1</h1>
    <li><a href=index.php>index</a>
    {% endblock %}
    Ответ написан
    Комментировать
  • Symfony, как безопасно хранить API ключи?

    @Flying
    В Symfony 4.4 будет добавлена возможность безопасного хранения ключей, подробнее в анонсе.
    Ответ написан
    6 комментариев
  • Как правильно удалять при однонаправленном ManyToOne?

    @anton1x Автор вопроса
    В общем вся мишура произошла из-за использования sqlite...
    При переходе на mysql все стало корректно отрабатывать
    Ответ написан
    Комментировать
  • Какую библиотеку использовать для words to number?

    TommyV888
    @TommyV888 Куратор тега PHP
    -
    Сам неделю назад столкнулся с похожим, судя по подпискам вещь нужная, так что выложил в паблик раньше чем планировал:
    https://github.com/LoginovIlya/words-to-numbers
    P.S. Другие языки и нормальный readme будут позже
    Ответ написан
    Комментировать
  • Почему rand() может выдавать очень близкие значения?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Потому что случайные.
    Кому-то здесь надо уяснить для себя смысл этого слова. И явно не одному автору.

    Случайно тут могут оказаться не то что "близкие" а вообще одинаковые значения.
    Ответ написан
    3 комментария
  • Сделать карьеру на PHP: Symphony vs Zend?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Вопрос, как всегда, поставлен жутко неграмотно, так сказать, по деревенски: без какого бы то ни было видения перспективы, хотя бы на 5 лет вперёд.

    Изучать какой-либо современный фреймворк ради *карьеры* - несусветная глупость. 5 лет назад ларавеля не было, а симфони и зенд были в таком виде, что мы бы сейчас обплевались. При том что различия между современными версиями довольно минимальны.

    Это, я не знаю, как спросить "хочу быть столяром, какую отвёртку мне изучать, крестовую или шлицевую?".

    Изучать, ради карьеры, надо столярное ремесло целиком. В данном случае - программирование. Принципы, на которых устроены фреймворки. Одного этого хватит на те же лет 5. Зато потом не будет проблемы адаптироваться к неизбежным изменениям.

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

    И кстати для изучения принципов симфони подходит лучше

    Да - и конечно же, все ответы туда же.
    Один решил меряться количеством скачиваний. Ну если судить по такому критерию, то все перечисленное - букашки, которые копошатся под подошвами Вордпресса, с его присными темами и плагинами.

    Да, и самое главное я тоже забыл сказать. Коллега xfg в самую точку написал в комментарии:

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

    Очень на эту тему прочищают мозги доклады и видео Дмитрия Елисеева. У него на сайте как раз появился доклад с PHP Russia 2019, который я горячо рекомендую.

    На ту же тему был и доклад Томаша Вотрубы, кстати. Что фреймворки, по сути, можно менять как перчатки, при желании. И у него есть даже инструмент для этого. Но в данном случае речь не об инструменте а о том, что фреймворк- далеко не главная часть приложения, и упираться в изучение фреймворков это все равно что в изучение отверток.
    Ответ написан
    4 комментария
  • Нужна помощь с вложенными циклами?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Если читать вопрос словами, которые осилил автор, то
    Есть массив значений, мне требуется выводить элементы массива пока он не кончится,

    $arr = array('Apple', 'Grape', 'Lemon');
    foreach($arr as $znatchenie) {
        echo "$znatchenie<br>";
    }
    echo 'Массив кончился.<br>';


    Если пытаться понять бессмысленный код приведенный в вопросе, то наверное так
    for ($i = 0; $i < 10; $i++) {
        foreach($arr as $znatchenie) {
            echo "$znatchenie<br>";
        }
        echo 'Массив кончился. Продолжаем внешний цикл <br>';
    }

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

    Апдейт.
    Благодаря BoShurik, который выпытал из автора, что ему нужно,

    for ($i = 0; $i < 10; $i++) {
        echo $arr[$i] ?? 'Массив кончился. Продолжаем внешний цикл';
        echo "<br>";
    }

    Вопрос, зачем здесь вложенный цикл, сочтем неуместным.
    Ответ написан
    7 комментариев
  • Как организовать архитектуру проекта с 1000 api?

    Gomonov
    @Gomonov
    Используйте очереди. Консьюмеры, обрабатывающие сообщения из очереди, будут держать соединение с бд, чего Вы так боитесь. Продюсеры могут вызываться из крона (определённое время запуска), а могут и из отдельного воркера (запуски через малые промежутки времени)
    Ответ написан
    Комментировать
  • Архитектура Entities в Doctrine, Symfony 4 - кто может помочь?

    ghost404
    @ghost404
    PHP Developer
    Есть такая штука как предметная область (Domain). Предметная область состоит из моделей (в Doctrine это Entity), сервисов предметной области и много чего ещё.

    На сколько я понимаю из ваших комментариев, у вас есть 3 интерфейса (UI) которые работают с единой предметной областью. В этом случае не нужно дублировать бизнес-логику под каждый интерфейс. Правильней выделить бизнес-логику в отдельный субъект и реиспользовать его в ваших приложениях с интерфейсами.
    Можно организовать код вашей бизнес-логики в самостоятельный модуль, вынести в пакете Composer и оформить как Symfony Bundle, что вы и сделали.

    Если же у вас есть несколько независемых проектов/сайтов у которых схожая предметная область с небольшими отличиями, то я рекомендую не использовать одну реализацию бизнес-логики на все проекты и рекомендую продублировать код во все проекты.
    Поясню. Поначалу, на маленьких проектах кажется хорошей идеей реиспользовать код, но со временем проекты развиваются и развиваются они как правило независимо друг от друга. С развитием отдельных проектов может, и скорей всего будет, изменяться бизнес-логика соответствующих проектов и вам придется вносить изменения в единый код для всех проектов. Таким образом изменения будут применяться не только в том проекте где они нужны, но и в других проектах которым эти изменения не требуются. Это может нарушать бизнес-логику других проектов, приводить к конфликтам и неожиданным ошибкам. Этот подход имеет право на жизнь, но нужно оценивать риски и всё тщательно взвешивать. Моя практика показала, что ни к чему хорошему это не приводит.
    Ответ написан
    Комментировать