• Как правильно построить архитектуру Symfony 4?

    @dreamerz
    Как я собираю проэкт Симфонии
    composer self-update
    composer require symfony/symfony-skeletone (требует лимит мемори для пхп свыше 1800М)
    Никогда неделайте ничего при старте вручную - Первое правило =)
    Если Вам вдруг нужна авторизация из-корробки -
    php bin/console make:auth
    Первый Ваш контроллер
    php bin/console make:controller
    > MyShopController
    Нужен класс для связи с БД
    php bin/console make:entity
    > Shop
    в процессе Вам напишут что Реппозиторий создался автомматически
    Мы забыли про БД! Непугайтесь сделайте ещё пару комманд)
    php bin/console doctrine:database:create
    Теперь можно выгружать таблицы:
    php bin/console make:migration
    Теперь чтобы увидеть таблицы в самой БД скажем комманду
    php bin/console doctrine:migrations:migrate
    Вуаля - это Магия Симфонии)

    Если что - обращайтесь

    Если конкретно по-вопросу -
    У меня роутер выглядит так:
    app_product
    path: /product/{slug}/{action}
    controller: App\Controller\ProductController:indexAction

    По ссылке /product/update/#id
    POST ajax request
    ProductController:
    $post = $request->request->all(); // все POST запросы
    $product = new Product;
    $product->setPrice($post['price']);
    ...
    /product/show/#id
    Загружается страничка с продуктом.
    Это конкретный пример логики
    Ответ написан
  • В чем преимущества ValueObject и DTO?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Преимущество VO в том, что это значения, которые уже проверены на границы и тип. В вашем примере валидация происходит в геттере - это мягко говоря бессмысленно. Вот вам пример
    class UUID
    {
        /** @var string */
        private $value;
    
        /**
         * @param string $value
         */
        public function __construct(string $value)
        {
            if (!preg_match('/^[\da-f]{32}$/', $value)) {
                throw new \InvalidArgumentException(
                    sprintf('Argument "$value" must be correct UUID, actual value: "%s"', $value)
                );
            }
            
            $this->value = $value;
        }
    
        /**
         * @return string
         */
        public function getValue(): string
        {
            return $this->value;
        }
    }


    Дальше в коде вам достаточно делать type hinting на тип VO и все, значение будет корректным. От рефлексии, или runkit вы все равно защититься не сможете.

    -- --

    DTO - это штука, для удобного транспорта данных, между разными частями системы. Например у вас есть метод, который на вход принимает 20+ аргументов (например регистрация), вызывать такое кодло вероятно будет не удобно, но собрав dto вы можете его передать одним аргументом и рассчитывать на то, что данные переданы с правильными типами. Граничные же значения придется проверить, так как в задачу "транспорта" не входит контроль правильности данных между системами, что его используют.

    но вот внутри в тех частях логика которых фиксирована и не может меняться - вполне подходит массив ключ-значение

    Использование KV в контексте DTO/VO - дико хреновая практика, в очень редких кейсах ее использование оправдывает себя. Дело в том, что массив - это набор произвольных данных. Что бы писать надежный код - вам придется на каждом этапе делать проверку правильности этого массива. Что это за проверки?
    * все нужные ключи существуют
    * все значения по этим ключам правильных типов
    * массив не содержит левых данных

    как реализовать на php типизированую коллекцию типа как в СИ

    class MyTypedCollection implements \Countable, \IteratorAggregate, \ArrayAccess
    ...
    Ответ написан
    2 комментария
  • Как разбить транзакцию по микросервисам сохранив консистентность данных?

    angrySCV
    @angrySCV
    machine learning, programming, startuping
    то что вы описали называется двухФазным комитом, раньше очень часто использовался.
    сейчас активнее используют похожий но немного другой подход, тоже связанный с тем что резервируют определенные ресурсы (например деньги на счету, и товар на складе) потом проверяют промежуточный статус операции, и потом проводят и подтверждают операцию - разница в том что ничего не перезаписывается а непрерывно все запросы логируется, и любые откаты операции идут через добавление новых записей-запросов в лог (он же и очередь сообщений)
    ----
    там много тонкостей, например вы говорили про время-метки, в целом метки времени добавляют - если нужно контролировать очередность промежуточных шагов (но обычно это не так важно, поэтому метку времени не всегда добавляют), но добавляют уникальный айди операции, тк в случае сбоя запроса (при например длительном ожидания ответа), может произойти "переотправка" запроса, и нам эта метка с уникальным айди позволяет не дублировать одну и туже операцию.
    =====
    есть тонкости например с тем, каким образом разделены эти микросервисы, может это просто дублирование одного и того же сервиса но например каждый из них обрабатывает запросы от разных сегментов пользователей, поэтому не требуется согласовывать какие-то операции между этими микросервисами.
    ====
    на мой взгляд - это вобще разводные вопросы не имеющие правильного ответа, схемы подбираются конкретно под проект и задачи, тем более если вы не разрабатывали какую-нибудь платежную систему, типа яндекс.денег то вообще бесполезно что-то обсуждать.
    это не камень в ваш огород, этим вообще обычно мало кто реально занимается, уверен те кто у вас это спрашивал сами мало что в этом понимают, а спрашивают такие вещи чтоб вас слить.
    Ответ написан
    3 комментария
  • Как обновить тип поля в маппинге elasticsearch?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Разочарую - мапинг обновить нельзя! Можно только добавлять новые поля.
    Ваши действия - делаем новый индекс с правильным мапингом до заливки данных в этот индекс, переливаем туда старые данные, например через _reindex api - https://www.elastic.co/guide/en/elasticsearch/refe...
    И да, агрегации с разными типами одного поля работать не будут.

    Как создать мапинг? Отдельная песнь - описана в подробностях здесь - https://www.elastic.co/guide/en/elasticsearch/refe...
    Обычно делается перед заливкой данных. Там еще кроме мапинга есть settings - отже отдельная песнь.
    Ответ написан
    4 комментария
  • Как понять БЭМ, и что мотивирует верстальщик в использовании его?

    Wolfnsex
    @Wolfnsex Куратор тега Веб-разработка
    Если не хочешь быть первым - не вставай в очередь!
    Мне как back-end - щику трудно ужиться с этим БЭМ - ом.
    Вам это совершенно не обязательно делать.

    Зачем БЭМ когда есть SASS/SCSS/LESS.
    Что-то из серии "Зачем мне холодильник, если я не курю", ну вы понимаете... :)

    Шесть классов для простого button в регистрации.
    Такого эффекта можно добиться и без БЭМ.

    У меня код в IDE от JetBrains уходит далеко за белую полосу.
    Обычно это решается с помощью комбинации Ctrl+Alt+L в IDE от JetBrains.

    "Это бэм, я использую один стиль несколько раз и т.д".
    БЭМ придумали не для того, что бы "использовать один стиль несколько раз", если почитать историю, то БЭМ был создан для решения вполне конкретных задач, о них Вы в принципе можете прочесть на оф. сайте БЭМа (не рискну перечислять самостоятельно, дабы не исковеркать смысл).

    почему ты не можешь через родителя добираться к дочернему элементу ? где лаконичность ? где миксины ? почему ты не делаешь наследовать классов в своем SCSS ?
    Не знаю :)

    Так по мне БЭМ это вообще огромный костыль а не методология.
    Отчасти Вы правы, но лишь от части. От "насколько большой части" - сказать трудно. Всё зависит от Вашего восприятия и субъективной реальности происходящего. Колоть монитором орехи - "большой костыль", но не от того, что монитор плохой, монитор хороший, но он создан для решения несколько других задач. Так же и БЭМ создавался для решения задач, с которыми он более ли менее успешно справляется. Проблема тут не в самом БЭМе, а в том, что толпы верстальщиков (сомнительного качества) кинулись "за новомодной соской"... как в басне Крылова - "Мартышка и очки", применять этот самый БЭМ там где надо и не надо. Препроцессор, например, SASS - это круто. Но это не значит, что для стиля "в 3 селектора" нужно за собой тащить целый препроцессор, нужно понимать, когда он действительно нужен, а когда CSS < 1Кб и можно обойтись "руками" (без препроцессоров).

    БЭМ - это не только методология, но и ряд других инструментов, без которых он как по мне (*исключительно личное умозаключение, на истину не претендует), примерно настолько же полезен, насколько полезен SASS без своего "компилятора". Есть масса способов написать код лучше не хуже чем с применением БЭМ, которые вполне себе успешно работают в своём контексте.

    P.S. Я не однократно встречал т.н. "БЭМ" код в проектах, где он вообще ни в какую не упёрся, но этом обусловлено не тем, что "БЭМ плохой", а тем, что верстальщик не может принимать оптимальных решений. Это выглядело как если бы, человек научился пользоваться пассатижами и побежал бы ими делать "всё", и колоть орехи и забивать гвозди и снимать кастрюлю с плиты, что бы не обжечься.
    Ответ написан
    Комментировать
  • Дает ли строгая типизация в PHP 7 прирост производительности?

    Начал писать ответ комментарий https://toster.ru/answer?answer_id=937197, но ответ получился большим и поэтому решил поместить его отдельно.

    DevMan , я попробую уточнить ваше утверждение, что немного снижает.
    На самом деле, при использовании скалярных тайпхинтов снижается производительность вызова функций, поскольку возникает некий дополнительный оверхед на валидацию аргументов и приведение значений к нужным типам (если не используется strict_types). Но! Так как внутри функции значения аргументов уже приведены к нужным типам, то при использовании аргументов не происходит неявного приведения типа.
    Поясню на синтетическом примере:
    function foo($x) {
        $result = 0;
        for ($i = 0; $i < 100; $i++) {
            $result += $i + $x;
        }
        return $result;
    }


    Если вызвать эту функцию так: "foo('123')", то в таком случае внутри цикла аргумент будет неявно приводится к целому числу 100 раз. Если вызвать функцию так: "foo(123)", то в таком случае аргумент не будет внутри цикла приводится к целому числу. Очевидно, что второй вариант более производительный:
    ~$ time php70 -r 'function foo($x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo("123");'
    
    real    0m0.860s
    user    0m0.855s
    sys     0m0.005s

    ~$ time php70 -r 'function foo($x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo(123);'
    
    real    0m0.508s
    user    0m0.500s
    sys     0m0.008s


    В то же самое время, если добавить к аргументу скалярный тайпхинт, то тогда значение аргумента один раз будет приведено к тайпхинту и внутри функции уйдёт весь оверхед связанный с неявным приведением типа:
    ~$ time php70 -r 'function foo(int $x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo("123");'
    
    real    0m0.502s
    user    0m0.498s
    sys     0m0.003s

    ~$ time php70 -r 'function foo(int $x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo(123);'
    
    real    0m0.504s
    user    0m0.495s
    sys     0m0.008s


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

    Зато использование строгой типизации не даст запустить функцию в неконтроллируемом состоянии: когда функция ожидает на вход целое число, а по какой-то причине подсунули массив:
    $var = $_GET['foo'];
    bar($var);
    , для get-параметра foo=123 вызов будет корректным, а для foo[]=123 вызов функции приведёт к TypeError; для foo=abc тоже будет TypeError. Разумеется, этот пример сильно надуман и тут нужно использовать "нормальный" валидатор.
    Ответ написан
    1 комментарий
  • Как в настоящее время обстоят дела с keywords у поисковиков?

    kopcap_va
    @kopcap_va
    SEO Consultant
    А что тут аргументировать? Сейчас основные поисковые системы без труда оценивают содержание страниц самостоятельно, раньше тег им в этом помогал, а теперь потерял свою актуальность.
    Ответ написан
    Комментировать
  • Как правильно реализовать локализацию БД в laravel?

    wielski
    @wielski
    ✔ Совет: Вам помогли? Отметьте ответы решением.
    На мой взгляд использование пакетов для этой цели нецелесообразно.
    Обычная полиморфическая связь подойдет.

    И так, давайте представим что основной контент статьи на русском языке.
    Во первых, создадим модель нашей локализации:
    php artisan make:model Localization

    Укажем что это полиморфическая связь:
    protected $table = 'localization';
    
    public function lozalizable()
      {
          return $this->morphTo();
      }


    В нашей модели статей привяжем свежесозданную модель в качестве связи:
    public function lozalization(){
    	    return $this->morphOne('App\Localization', 'lozalizable');
    	}


    И создадим миграцию для модели Lozalizable:
    Schema::create('localization', function (Blueprint $table) {
            $table->increments('id');
            $table->string('field');
            $table->string('language');
            $table->string('value');
            $table->string('lozalizable_type');
            $table->integer('lozalizable_id');
            $table->timestamps();
          });


    Теперь, для создания локализации статьи с языком en выполним следующий код:
    $article = Article::create($Atricle);
    
    $localization = new Localization;
    $localization->language = 'en';
    $localization->field = 'content';
    $localization->value = 'Znachenye na english yazike';
    $article->localization()->save($localization); //привязываем к свежесозданному объекту Article новую локализацию


    С помощью scope функций в модели можно без особых проблем реализовать более удобное выдергивание нужного значения и языка:
    public function scopeGetLocalize($language, $field){
         return $this->localization()->where(['language' => $language, 'field' => $field])-> firstOrFail()->value;
    }


    В таком случае, скажем, поле title для локализации en можно выдергивать так:
    $article->getLocalize('en', 'title')
    Ответ написан
    19 комментариев
  • Как решить проблему с зависимостями в composer?

    SamDark
    @SamDark
    Yii2 core team
    composer global require "fxp/composer-asset-plugin:~1.1.1"


    www.yiiframework.com/doc-2.0/guide-start-installat...
    Ответ написан
    Комментировать
  • Дерево категорий Laravel. Как уменьшить количество запросов в БД?

    ThunderCat
    @ThunderCat Куратор тега MySQL
    {PHP, MySql, HTML, JS, CSS} developer
    Выбирать все одним запросом и строить дерево рекурсивной функцией, если еще пхп не забыли.
    пример
    Ответ написан
    5 комментариев