• Как справляться с большим потоком малых задач на фрилансе?

    @Stalinko Куратор тега Фриланс
    PHP'шник и фрилансер до мозга костей
    Универсального варианта быть не может, потому что сами задачи и твоё свободное время всегда разные.

    Лично у меня позиция следующая: у меня есть 1-2 основных клиента, на которых я трачу 90-100% своего рабочего времени. Они как бы "моя основная работа".
    И периодически всплывают старые клиенты с доработками. На них я готов выделить максимум 5-10 часов в неделю. Это я сразу же четко обозначаю. Если у них задача большая, то даже не буду браться, потому что это растянется на месяцы. Мелкие задачи беру, но с условием, что буду делать, когда будет свободное время. Это может быть и через день, а может и через неделю.

    Если кратко: то я называю свои условия, а они решают, устраивает или нет. Ситуация, чтобы всё бросить ради внезапного клиента, - это исключительная редкость.
    Ответ написан
    2 комментария
  • Чем mock отличается от stub в phunit?

    nokimaro
    @nokimaro
    Меня невозможно остановить, если я смогу начать.
    https://vc.ru/flood/44925-za-chto-ya-cenyu-testiro...

    Главное различие между stubs и mocks заключается в том, что в одном случае мы управляем состоянием, а в другом - поведением.

    Когда мы используем mocks, мы заменяем весь модуль на mock (ложный, тестовый объект, имитирующий настоящий). А stub - это функция, которая всегда выводит один и тот же результат, вне зависимости от того, что было подано на вход. Mocks используют для того, чтобы проверить, была ли функция вызвана с правильными аргументами, а stubs, чтобы протестировать, как функция работает с полученным ответом. Стабы нужны для проверки состояния метода, а моки используются для регулировки поведения.
    Ответ написан
    Комментировать
  • Как повысить свои навыки в построении архитектуры сложных приложений?

    heman
    @heman
    бэкенд разработчик на php
    Идеально конечно попасть в большой проект с опытными коллегами.

    Чистая архитектура полезная книга.

    Мне помогла серия видео по запросу "модульный монолит".

    ArchDays 2020 • Модульный монолит вместо микросервисов • Денис Цветцих (Epam)

    Модульный PHP монолит как альтернатива микросервисной архитектуре - Юлия Николаева, iSpring

    И самое главное серия статей Herberto Graça The Software Architecture Chronicles
    https://habr.com/ru/post/427739/
    https://herbertograca.com/2017/07/03/the-software-...

    В голову заходит тяжело. Выше коллега писал про свой подход: постоянно пробовать то что узнал на практике и пересмотр решений.
    Ответ написан
    Комментировать
  • Средствами доктрины можно сделать аннотациями при 2 ссылках таблицы на себя, именно на одно поле id?

    @tukreb
    Нельзя ссылаться в одной таблице на тоже самое поле.
    То что вы попытались описать называется Adjacency List (но нужно использовать дополнительное поле parent_id)
    А то что вы изобразили как 2 таблицы, называется Subsets
    Рекомендую ознакомится с этими понятиями и выбрать что вам нужно.
    Ответ написан
    1 комментарий
  • Почему файл php выполняется дольше, нежели html?

    saboteur_kiev
    @saboteur_kiev
    software engineer
    так html просто отдается, а php через php-fpm обрабатывается, не?
    Ответ написан
    Комментировать
  • Что такое мидлвар простыми словами?

    402d
    @402d
    начинал с бейсика на УКНЦ в 1988
    Применительно к симфони . хук повещенный на кернел.
    Применяется для выполнения дополнительных действий над реквестом до передачи его в контролер
    или над респонсом перед окончательным его выводом .
    https://symfony.com/doc/current/event_dispatcher/b...

    Но термина милдваре в явном виде Вы на сайте симфони не найдете. Это из лаверала
    https://laravel.com/docs/8.x/middleware
    Ответ написан
    1 комментарий
  • Как использовать одну переменную в нескольких make файлах?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    У меня есть два make-файла, первый вызывает второй.
    Мне хотелось бы получить некоторые данные из второго make-файла.

    Не предусмотрено такое логикой make, разве что через eval это можно накостылить. Обычно, когда нужна тесная связь между разными Makefile, один из них подключают в другой (и получают большой логический Makefile поделённый на несколько файлов).
    Ответ написан
    Комментировать
  • Как можно автоматизировать добавление повторяющегося кода в HTML?

    AlexNest
    @AlexNest
    Работаю с Python/Django
    Вариант 1:
    1. Изучаете основы работы с СУБД, sql, php
    2. Проектируете базу
    3. Подключаете к сайту с помощью php.
    4. Пишете CRUD-функции для работы с записями.

    Вариант 2:
    Используйте CMS-ку по типу вордпреасса
    Ответ написан
  • Почему через функцию mail() у меня письмо перекидывается без стилей и не учитывается тег?

    DevMan
    @DevMan
    1. верстка писем - отдельная тема с увлекательным секасом.
    2. пора забыть о функции mail для почты. как минимум, если почта не для себя, а на сторону.
    Ответ написан
    Комментировать
  • Как загрузить сразу несколько изображений на сервер в php?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Как научиться искать в интернете ответы на примитивные вопросы?
    Ответ написан
    Комментировать
  • Как задать значения consul kv при запуске в докере?

    @wargych Автор вопроса
    Нашел 3 пути.
    1. Первый и правильный с точки зрения назначения консула описан тут:
    поднимаем кластер для использования в качестве discovery-сервиса и потом заполняем данными из клиента.
    https://github.com/deployable/docker-consul
    2. Способ на котором мы пока остановились - храним данные в volume. Есть проблемы с правами при разворачивании проекта в новом окружении.
    3. Костыльный и неправильный , но рабочий способ - подставить в качестве entrypoint свой скрипт, который запускает 2 скрипта - один в фоновом режиме пингует поднятие консула и заполняет его данными, второй собственно поднимает сам консул.
    Примерное содержимое файлов:
    Docker-compose.yml
    version: '3.2'

    services:
    consul:
    build:
    context: ./
    dockerfile: Dockerfile
    ports:
    - 8500:8500
    entrypoint: sh -c "cd /confrun/ && sh kvconf.sh"

    Dockerfile

    FROM consul:latest
    COPY ./confrun/ /confrun/
    RUN chmod 755 -R /confrun/
    EXPOSE 8300 8400 8500 8600
    ENTRYPOINT sh -c "cd /confrun/ && sh kvconf.sh"

    kvconf.sh

    #!/usr/bin/dumb-init /bin/sh
    sh ./subscriber.sh &
    sh ./runner.sh

    subscriber.sh

    #!/bin/bash
    let "timeout = $(date +%s) + 15"; \
    while ! curl -f -s localhost:8500/v1/status/leader | grep "[0-9]:[0-9]"; do\
    if [ $(date +%s) -gt $timeout ]; then echo "timeout"; exit 1; fi; \
    sleep 1; \
    done; \
    consul kv put sql/config/addr db;
    ...все нужные команды. Чтобы избежать повторного заполнения при старте, нужно дописать consul get с проверкой на значение...

    runner.sh

    #!/bin/bash
    consul agent -server -ui -bind 0.0.0.0 -client 0.0.0.0 -bootstrap-expect 1 -data-dir /consul/data -config-dir /consul/config

    Ну и в принципе вместо runner.sh будет правильнее подставить стандартный скрипт консула entrypoint.sh.
    До конца этот путь не довел, т.к. все-таки слишком костыльно на мой взгляд, но все запускалось и значения добавлялись.
    Ответ написан
    Комментировать
  • Надо сделать регулярное выражение для проверки цены, как это сделать?

    saboteur_kiev
    @saboteur_kiev
    software engineer
    \d*(\.\d\d)?(\$|руб)

    Вообще такое задание лучше оформлять на каком-то онлайн регекс билдере
    https://regex101.com/r/e74O55/1

    И еще странно, что в случае с рублем, нет пробела перед ним
    ибо 100$ выглядит нормально, а 100руб - нет. Лучше 100 руб...
    но добавить пробел несложно (\d*(\.\d\d)?(\$| руб))
    Ответ написан
    8 комментариев
  • Как ограничить загрузку файла по прямой ссылке?

    ky0
    @ky0 Куратор тега Nginx
    Миллиардер, филантроп, патологический лгун
    Это работа приложения, а не веб-сервера.
    Ответ написан
    3 комментария
  • Что значит префикс "х" в адресе сайта?

    AgentSmith
    @AgentSmith
    Это мой правильный ответ на твой вопрос
    Это поддомен, а не префикс.
    Или домен третьего уровня.
    Ничего он не означает, так же как и m.
    Ответ написан
    Комментировать
  • Каким SQL запросом можно перенести данные из одного столбца в другой?

    hottabxp
    @hottabxp
    Сначала мы жили бедно, а потом нас обокрали..
    Вопрос звучит как задание. Но дам вам совет. Вы знаете какой-либо язык программирования? Если да, то эта задача делается просто. Я вот плохо знаю sql. Но неплохо знаю Python. И тоже много работаю с данными в MySQL, csv, excel... И excel я не понимаю. Если мне нужно манипулировать данными, я просто подключаю необходимые библиотеки, импортирую файл в python, все операции делаю в питоне. Потом экспортирую в нужный формат. PROFIT! И мне не стыдно, так как я решаю задачу теми инструментами, которые знаю.
    PS: Ещё один плюсик в карму Python :)
    Ответ написан
    1 комментарий
  • Как установить порядок валидации с проверкой другого поля в Symfony?

    rpsv
    @rpsv
    делай либо хорошо, либо никак
    - поменять поля местами
    ИЛИ
    - создать 2 группы, в них закинуть поля и указать порядок групп: https://symfony.com/doc/current/validation/sequenc...
    ИЛИ
    - вместо анотаций использовать PHP метод loadValidatorMetadata и в нем указать нужный порядок: https://symfony.com/doc/current/validation.html
    Ответ написан
    Комментировать
  • Как реализовать авторизацию/аутентификацию с помощью access/refresh tokens с использованием JWT?

    nowm
    @nowm
    3. Оба ли эти токены будут являться JWT?

    JWT — это строка, сформированная в соответствие с RFC7519. Если формат правильный, это JWT, если нет — это не JWT. Если вы распечатаете JWT-токен на бумаге и используете её как кулёк для семечек, эти токены не перестанут быть JWT-токенами. То есть, область применения никак не влияет на то, JWT это или нет — только формат самого токена.

    ---

    Суть Access- и Refresh-токенов в том, что у вас может быть 10 разных серверов, один из которых используется для авторизации. На сервере авторизации вы генерируете токены и сообщаете их клиенту, каким-то способом, безопасность и удобство которого вас устраивает. Кто-то в куках передаёт, кто-то прямыми ответами сервера. Остальные 9 серверов принимают запросы, в которых указаны Access-токены. Тут тоже можно разными способами это делать. Можно в GET-параметрах токен передавать, можно в куках, можно в теле запроса, можно использовать хэдер Authorization — опять же, это на ваше усмотрение, в зависимости от того, какой способ вам кажется более удобным или более безопасным. На этих 9 серверах есть открытые ключи авторизационного сервера либо они могут обратиться к авторизационному серверу за ними. Используя эти открытые ключи, они проверяют Access-токен на валиднось, и если всё хорошо, выполняют запрос, в котором был этот токен, вытаскивая из токена, например, идентификатор текущего пользователя и используя его дальше. Сами эти 9 серверов не занимаются генерацией токенов вообще. Они только проверяют их. Соответственно, им не требуется хранить в БД или в кэше конкретные токены, чтобы удостоверяться в легитимности запроса, им нужен только открытый ключ авторизационного сервера, закрытой частью которого он подписывает эти токены. Это упрощает на их стороне логику, и они могут сосредоточиться на своих узких задачах.

    Авторизационный сервер занимается только генерацией токенов. Именно он решает, что, например, Access-токен должен жить 3 минуты, а Refresh-токен — 30 дней. Он делает свои личные проверки любых данных, которые может достать (IP, UA, идентификатор сессии и так далее) — вы сами решаете и сами пишете логику того, какие проверки нужно делать и как. Если вы считаете, что в полнолуние нужно отказывать в генерации токена для браузера Firefox пользователям из Кении, именно так и программируйте систему, потому что за вас библиотека JWT автоматом такие проверки делать не будет — это не её назначение. Её назначение проверять и создавать JWT-токены из данных, которые вы ей даёте на входе. Среди этих данных могут быть идентификаторы пользователя, сессии и т.п., если вы сами захотели их туда засунуть.

    Когда вы запрашиваете новый Access-токен, передавая в параметрах Refresh-токен (опять же, передавать его можно разными способами в зависимости от ваших вкусов и того, как вы запрограммировали сервер), авторизационный сервер проверяет его валидность и принимает решение, выдавать новый токен или нет. Вполне можно построить систему так, чтобы Refresh-токен не приходилось хранить в БД на стороне сервера авторизации, потому что все нужные данные можно поместить прямо в payload токена — он всё равно подписывается, так что если клиент подменит там идентификатор пользователя, токен не пройдёт валидацию.

    Фишка с Access- и Refresh-токенами нужна для того, чтобы организовать распределённую работу нескольких серверов. Если вы генерируете токены на сервере, а потом на этом же сервере принимаете запросы, в которых используется Access-токен, вы делаете что-то неправильно, потому что в таких ситуациях городить подобную архитектуру не нужно, и передавать Refresh-токен вместе с Access-токеном API-серверу тоже не нужно, потому что генерация новых токенов — это не его забота.

    Немного выше я писал, что токены со стороны клиента можно передавать по-разному в зависимости от предпочтений: в куках, в GET-параметрах, в теле запроса или в хэдере Authorization. Хорошая практика — это когда вы передаёте их в хэдере Authorization и больше никак. Делаете запрос к API-серверу? В хэдер помещается Access-токен. Делаете запрос на продление токена к авторизационному серверу? В хэдер помещается Refresh-токен. Всё просто и однотипно.
    Ответ написан
    1 комментарий
  • Как вы считаете время ожидания на Freelance?

    opium
    @opium
    Просто люблю качественно работать
    Конечно не входит
    Собственно если такие простои постоянные надо оговорить с клиентом время реакции админа, фиксированую оплату в месяц, как то по другому организовать работу, внедрять девопс чтобы не ждать каждый раз админа
    Ответ написан
    4 комментария
  • Как сервису выбрать нужный репозиторий в рантайме?

    uDenX
    @uDenX
    PHP Developer
    https://github.com/symfony/symfony/blob/6.0/src/Sy...
    https://designpatternsphp.readthedocs.io/ru/latest...

    Либо перекладывать выбор на сами репозитории, либо вводить новый класс, который будет выбирать
    Ответ написан
    Комментировать