По собственному опыту скажу что XAMPP не лучшее решение.
Это только базовый веб-сервер.
Потом понадобится поставить Redis, Ruby, Java, SASS, Sphinx, Elasticsearch, APCu.
И весь этот зоопарк поддерживать на винде, никсах и маках.
С точки зрения разработки, Windows имеет массу недостатков. К описанным nitso проблемам, добавлю:
тормоза Symfony на винде из-за особенностей файловой системы. APCu и OPcache помогают, но не спасают. Все равно скорость в 3 дольше. Использование встроенного php сервера просто самоубийство.
частые проблемы с регистром имен файлов. Изменить регистр имени файла в git приходится делать 2 коммитами.
сталкивался с тем, что MySQL в XAMPP работает не так же как и на CentOS и запросы которые на Windows проходили без проблем, ломали боевой сервер. Или данные хранились не в корректном формате.
частая ситуация когда на винде все работает, а на никсах нет
И да, вы правы ограничения есть, однако это не это не равно утверждению "с рефлексией этого сделать нельзя".
Если ограничения не позволяют нам что-то сделать, значит это сделать нельзя. Разве нет?
Если ограничения накладываются в результате использования рефлексии, то значит "с рефлексией этого сделать нельзя".
Вроде все логично.
Предлагаю подвести итоги.
Можно использовать как явное описание списка доступных значений, так и динамически генерируемое с помощью рефлексии. Оба вариант имеют свои плюсы и минусы. Я услышал ваше мнение и признаю, что вариант через рефлексию тоже имеет право на жизнь.
я с этим не согласился и потом вы мне приводите именно пример что можно! Что то пошло не так?
Как раз я привожу пример что нельзя. 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)) {
}
Посмотрел код проекта. Оказалось все еще хуже чем я думал. Список доступных значений для ENUM получается с помощью рефлексии наследующего класса. Метод valueToString вообще мастерский говнокод.
Я ENUM в PHP рассматриваю как ValueObject и отношусь к нему соответствующе. В сущностях храню сам объект, а не его значение, список доступных значений описываю в явном виде и добавляю методы необходимыми для бизнеслогики.
А нам придется перед каждой функцией и константой писать слеш. Этож сколько проектов начнет заваливать логи нотисами, а потом и вовсе упадет. Тогда уж и для функций языка нужно вводить неймспайсы.
Как мне уже объяснил iSage и я сам об этом подозревал — это Firebase не может отправлять уведомления, а если реализовывать push-уведомления нативными средствами, то все работает. Что у вас и сделано.
А жаль, там много интересного. ) Думаю, я созрел для своей первой статьи для Хабра. :)
Я вижу что описанного материала многим недостаточно. И хотел бы написать статью/продолжение в которой описать больше технических тонкостей и альтернативных реализаций.
Готов уступить вам эту тему.
push-уведомления через Firebase бесплатные. Не знаю с чего вы взяли что за них нужно платить. Если использовать сторонние сервисы для отправки уведомлений такие как OneSignal и PushAll, то естественно это будет стоит денег, о чем я писал в одном из комментариев.
CDN естественно стоит денег. Если вы разместите статику на своих серверах, то это уже будет не CDN, а если вы начнете строить свою сеть CDN, то это выйдет дороже для большинства проектов.
Ну как сказать не автоматизируется. Уведомления это как email сообщения. Они работают через сторонние сервисы. Вопрос осмысленности такого тестирования я не поднимаю.
Некоторые тестируют отправляемые и доставляемые email сообщения поднимая тестовый SMTP сервер. Так и тут. Никто не мешает, при желании, поднять тестовый Service Worker и тестировать уведомления через него.
Тестировать работу самого Service Worker-а уже сложнее так как он работает вне контекста текущей страницы.
1. Заметь, я же нигде не говорил, что очередь не нужна. Но даже в фоне разбирать события курлом — плохой вариант.
Раз пошла такая тема. Нужно определится на чем написан сайт и бизнес логика проекта. Бизнес логика это самое важное в проекте и она определяет как отреагировать на то или иное событие.
Если проект написан на Go, то логично и уведомления отправлять через Go.
Если проект написан на PHP (как это часто бывает), то можно завести вторую очередь. Первая хранит события, а вторая уже готовые уведомления которые нужно отправить. А вот в качестве транспорта для отправки уведомлений из второй очереди, можно в этом случае использовать микросервисы на Go.
В этом случае мы можем потерять в производительности из-за 2 очередей, но зато логика будет прозрачной.
Не стоит говорить за всех. Я учился на вечерке и все алгоритмы прошли мимо меня, о чем я сейчас жалею.
Я кинул пару PR в myclabs/php-enum, может вам пригодится
По собственному опыту скажу что XAMPP не лучшее решение.
Это только базовый веб-сервер.
Потом понадобится поставить Redis, Ruby, Java, SASS, Sphinx, Elasticsearch, APCu.
И весь этот зоопарк поддерживать на винде, никсах и маках.
С точки зрения разработки, Windows имеет массу недостатков. К описанным nitso проблемам, добавлю:
Уведомления не доходили потому что нужно было еще прописать messaging.onMessage().
Сейчас все поправил и сделал полноценное приложение с отправкой уведомлений через js
Если ограничения не позволяют нам что-то сделать, значит это сделать нельзя. Разве нет?
Если ограничения накладываются в результате использования рефлексии, то значит "с рефлексией этого сделать нельзя".
Вроде все логично.
Предлагаю подвести итоги.
Можно использовать как явное описание списка доступных значений, так и динамически генерируемое с помощью рефлексии. Оба вариант имеют свои плюсы и минусы. Я услышал ваше мнение и признаю, что вариант через рефлексию тоже имеет право на жизнь.
Точно. Вся проблема была в
messaging.onMessage()
. Теперь я понял почему не работало без него. Добавил обработчик и сразу все, везде заработало.Спасибо большое.
Как раз я привожу пример что нельзя. myclabs/php-enum воспринимает константы с описанием как варианты значения. Тоесть метод
Action::toArray()
вернетTITLE_VIEW
, что не корректно. Можно объявить TITLE_VIEW как не константу, но это все ухищрения чтоб угодить инструменту, а не бизнесу.Хорошее решение этой проблемы предлагает библиотека marc-mabe/php-enum, которая воспринимает только публичные константы, но нужен PHP 7.1.
Да, схитрил. Естественно. Потому что с точки зрения бизнеса не должно быть
final
и неfinal
методов. Весь объект должен бытьfinal
. А если инструмент требует помечать методы какfinal
, то я вынужден и остальные методы тоже помечать какfinal
, чтоб защитить класс.Я хочу сказать, что используя подход с рефлексией, мы получаем автоматизацию генерации списка доступных значений (
Action::choices()
), и в тоже время некоторые ограничения на использование методов или констант.Создав один метод
Action::choices()
вручную, мы сохраним все те же самые функции, но не будем иметь ограничений накладываемых рефлексией.Спасибо. Добавил ссылки в статью
Пример на основе того же myclabs/php-enum. Я добавляю человеческое описание для вывода на frontend
Можно не добавлять префикс для значения, но тогда теряется контекст. Одно и то же значение в разном контексте может по разному переводится.
Пример на основе antanas-arvasevicius/enumerable-type. Я добавляю свои методы для бизнеслогики
Можно реализовать все тоже самое кеширование и прочие радости без рефлексии, явным образом реализовав метод или свойство которые возвращают список доступных значений.
Также можно добавить методы необходимые для бизнес логики и человеческое описание для вариантов значения для вывода на 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). Получается что-то вроде:
или так
Посмотрел код проекта. Оказалось все еще хуже чем я думал. Список доступных значений для ENUM получается с помощью рефлексии наследующего класса. Метод valueToString вообще мастерский говнокод.
Я ENUM в PHP рассматриваю как ValueObject и отношусь к нему соответствующе. В сущностях храню сам объект, а не его значение, список доступных значений описываю в явном виде и добавляю методы необходимыми для бизнеслогики.
А нам придется перед каждой функцией и константой писать слеш. Этож сколько проектов начнет заваливать логи нотисами, а потом и вовсе упадет. Тогда уж и для функций языка нужно вводить неймспайсы.
Вы похоже перепутали Firebase Realtime Database и Firebase Cloud Messaging.
На официальном сайте Firebase, в разделе цены, вполне четко описано какие услуги платные, а какие нет
push-уведомления относятся к категории бесплатных услуг.
Еще раз. С чего вы решили что уведомления платные?
Как мне уже объяснил iSage и я сам об этом подозревал — это Firebase не может отправлять уведомления, а если реализовывать push-уведомления нативными средствами, то все работает. Что у вас и сделано.
Я вижу что описанного материала многим недостаточно. И хотел бы написать статью/продолжение в которой описать больше технических тонкостей и альтернативных реализаций.
Готов уступить вам эту тему.
push-уведомления через Firebase бесплатные. Не знаю с чего вы взяли что за них нужно платить. Если использовать сторонние сервисы для отправки уведомлений такие как OneSignal и PushAll, то естественно это будет стоит денег, о чем я писал в одном из комментариев.
CDN естественно стоит денег. Если вы разместите статику на своих серверах, то это уже будет не CDN, а если вы начнете строить свою сеть CDN, то это выйдет дороже для большинства проектов.
Ну как сказать не автоматизируется. Уведомления это как email сообщения. Они работают через сторонние сервисы. Вопрос осмысленности такого тестирования я не поднимаю.
Некоторые тестируют отправляемые и доставляемые email сообщения поднимая тестовый SMTP сервер. Так и тут. Никто не мешает, при желании, поднять тестовый Service Worker и тестировать уведомления через него.
Тестировать работу самого Service Worker-а уже сложнее так как он работает вне контекста текущей страницы.
Раз пошла такая тема. Нужно определится на чем написан сайт и бизнес логика проекта. Бизнес логика это самое важное в проекте и она определяет как отреагировать на то или иное событие.
Если проект написан на Go, то логично и уведомления отправлять через Go.
Если проект написан на PHP (как это часто бывает), то можно завести вторую очередь. Первая хранит события, а вторая уже готовые уведомления которые нужно отправить. А вот в качестве транспорта для отправки уведомлений из второй очереди, можно в этом случае использовать микросервисы на Go.
В этом случае мы можем потерять в производительности из-за 2 очередей, но зато логика будет прозрачной.