All streams
Search
Write a publication
Pull to refresh
29
0
Пётр Грибанов @ghost404

Symfony professional developer

Send message

Не стоит говорить за всех. Я учился на вечерке и все алгоритмы прошли мимо меня, о чем я сейчас жалею.

По собственному опыту скажу что XAMPP не лучшее решение.
Это только базовый веб-сервер.
Потом понадобится поставить Redis, Ruby, Java, SASS, Sphinx, Elasticsearch, APCu.
И весь этот зоопарк поддерживать на винде, никсах и маках.


С точки зрения разработки, Windows имеет массу недостатков. К описанным nitso проблемам, добавлю:


  • тормоза Symfony на винде из-за особенностей файловой системы. APCu и OPcache помогают, но не спасают. Все равно скорость в 3 дольше. Использование встроенного php сервера просто самоубийство.
  • частые проблемы с регистром имен файлов. Изменить регистр имени файла в git приходится делать 2 коммитами.
  • сталкивался с тем, что MySQL в XAMPP работает не так же как и на CentOS и запросы которые на Windows проходили без проблем, ломали боевой сервер. Или данные хранились не в корректном формате.
  • частая ситуация когда на винде все работает, а на никсах нет

Уведомления не доходили потому что нужно было еще прописать messaging.onMessage().


Сейчас все поправил и сделал полноценное приложение с отправкой уведомлений через js

И да, вы правы ограничения есть, однако это не это не равно утверждению "с рефлексией этого сделать нельзя".

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


Предлагаю подвести итоги.
Можно использовать как явное описание списка доступных значений, так и динамически генерируемое с помощью рефлексии. Оба вариант имеют свои плюсы и минусы. Я услышал ваше мнение и признаю, что вариант через рефлексию тоже имеет право на жизнь.

Точно. Вся проблема была в messaging.onMessage(). Теперь я понял почему не работало без него. Добавил обработчик и сразу все, везде заработало.


Спасибо большое.

я с этим не согласился и потом вы мне приводите именно пример что можно! Что то пошло не так?

Как раз я привожу пример что нельзя. myclabs/php-enum воспринимает константы с описанием как варианты значения. Тоесть метод Action::toArray() вернет TITLE_VIEW, что не корректно. Можно объявить TITLE_VIEW как не константу, но это все ухищрения чтоб угодить инструменту, а не бизнесу.


Хорошее решение этой проблемы предлагает библиотека marc-mabe/php-enum, которая воспринимает только публичные константы, но нужен PHP 7.1.


в случая же 2 вы как то сразу схитрили. Зачем метод делать final public static?

Да, схитрил. Естественно. Потому что с точки зрения бизнеса не должно быть final и не final методов. Весь объект должен быть final. А если инструмент требует помечать методы как final, то я вынужден и остальные методы тоже помечать как final, чтоб защитить класс.


Я хочу сказать, что используя подход с рефлексией, мы получаем автоматизацию генерации списка доступных значений (Action::choices()), и в тоже время некоторые ограничения на использование методов или констант.
Создав один метод Action::choices() вручную, мы сохраним все те же самые функции, но не будем иметь ограничений накладываемых рефлексией.

Спасибо. Добавил ссылки в статью

Это почему нельзя? что мне помешает?

Пример на основе того же myclabs/php-enum. Я добавляю человеческое описание для вывода на frontend


class Action extends Enum
{
    const VIEW = 'view';
    const EDIT = 'edit';

    // константы воспринимаются как варианты значения
    // формат предназначен для перевода
    const TITLE_VIEW = 'acme.demo.action.view';
    const TITLE_EDIT = 'acme.demo.action.edit';

    // можно использовать для radio/checkbox/select
    public static function choices()
    {
        return [
            self::VIEW => self::TITLE_VIEW,
            self::EDIT => self::TITLE_EDIT,
        ];
    }

    public function title()
    {
        return static::choices()[$this->getValue()];
        // можно былоб писать проще и не создавать метод choices,
        // но тогда такую конструкцию тяжелее использовать для radio/checkbox/select
        //return 'acme.demo.action.'.$this->getValue();
    }
}

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


Пример на основе antanas-arvasevicius/enumerable-type. Я добавляю свои методы для бизнеслогики


class Action extends EnumerableType
{
    final public static View()
    {
        return static::get('view');
    }

    final public static Edit()
    {
        return static::get('edit');
    }

