• Как происходит загрузка cms(framework) Joomla 3.9 по шагам? Какие SQL запосы и в какой последовательности выполняются и после загрузки каких файлов?

    @Flying
    Ничто не даст вам так много знаний об устройстве и работе кода как вдумчивое хождение по нему с отладчиком.

    Так что просто возьмите тот же PHPStorm, настройте там отладку через XDebug и потратьте день на то чтобы походить по коду, пройтись с самого начала. В результате вы начнёте лучше понимать код с которым работаете, при этом это будет ваше собственное, прямое, знание, а не знание почерпнутое из внешних источников.
    Ответ написан
    Комментировать
  • Symfony 4 autowiring и наследование?

    @Flying
    Поскольку вы наследуете свой класс от абстрактного класса - иницализация parent'а - ваша прямая обязанность (см. сноску после первого абзаца). Таким образом, если абстрактный класс принимает свои зависимости через конструктор - вам необходимо принимать их же и передавать выше по иерархии наследования.

    Т.е. если абстрактный класс выглядит как:
    abstract class AbstractExample 
    {
      public function __construct(Foo $foo, Bar $bar) 
      {
      }
    }

    а вам необходима ещё дополнительная зависимость Baz $baz, то ваш конструктор должен выглядеть примерно так:
    class MyExample extends AbstractExample 
    {
      public function __construct(Foo $foo, Bar $bar, Baz $baz) 
      {
        parent::__construct($foo, $bar);
        // ... и далее ваша логика ...
      }
    }
    Ответ написан
    Комментировать
  • Что из препроцессоров вы используете?

    @Flying
    Использую по возможности всё что есть в Sass и хотелось бы видеть в нём больше. Активно использую и переменные и миксины и функции и placeholder'ы и list'ы и map'ы и т.п. Многие практические задачи намного легче решаются через препроцессор, те же CSS variables ни разу не замена.

    Конечно для того чтобы код не превратился в кровавое месиво - необходимо соблюдать правила, но это справедливо и для любого другого языка программирования. Да и без использования препроцессоров я видел огромное количество write only css который невозможно нормально поддерживать.

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

    С другой стороны наличие определённой архитектуры и следование ей в проекте даёт возможность относительно безболезненного рефакторинга стилей и оставляет код стилей поддерживаемым и расширяемым. Препроцессоры здесь только на пользу.
    Ответ написан
    Комментировать
  • Doctrine: как указать, что в БД тип поля не тот, что в сущности?

    @Flying
    Лезть в исходники mapping'ов для entities в Doctrine явно не стоит т.к. Doctrine поддерживает несколько вариантов задания mapping'а и никто заранее не скажет вам какой источник (или источники) используются - это определяется конфигурацией Doctrine.

    Стандартным способом работы с mapping'ами в runtime является ClassMetadata API. Получить доступ к class metadata factory можно через EntityManager::getMetadataFactory() либо, если вас интересует конкретный entity - через EntityManager::getClassMetadata().

    Объект ClassMetadataInfo содержит информацию обо всех деталях mapping'а конкретной entity. Большинство его properties объявлено как public для более быстрого доступа, хотя писать туда, разумеется, запрещено.

    Класс весьма большой, так что проще всего посмотреть на его содержимое либо в отладчике либо через какой-нибудь dump. Конкретно mapping'и полей находятся в переменной $fieldMappings.
    Ответ написан
    7 комментариев
  • Как запустить браузер на хостинге?

    @Flying
    Ответ написан
    Комментировать
  • Почему WP выводит код на страницу после переноса?

    @Flying
    short_open_tag=on
    в php.ini
    Ответ написан
    Комментировать
  • Каким способом можно сделать PARSER в Symfony?

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

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

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

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

    @Flying
    https://www.w3.org/Style/CSS/ здесь много всего интересного, скучно не будет.
    ну или хотя бы здесь: https://developer.mozilla.org/en-US/docs/Web/CSS
    Ответ написан
    1 комментарий
  • Как остановить местное время и запустить время по координатам?

    @Flying
    Ошибка довольно очевидна, хотя и размазана по коду. Однако причина её появления - в том что вы плохо понимаете те механизмы которые пытаетесь использовать. Другими словами это ошибка не техническая, а ошибка от недостатка знаний.

    Ваш текущий код работает по причине того что вы используете неявное создание нового объекта на каждый вызов через указание new Date() в качестве значения по-умолчанию. Это значение по-умолчанию вас и сбивает с толку т.к. оно выглядит как своеобразный генератор значений, хотя по факту им не является.

    Кроме того await date тоже по факту работает не совсем так как вы (скорее всего) ожидаете. Из MDN: "If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise." Таким образом const currDate = await date в вашем случае эквивалентно const currDate = date.

    Далее, следите за руками:

    Сначала вы передаёте в setInterval функцию без дополнительных аргументов. Она работает по причинам, описанным выше.

    Затем вы передаёте в setInterval() значение вызова setSearchTime() третьим аргументом (т.е. аргументом для интервальной функции). При этом, как вы сами пишете - функция setSearchTime() у вас возвращает Promise что по определению - обещание вернуть одно значение.

    Таким образом когда вы передаёте этот третий аргумент - ваша функция начинает получает значение аргумента date (т.е. перестаёт отрабатывать генерация значения по-умолчанию). При первом вызове ваш Promise, переданный в качестве аргумента в интервальную функцию, переходит в состояние fulfilled и отдаёт значение, но дальше этого уже не будет происходить т.к. Promise уже в состоянии fulfilled, так что вы будете всегда получать одно и то же значение. Однако это будет происходить не потому что setInterval не работает, а потому что вы и передаёте одно значение.

    Если вы (сами или из описания выше) понимаете как всё это работает на самом деле - то решение проблемы становится очевидным: вам всего лишь нужно передавать в вашу функцию setCurrTime не значение времени, а функцию-генератор времени. Тогда её вызов на каждой итерации будет приводить к созданию нового значения времени и всё начнёт работать.

    Также пара замечаний которые не относятся непосредственно к вашему вопросу, но являются важными:
    1. Ваша функция отображает время с точностью до минуты, но вызывается каждые 100 миллисекунд. Таким образом она 600 раз генерирует одно и то же значение что, очевидно, неразумно
    2. Сама функция преобразования времени у вас не показана, но важно чтобы эта функция не опиралась на setInterval в качестве источника информации о количестве прошедшего времени. Вместо этого вы должны всегда отталкиваться от new Date() и модифицировать этот объект. В качестве примера почему так попробуйте себе представить что компьютер с браузером в котором запущен ваш скрипт, был отправлен в гибернацию на какое-то время, а потом вернулся назад
    Ответ написан
    8 комментариев
  • Как вам такое решение задачки?

    @Flying
    Можно воспользоваться тем фактом что в JavaScript в reduce()передаётся текущий индекс и сам массив, это позволяет упростить backreference. В итоге у меня получилось нечто подобное:
    /**
     * @param {Array} list
     * @return {string}
     */
    const range = list => list
        .sort((a,b) => a - b)
        .reduce((r, v, i, a) => {
            if (i > 0 &&  v - a[i - 1] === 1) {
                let l = r.pop();
                l.push(v);
                r.push(l);
            } else {
                r.push([v]);
            }
            return r;
        }, [])
        .map(v => v.length > 1 ? `${v.shift()}-${v.pop()}` : v)
        .join(', ');

    Кусок с pop/push можно ускорить за счёт усложнения обращения к массивам, но так код получается выразительнее.

    Отдельное спасибо Дмитрий за .sort((a,b) => a - b) - не знал
    Ответ написан
  • Почему советуют не выбирать yii2 для разработки?

    @Flying
    Даже если не учитывать массу очень дельных аргументов в других ответах - начинать новые проекты на Yii2 не стоит уже по той причине что 2-я версия уже почти два года официально находится в состоянии feature freeze т.е. по сути не развивается. Два года - огромный период в IT, к примеру поддержки только вышедшего PHP 7.4 и, тем более, 8-й версии там можно уже не ждать.

    Т.е. поддерживать уже имеющиеся проекты там ещё можно, но начинать новое лучше на framework'е у которого есть активная разработка и понятный план развития. В этом плане наиболее предсказуема Symfony.
    Ответ написан
    1 комментарий
  • Как запретить одновременный вход в один аккаунт на сайте?

    @Flying
    В целом это может быть не такой хорошей идеей как кажется. Наличие нескольких одновременных сессий с разных устройств сейчас - это весьма распространённая практика, особенно если вспомнить о наличии смартфонов. Привязка к IP адресу того же смартфона жителя мегаполиса, перемещающегося в метро и переключающегося между разными WiFi сетями - тоже не вариант. Поэтому прежде чем приступать к реализации - стоит продумать этот вопрос более внимательно.

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

    В любом случае в каком-либо хранилище нужно будет сохранить пару "user id => token" и при дальнейших запросах мы просто проверять имеющийся у нас токен с сохранённым. В случае несовпадения принудительно делать logout с выдачей сообщения через flash messenger.
    Ответ написан
    Комментировать
  • Как сравнить строки в PHP?

    @Flying
    PHP поддерживает сравнение объектов DateTimeInterface напрямую, в данном случае стоит пользоваться именно этим:
    $format = 'd.m.Y H:i';
    $tz = new DateTimeZone('UTC');
    
    $d1 = DateTimeImmutable::createFromFormat($format, '01.01.2019 15:24', $tz);
    $d2 = DateTimeImmutable::createFromFormat($format, '02.01.2019 13:56', $tz);
    
    $newer = $d1 >= $d2 ? $d1 : $d2;
    echo $newer->format(DATE_ATOM);
    Ответ написан
    Комментировать
  • Профиль mozilla с предустановленным расширением - можно ли так сделать?

    @Flying
    Пока ещё возможно, через копирование файла addon'а в профиль и указание используемого профиля, но в ближайшем будущем такая возможность пропадёт, смотрите новость про Firefox 73, она как раз об этом.
    Ответ написан
    Комментировать
  • Как с помощью Elasticsearch получить более 1 000 000 записей?

    @Flying
    Выбирать произвольное количество результатов из Elasticsearch можно с использованием scroll API.

    Это более-менее аналог курсоров в базах данных. Таким образом вы, определяя размеры окна и время жизни токена можете подстроить выборку под свои задачи.

    У меня в проекте приходилось итерировать через scroll и больше миллиона документов - нормально работает.
    Ответ написан
    Комментировать
  • Symfony, как безопасно хранить API ключи?

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

    @Flying
    Поддержка Safari для Windows закончилась на версии 5.1.10 в 2013-м году.

    Так что остаются только маки, виртуалки и сервисы типа BrowserStack.
    Ответ написан
    Комментировать
  • Упрощение стека проекта?

    @Flying
    Для работы с Elasticsearch очень хорошо работает ruflin/elastica, хотя есть и более низкоуровневые официальные binding'и: elasticsearch/elasticsearch

    Для работы с Redis чаще всего используется predis/predis, но с ним сейчас непонятная ситуация из-за того что автор уже давно не поддерживает библиотеку и сейчас есть проблемы с PHP7.3+. Есть форк исправляющий эту проблему, но большинство библиотек завязаны на predis, так что как разрулится ситуация дальше - пока не очень понятно.

    Для работы с HTTP запросами сейчас как правило используют guzzlehttp/guzzle, хотя есть и другие хорошие варианты.

    Для работы с SQL есть множество библиотек разной степени развития и популярности. Если хочется именно plain sql - то можно посмотреть на doctrine/dbal, он очень развит и стабилен.

    Связать всё это в кучу может любой современный framework, лично я бы смотрел в сторону Symfony (из 4-й версии вполне можно сделать micro framework из-за чего прекратили разработку Silex), но есть и реальные микрофреймворки, к примеру весьма популярен slim/slim
    Ответ написан