• Почему я не могу объявить аргумент метода типа потомка от аргумента родительского класса?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Ковариантность и контравариантность ¶
    Официальная документация

    Если коротко: сужать тип у метода наследника можно для возвращаемого значения, а для аргумента можно расширять. И только так, дабы соблюсти Liskov Substitution Principle. В TypeScript это самая популярная проблема, куда разрабов языка постоянно тыкают носом... тк программы в рантайме падают из-за возможности расширять/сужать как тип параметра, так и возвращаемого значения
    Ответ написан
    Комментировать
  • Как такое делается в командной строке?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Комментировать
  • Pxg query Scan() error?

    Maksclub
    @Maksclub
    maksfedorov.ru
    но в любом случае ошибка вылазит, но все работает спокойно

    Scan нужен для конвертации результата в Go types и специальные типы пакета

    но все работает спокойно

    Сначала работает QueryRow(), то есть запрос выполняется. Потом вы запрос пытаетесь конвертнуть в типы go и уже ошибка скорее всего тут...

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

    62c49e38783b9990090532.png
    Ответ написан
  • Зачем нужен статический анлизатор и как он работает?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Например для линтеров, очень подробное руководство зачем они нужны
    https://habr.com/ru/post/457970/

    Чтобы написать линтер — часто нужно сделать статич анализ кода.

    Проверять цикломатич сложность, форматирование кода, находить ошибки или некорректное использование кода.

    Для динамически-типизированных языков стат-анализ может взять роль компилятора и проверять корректность типов и прочих штук. Например описать типы массива (который не типизирован в PHP) или даже имитировать функционал дженериков. Это повысит качество кода и его надежность, избавит от ошибок в боевой среде.

    И ещё интересно, как именно происходит анализ кода?

    Все зависит от того, какую проверку вы делаете... Например (из воздуха) вы хотите сделать проверку, что метод слишком сложный (большой) — делаете анализ кода и по каким-то критериям выдаете оценку/предупреждения. Находите метод (начало и конец) и число строк сравниваете с "приемлимым для вас".

    Или например есть код, но на самом деле он не вызывается никогда (утверждения всегда true дают, а IDE не может этого понять), вы находите такие случае в работе/на ревью со временем и вырабатываете правила как это детектить... Чтобы задетектить, вам надо разобрать инструкции кода, как понимаете без статанализа этого не возможно, не регулярками же делать.
    Ответ написан
    Комментировать
  • Как развертывать приложение в отдельных контейнерах с пробросом портов?

    Maksclub
    @Maksclub
    maksfedorov.ru
    не localhost, а имя докер-сервиса
    Ответ написан
    Комментировать
  • Как правильно сделать авторизацию на Casbin и Go?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Аутентификацию и авторизацию сделать отдельными посредниками

    Для авторизации можете создать дополнительную абстракцию, назовем ее Voter
    Делаете посредник, который принимает voters и можете навешивать их на разные роуты

    Что-то типа (на примере др роутера):

    router.Group(func(router chi.Router) {
         // вся группа роутов внутри только для аутентифицированных
         // тут же можно обогатить контекст юзером
         router.Use(oauth.Authorize().Handler)
    
         // роут только для админов
         router.
             With(perm.WithVoters(perm.ManagerVoter(perm.AdminVoter())).
             Get("/admin", AdminHandler())
    
         // только для manager И owner одновременно
         router.Group(func(router chi.Router) {
              router.Use(perm.WithVoters(
                   perm.ManagerVoter(),
                   campaign.OwnerVoter("id"),
                   // ... любой др voter
              ).Handler)
    
              router.Get("/campaign/{id}", GetCampaign())
              router.Patch("/campaign/{id}", UpdateCampaign())
        })
    }


    Получается гибко и можно управлять ролями для разных роутов
    Ответ написан
    Комментировать
  • Не является ли создание глобального контекста антипаттерном?

    Maksclub
    @Maksclub
    maksfedorov.ru
    в Golang, например, контекст есть на уровне стандартной библиотеки (нужен для управления конкурентными сущностями (закрытие как правило)), а на уровне http роутеров — контекст используют как контейнер для значений почти все реализации, тк через жизненный цикл запроса протаскивать значения — типовая задача роутера

    в целом, вам нужно минимизировать такое явление. Если http-контекст остается только в http слое, то ваша задумка покушается на бизнес-логику. В бизнес-логике никакого контекста быть не может, если у вас есть конфиги или что-то такое — это часть контракта, просто его вы задаете в конфиге и инжектите ту часть контракта, что нужна
    Ответ написан
    1 комментарий
  • Как считать ответ POST частями?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Вы можете воспользоваться Guzzle и middleware MultipartStream
    https://github.com/guzzle/psr7#multipartstream

    Как работать со стримами:
    https://docs.guzzlephp.org/en/stable/psr7.html?hig...
    Ответ написан
    Комментировать
  • Как добавить Array в map?

    Maksclub
    @Maksclub
    maksfedorov.ru
    "bets":  []map[string]interface{}{{
    }
    Ответ написан
    3 комментария
  • Как в Symfony преобразовать строку вида prop.prop[3].prop в строку [prop][prop][3][prop]?

    Maksclub
    @Maksclub
    maksfedorov.ru
    В Laravel есть такая Arr:undot()
    https://github.com/laravel/framework/blob/8.x/src/...

    Вы можете подтянуть хэлперы через композер от туда, тогда так юзать:
    use Illuminate\Support\Arr;
     
    $array = [
        'user.name' => 'Kevin Malone',
        'user.occupation' => 'Accountant',
    ];
     
    $array = Arr::undot($array);
     
    // ['user' => ['name' => 'Kevin Malone', 'occupation' => 'Accountant']]


    или сделать свою такую же
    Ответ написан
    Комментировать
  • Когда выполняется __destruct?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Может до, может после

    Данные серверу (пользователю) можно отправить через fast_cgi_finish_request, но приложение продолжит работать — очевидно объекты продолжат существовать столько, сколько нужно и удалены (если пришёл gc, а на объект никто не ссылается)

    Кроме того у вас может быть демон, который вообще не работает с веб-сервером… очевидно что объекты будут существовать без связи с клиентом

    В общем случае (классич работа приложения) после того как закончится выполнение — fpm прибьёт ваш процесс и объекты соотвественно — и будет вызван деструктор

    Вы можете и сами инициализировать деструктор через удаленние объекта через unset

    В режиме, когда пхп-скрипт работает достаточно долго (или в cli режиме или после finish request) — gc может прийти за брошенными объектами сам и вызвать деструкторы

    Почитать:

    https://abhishekjakhotiya.medium.com/php-fpm-shutd...

    https://www.php.net/manual/ru/features.gc.performa...
    https://developpaper.com/garbage-collection-mechan...

    gc = garbage collector = сборщик мусора
    Ответ написан
    Комментировать
  • Как работает метод Object.keys?

    Maksclub
    @Maksclub
    maksfedorov.ru
    если методом reduce мы обрабатываем только массив названия ключей, то откуда внутри метода значения этих ключей?

    Вы итерируетесь по массиву с ключами (которые достали через Object.keys(obj) у объекта), но доступ к переменной obj то у вас остается и переменная никуда не делась и не изменилась, не пропала :), вот вы с ней и работаете
    Ответ написан
    Комментировать
  • Как правильно указывать(хранить)пароли в docker-compose?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Универсальным рецептом на любую архитектуру является:
    Хранение паролей в секретнице, например HashiCorp Vault

    Приложение при инициализации идет за своим набором секретов по сети и создает подключения к БД, конфиги доступа к др ресурсам и прочее и хранит у себя... Все секьюрно и надежно

    Если проще: передавайте секреты через переменные окружения при деплое.
    Локально — через .env файл. Docker-compose сервисы могут содержать параметр env_file: .env.test, если вам нужно точечно что-то сделать

    Вы разве используете docker-compose для продакшн?
    Ответ написан
    9 комментариев
  • Sequalize - как по id товара и массиву из опций, найти id торгового предложения строго включающий в себя все эти опции, не больше и не меньше?

    Maksclub
    @Maksclub
    maksfedorov.ru
    SQL запрос такой

    Тут используется небольшой чит (эвритсика) — заранее вычисляется сумма значений в optionsTpid и подставляется в группировку

    SELECT productsTpId
    FROM (SELECT productId, productsTpId
          FROM tt
          WHERE TRUE
            AND (
              optionsTpid = 1
              OR optionsTpid = 5
              OR optionsTpid = 10
            )
          GROUP BY productId, productsTpId
          HAVING COUNT(productId) = 3 -- тут длина (количество) значений optionsTpid (1, 5, 10— это 3 значения)
         ) AS nest
    WHERE productId = 2   --  искомый productId


    Пруф работы: sqlfiddle.com/#!9/9f8b5a5/1
    Ответ написан
    Комментировать
  • Что лучше использовать в локальной разработке веб-проектов на Mac OS? MAMP Pro или Docker?

    Maksclub
    @Maksclub Куратор тега Веб-разработка
    maksfedorov.ru
    Docker очень удобен и прост для поднятия каких угодно сервисов для нужд проекта...
    RabbitMQ, базы для дева/теста, какие угодно демоны и прочее... супер-просто и супер-надежно

    Статьи про ненужность Докера идут только в контексте контейнеров на проде в кубере и прочее

    если, например мне нужно запустить 3 сайта. api.domain.loc, lk.domain.loc, domain.loc. Как сделать, чтобы в адресной строке браузера указывать эти домены и попадать на каждый проект?


    для данного решения вы можете поставить еще один контейнер с nginx как реврес-прокси или traefik как тот же реверс-прокси, который будет ваши урлы роутить внутри приватной network внутри докер-сервисов и отправлять туда запросы...

    Итого:
    • Создаете в docker-compose некоторую сеть (секция network в docker-compose.yml, у каждого из сервиса делаете expose 80 порта (не биндинг портов, чтобы конфликта в localhost не было)
    • Ставите реверс-прокси с nginx, чтобы он тоже мог с этой сетью работать
    • Настраиваете его так, чтобы роуты он направлял в нужные сети нужным серисам
    • Все домены добавляется в /etc/hosts
    Ответ написан
  • Как установить соединение с Postgres и при потере, восстановить его?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Можете пользоваться пулом подключений, если подключения нет — пул автоматом создаст новое (обычно библиотеки, которые позволяют создать pool — хорошо и эффективно создают такие соединения)

    Ваша задача только: между сервисами разделить потребности пулов, чтобы размеры пулов в сумме у всех сервисов не были больше количества соединений самого Postgres.

    Также посмотрите на pgbouncer или odissey, если у вас нагруженное приложение.

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

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    В лоб без сложных ограничений
    <?php
    
    $inp = <<<TEXT
    /**
     * Use the default user interface font in all browsers (opinionated).
     */
    
    html {
      font-family:
        system-ui,
        /* macOS 10.11-10.12 */ -apple-system,
        /* Windows 6+ */ "Segoe UI",
        /* Android 4+ */ "Roboto",
        /* Ubuntu 10.10+ */ "Ubuntu",
        /* Gnome 3+ */ "Cantarell",
        /* KDE Plasma 5+ */ "Noto Sans",
        /* fallback */ sans-serif,
        /* macOS emoji */ "Apple Color Emoji",
        /* Windows emoji */ "Segoe UI Emoji",
        /* Windows emoji */ "Segoe UI Symbol",
        /* Linux emoji */ "Noto Color Emoji";
    }
    TEXT;
    
    $text = preg_replace('!/\*.*?\*/!s', '', $inp);
    
    var_dump($text);
    Ответ написан
  • Аналог xDebug для NodeJS?

    Maksclub
    @Maksclub
    maksfedorov.ru
    С нодой идет инспектор, клиенты для инспектора есть для многих платформ (IDE, браузеры)
    https://nodejs.org/ru/docs/guides/debugging-gettin...
    Ответ написан
    Комментировать