    // воспринимается как вариант значения
    final public static equals(Action $action)
    {
        return $this->id() === $action->id();
    }
}

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


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

Форкнул репозиторий и открыл на GitHub Pages. Протестировал через curl в Chrome и Firefox на Windows. Результат, мягко говоря, ошеломляет.


В Chrome все доходит как и должно и уведомление отображается. В Firefox уведомление тоже доходит, но не отображается. Отрабатывает метод messaging.onMessage() на странице и печатает тело уведомления в блоке #messages. Через fetch я получил тот же результат. В Chrome этот метод не отрабатывает.


Получается в Firefox нужно использовать метод messaging.onMessage() и в нем реализовывать показ уведомления вручную. Поскольку этот метод реализован на странице, а не в Service Worker, то мы сталкиваемся с рядом проблем:


  • Нельзя получить уведомление если сайт не открыт в данный момент;
  • Нельзя получить уведомление при закрытом браузере;
  • Если сайт открыт в нескольких вкладках, то скрипт отрабатывает во всех вкладках.

Это лишь результаты беглого осмотра. Возможно я что-то упустил. У вас другие результаты?


И спасибо за ссылку. Добавил в статью.


PS: Странно то что у меня и без messaging.onMessage() в Firefox уведомления иногда отображались.

не очень понял вопрос.


Значение, для свойства объекта доменной области, может быть перечисление (enum). Для контроля за этим перечислением его удобно описать в виде объекта значения (ValueObject). Получается что-то вроде:


$my_type = TicketType::priority();
if ($ticket->type()->equals($my_type)) {
}

или так


if ($ticket->type()->isPriority()) {
}

Посмотрел код проекта. Оказалось все еще хуже чем я думал. Список доступных значений для ENUM получается с помощью рефлексии наследующего класса. Метод valueToString вообще мастерский говнокод.


Я ENUM в PHP рассматриваю как ValueObject и отношусь к нему соответствующе. В сущностях храню сам объект, а не его значение, список доступных значений описываю в явном виде и добавляю методы необходимыми для бизнеслогики.

А нам придется перед каждой функцией и константой писать слеш. Этож сколько проектов начнет заваливать логи нотисами, а потом и вовсе упадет. Тогда уж и для функций языка нужно вводить неймспайсы.

На официальном сайте Firebase, в разделе цены, вполне четко описано какие услуги платные, а какие нет


Included Free
Analytics, App Indexing, Authentication, Cloud Messaging, Crash Reporting, Dynamic Links, Invites, Notifications & Remote Config

push-уведомления относятся к категории бесплатных услуг.
Еще раз. С чего вы решили что уведомления платные?

Можно. Работает: https://gauntface.github.io/simple-push-demo/.
Работают. Проверял на Windows и Android.

Как мне уже объяснил iSage и я сам об этом подозревал — это Firebase не может отправлять уведомления, а если реализовывать push-уведомления нативными средствами, то все работает. Что у вас и сделано.


А жаль, там много интересного. ) Думаю, я созрел для своей первой статьи для Хабра. :)

Я вижу что описанного материала многим недостаточно. И хотел бы написать статью/продолжение в которой описать больше технических тонкостей и альтернативных реализаций.
Готов уступить вам эту тему.

push-уведомления через Firebase бесплатные. Не знаю с чего вы взяли что за них нужно платить. Если использовать сторонние сервисы для отправки уведомлений такие как OneSignal и PushAll, то естественно это будет стоит денег, о чем я писал в одном из комментариев.


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

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


Некоторые тестируют отправляемые и доставляемые email сообщения поднимая тестовый SMTP сервер. Так и тут. Никто не мешает, при желании, поднять тестовый Service Worker и тестировать уведомления через него.


Тестировать работу самого Service Worker-а уже сложнее так как он работает вне контекста текущей страницы.

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

Раз пошла такая тема. Нужно определится на чем написан сайт и бизнес логика проекта. Бизнес логика это самое важное в проекте и она определяет как отреагировать на то или иное событие.


Если проект написан на Go, то логично и уведомления отправлять через Go.


Если проект написан на PHP (как это часто бывает), то можно завести вторую очередь. Первая хранит события, а вторая уже готовые уведомления которые нужно отправить. А вот в качестве транспорта для отправки уведомлений из второй очереди, можно в этом случае использовать микросервисы на Go.


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

Information

Rating
Does not participate
Location
Россия
Registered
Activity