• Как сконвертить в читабельный json stdObject со вложенными объектами?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Автоматически никак. Реализуйте в классе интерфейс JsonSerializable, метод jsonSerialize которого будет возвращать данные для сериализации в JSON.
    Ответ написан
    Комментировать
  • Попросили проверить код, на что смотреть нужно?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Смотря зачем)). Я когда делаю Code Review критерии следующие:

    * Безопасность:
    - Каждый аргумент метода простого типа должен проверяться на тип в случае его проксирования и на граничные значения в случае обработки. Чуть что не так - бросается исключение. Если метод с кучкой аргументов на 80% состоит из поверки из аргументов - это вполне норм))
    - Никаких trigger_error, только исключения.
    - Исключения ДОЛЖНЫ быть человеко-понятны, всякие "Something went wrong" можно отдавать пользователю, но в лог должно попасть исключение со стектрейсом и человеко-понятным описанием, что же там пошло не так.
    - Каждый аргумент (объект) метода должен быть с тайпхинтингом на этот его класс, или интерфейс.
    - За eval как правило шлю на **й.
    - @ допускается только в безвыходных ситуациях, например проверка json_last_error.
    - Перед работой с БД - обязательная проверка данных.
    - Никаких == и !=. Со swtich - единственное исключение, по ситуации.
    - Если метод возвращает не только bool, а еще что-то - жесткая проверка с ===, или !== обязательна.
    - Никаких условий с присваиваниями внутри. while($row = ...) - тоже идет лесом.
    - Магические геттеры/сеттеры разрешаются только в безвыходных ситуациях, в остальном - запрещены.
    - Конкатенации в sql - только в безвыходных ситуациях.
    - Параметры в sql - ТОЛЬКО через плейсхолдеры.
    - Никаких глобальных переменных.
    - Даты в виде строки разрешаются только в шаблонах и в БД, в пхп коде сразу преобразуется в \DateTimeImmutable (в безвыходных ситуациях разрешено \DateTime)
    - Конечно зависит от проекта, но как приавло должно быть всего две точки входа: index.php для web и console(или как-то по другому назваться) - для консоли.

    * Кодстайл PSR-2 + PSR-5 как минимум, + еще куча более жестких требований (для начала все то что в PSR помечено как SHOULD - становится MUST)
    - В PhpStorm ни одна строчка не должна подсвечиваться (исключением является typo ошибки, например словарик не знает какой-то из аббревиатур, принятых в вашем проекте). При этом разрешается использовать /** @noinspection *** */ для безвыходных ситуаций.
    - Если кто-то говорит, что пишет в другом редакторе и у него не подсвечивается, на эти отговорки кладется ВОТ ТАКЕЕЕНЫЙ мужской половой **й и отправляется на доработку)).

    * Организация кода:
    - Никаких глобальных функций.
    - Классы без неймспейса разрешаются только в исключительно безвыходных ситуациях.

    * Тестируемость (в смысле простота тестирования) кода должна быть высокая.
    - Покрытие кода обязательно для всех возможных кейсов использования каждого публичного метода с моками зависимостей.

    * Принципы MVC:
    - Никаких обработок пользовательского ввода в моделях, от слова совсем.
    - Никаких ***ть запросов в БД из шаблонов.
    - Никаких верстки/js/css/sql-ин в контроллерах.
    - В моделях НИКАКОЙ МАГИИ, только приватные свойства + геттеры с сеттерами.
    - В моделях разрешено использовать метод save(при наличии такого разумеется) только в исключительных ситуациях. Во всех остальных - либо insert, либо update.

    * Принципы SOLD:
    - Никаких божественных объектов умеющих во все.
    - Если метод для внутреннего пользования - private, никаких public.
    - Статические методы разрешаются только в случае безвыходности.

    * Принцип DRY разрешено нарушать в случаях:
    - Явного разделения обязанностей
    - В тестах (каждый тест должен быть независимым, на сколько это возможно)

    * Работа с БД:
    - Запрос в цикле должен быть РЕАЛЬНО обоснован.
    - За ORDER BY RAND() - шлю на***й.
    - Поиск не по ключам (конечно если таблица НЕ на 5 строк) запрещен.
    - Поиск без LIMIT (опять же если таблица НЕ на 5 строк) запрещен.
    - SELECT * - запрещен.
    - Денормализация БД должна быть обоснована.
    - MyISAM не используется (так уж)) )
    - Множественные операции обязательно в транзакции, с откатом если чо пошло не так.
    - БД не должна содержать бизнес логики, только данные в целостном виде.
    - Не должно быть нецелесообразного дерганья БД там, где без этого можно обойтись.

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

    * О людях:
    - "Я привык писать так и буду дальше" - не вопрос, ревью пройдешь только когда поменяешь свое мнение.
    - "Я пишу в vim-е и мне так удобно" - здорово, код консолью я тоже в нем пишу)) но есть требования к коду, если в них не сможешь - не пройдешь ревью.
    - "Я скопировал этот страшный метод и поменял 2 строчки" - это конечно замечательно, но по блейму автор всего этого метода ты, так что давай без говняшек, хорошо?
    - "Оно же работает!" - вот эта фраза переводится примерно так: "да, я понимаю, что пишу полную хрень, но не могу писать нормально потому, что руки из жо", я правильно тебя понял?))
    - "У меня все работает!" - рад за тебя, а как на счет продакшна?
    - "Там все просто" - не используй слово "просто", от слова "совсем". Вот тебе кусок кода (первого попавшегося с сложной бизнес логикой), где там ошибка (не важно есть она, или нет)? Ты смотришь его уже 2 минуты, в чем проблема, там же все "просто"))

    * Всякое:
    ActiveRecord (это я вам как в прошлом фанат Yii говорю) - полное говно, примите за исходную. По факту у вас бесконтрольно по проекту гуляют модельки с подключением к БД. Не раз натыкался на то, что в тех же шаблонах вызывают save, или update (за такое надо сжигать).
    То, что используется Laravel - это печально((. Что бы выполнить требования приведенные выше, приходится "воевать" с фреймворком.

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

    UPD

    Формализировал данные критерии по ссылочке: https://github.com/index0h/php-conventions
    Ответ написан
    55 комментариев
  • Почему при тестировании symfony не отрабатывает аутентификатор?

    Скорее всего отличаются настройки для тестового и обычного окружения. Разные ключи для генерации токена, или конфиги для подключения к хранилищу с юзерами.
    Ответ написан
    1 комментарий
  • Как победить в Vue 2 рекурсию изменений связанных свойств - price, percent?

    @Kostik_1993
    Web Developer
    Уйти от вотчеров и использовать события инпута и методы для пересчета
    Ответ написан
    3 комментария
  • Как запустить Vue в docker в dev режиме?

    может, дописать путь к установленному vue-cli-service
    ENV PATH=${APP_DIR}/node_modules/.bin:$PATH
    Ответ написан
    2 комментария
  • Как взаимодействовать с iframe google captcha?

    @Ilya12345
    Через селениум случайно получилось так одну из пикч ткнуть, пока делал другую таску, копай в этом направлении или колхозь из ProBrowser.
    $iframe = $driver->findElement(WebDriverBy::xpath('//iframe[@title=\'проверка recaptcha\']'));
    $driver->switchTo()->frame($iframe);
    $driver->findElement(WebDriverBy::xpath('//div[@class=\'rc-image-tile-wrapper\']'))->click();
    Ответ написан
    3 комментария
  • Как взаимодействовать с iframe google captcha?

    @haveacess
    Все что ты пытаешься сделать уже придумали давно до тебя.
    взгляни на доку antigate как они обходят капчу гугла.
    по-моему даже есть расширение. куда вставляешь свой токен и оно все делает автоматом (прям все то что ты пытаешься сделать сейчас)

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

    @KoreanGuy
    лол. Написать video streaming платформу с нуля на вебсокетах. Без обид, но одно это предложение уже говорит о том, что вы не сможете этого сделать. Стриминг не делается на tcp никогда. Вообще мало кто сможет такое сделать, а уж в одного так и подавно. Есть простое правило: если стриминг видео является не основой вашего бизнеса (как, например, у твича, юдеми, и тп), а просто каким-то доп функционалом, ни в коем случае не пишите свой велосипед. Берите vimeo и не усложняйте себе жизнь в 1000 раз.
    Ответ написан
    3 комментария
  • В какой программе делать такие SVG карты?

    profesor08
    @profesor08 Куратор тега CSS
    Конкретно там используется https://leafletjs.com/
    Ответ написан
    Комментировать
  • В какой программе делать такие SVG карты?

    @balgarot
    https://interactive-suite.com/#walindo
    почитай на сайте разработчика, что это
    Ответ написан
    Комментировать
  • Как организовать сеть контейнеров с помощью docker-compose?

    Использую docker-compose file version 2

    Создаем вручную сеть
    docker network create myglobalnetwork

    Описание сети добавить в каждый файл
    networks:
      mynetwork:
        external:
          name: myglobalnetwork

    Сервисам задаем алиасы для сетей по которым контейнеры будут общаться
    services:
      nginx:
        build: ./nginx
        networks:
          mynetwork:
            aliases:
              - nginx.mynetwork
      postgres:
        build: ./postgres
        networks:
          mynetwork:
            aliases:
              - postgres.mynetwork

    Здесь nginx.mynetwork и postgres.mynetwork являются внутренними dns адресами контейнеров
    Ответ написан
    2 комментария
  • Как правильно делать deploy с помощью docker registry?

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

    Давайте разберемся с инструментами и их предназначением, которые Вы используете:
    • Комманда docker - это консольный интерфейс (CLI) для работы с Docker
    • docker build создает по заданному Dockerfile образ контейнера
    • docker tag присваивает указанному образу указанный тег (опция -t для build делает то же самое)
    • docker pull скачивает указанный образ из удаленного регистра на текущую машину
    • docker push заливает указанный образ в удаленный регистр
    • docker run запускает новый контейнер из указанного образа
    • docker ps выводит список текущих "бегущих" контейнеров

    Команда docker не жонглирует файлами, она жонглирует образами и контейнерами, а они от нас абстрагированы Docker'ом, как что-то эфемерное. То есть выполняя комманду docker pull Вы не скачиваете образ в ту папку, где выполняете команду, и уж точно не скачиваете какие-либо файлы. Все что Вы делаете этой командой - это скачиваете образ в локальное хранилище Docker'а, дабы Docker daemon мог запустить контейнер на основании этого образа.

    Команда docker-compose - это уже совсем другая команда. Все что она делает - это читает указанный YAML-манифест и выполняет соответствующие команды Docker. Это всего лишь позволяет декларативно указывать желаемые сценарии при работе с Docker в удобном формате. Но ни команда docker, ни docker-compose, не предоставляют ничего для того, чтобы транспортировать/обновлять версии Ваших манифестов где-то там. Docker, опять таки, жонглирует образами и контейнерами, не более.

    У Вас в манифесте указана директива build:. Таким образом docker-compose пытается сначала собрать контейнер, вместо того, чтобы просто запустить его из образа.

    Касательно совета docker-compose.yml под каждый env, все правильно советовали. Именно так это и задумывалось. Вы в манифесте указываете отнюдь не разные окружения (development, production), а набор контейнеров, которые должны бежать в одной связке одной логической единицей (концепция POD'ов). Ничего не запрещает делать и так, как сделали Вы, но это сродни использованию дуршлага в роли миски для еды: сегодня Вы нормально из него наворачиваете пельмени, а завтра супчик в нем уже куда-то не туда утекает.

    Воркфлоу в Вашем случае можно организовать следующим образом:
    1. На dev-машине у Вас один docker-compose.yml, согласно которому контейнер перед запуском собирается из сорцов.
    2. Когда у Вас готова новая версия приложения, Вы его собираете через docker build, присваиваете ему номер версии через docker tag и отправляете в удаленный регистр образов через docker push.
    3. На prod-машине у Вас отдельный docker-compose.ymlв котором указано запускать конкретную версию образа (и никаких build). Новая версия приложения - меняем тег образа в манифесте и перезапускаем контейнеры. При выполнении docker-compose образ автоматически скачается перед запуском, если его нет локально. Если же Вы обновили образ конкретной версии, которая уже была скачана ранее, то да, нужно выполнить docker pull перед стартом, дабы скачать новый образ.


    Дополнительный совет:
    Сборку образа и его заливку в удаленный регистр часто удобно автоматизировать с помощь Makefile'ов.
    Ответ написан
    3 комментария
  • Можно ли в PHP автоматически вызвать класс?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Во-первых, это называется не процедурное, а функциональное программирование
    Во-вторых, я снова очень сильно сомневаюсь, что это именно то что тебе нужно. В частности, "вызов класса" - это бессмыслица, вызываются методы, а не сами классы
    В-третьих, по аналогии с функциональным программированием, это называется анонимный класс

    (new class {
        public function log($msg)
        {
            echo $msg;
        }
    })->log("hello");
    Ответ написан
    7 комментариев
  • Как правильней создать структуру игровых серверов?

    Stalker_RED
    @Stalker_RED
    Если проект большой, то есть смысл разделить не на две, а на 4+. Логин-сервер, сайт, форум и сколько-то игровых серверов.
    Даже если они физически в вас на двух компах, чтобы была возможность быстро разнести.

    Выбор БД - или то что вам знакомо, или то, что вы хотите изучить-поиграться, или, если уптраетесь в произвол ьельность - по тестам. Берете реальные данные, реальные запросы, и пробуете с разными настройками и БД. Это сложно и долго, но максимальную производительность можно получить только через эксперименты.
    Ответ написан
    1 комментарий
  • Курс или полный гайдлайн по git?

    Griboks
    @Griboks
    Ответ написан
    Комментировать
  • Путь к phpstorm Linux Ubuntu 18.04?

    LazyTalent
    @LazyTalent
    Data Engineer, Freelancer
    1. Запускаешь шторм
    2. Tools -> Create Command-line Launcher
    3. Появиться диалоговое окно с путём
    4. Копируешь путь
    5. Жмеёшь OK
    Ответ написан
    Комментировать
  • Как организовать социальную аутентификацию через Socialite(Laravel)+JWTAuth+Vue.js без редиректа с API-сервера?

    @grinat
    В oauth в качестве redirect-url указываешь window.location, на который юзера перекинут, когда прекинули, парсишь данные из url и отправляешь на сервер.
    Ответ написан
    4 комментария
  • Как организовать социальную аутентификацию через Socialite(Laravel)+JWTAuth+Vue.js без редиректа с API-сервера?

    dlnsk
    @dlnsk
    ПК Партнер 01.01 -> ПК Поиск -> IBM PC
    Работает у меня такая схема и в Ionic и в NativeScript.
    В общем схема везде одинаковая.
    Ionic:
    На Laravel нужен Socialite, на клиенте что-то в соответствии с фреймворком. Я использовал ng2-ui-auth. Еще вам нужно установить плагин InAppBrowser.
    Последовательность такая:
    1. В своем приложении вы жмете на кнопку "Войти через GitHub"
    2. Открывается InAppBrowser окно входа GitHub (в урле передается clientId вашего приложения и redirectUri, за это отвечает ng2-ui-auth).
    2а. Обратите внимание что redirectUri из запроса должен быть идентичен Authorization callback URL в настройках вашего приложения на сайте GitHub (Settings / Developer settings / OAuth Apps) и в случае Cordova должен быть равен "localhost:3000".
    3. GitHub авторизирует вас по логину/паролю, спросит разрешения передавать данные Приложению и редиректит страницу на redirectUri добавляя к нему токен.
    4. ng2-ui-auth перехватывает обращение к localhost:3000 (это делается с помощью JS, тут нет никакого локального сервера), достает токен и пересылает его на конечный url (указывается для каждого провайдера в настройках ng2-ui-auth).
    4а. Вот этот конечный url должен быть адресом вашего backend'а, а именно метода, который с помощью Socialite будет запрашивать данные пользователя у GitHub.
    5. С помощь Socialite вы получаете данные о пользователе у GitHub. Создаете пользователя в Laravel, если его нет, и делаете любые другие необходимы действия.
    6. Используя данные пользователя с помощью jwt-auth создаете jwt-токен и возвращаете его клиенту (в пункт 4).
    7. На клиенте запоминаете jwt-токен и тот факт, что пользователь аутентифицирован. Из ответа можете достать email (если вы его передали) и где-нибудь отобразить.
    Все!

    С NativeScript все абсолютно аналогично (там на клиенте я использую nativescript-oauth2) за исключением одного: в NS нет webview, поэтому перехват redirectUri выглядит по-другому:
    1. В Authorization callback URL на GitHub вы пишите что-то вроде blablabla://auth (вместо blablabla какая-то длинная уникальная строка - urlScheme).
    2. Эта urlScheme также пописывается в настройках nativescript-oauth2 и в App_Resources/Android/src/main/AndroidManifest.xml в виде intent-filter
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="blablabla" />
    </intent-filter>

    Приложение перехватывает обращение к этой уникальной urlScheme и дальше все продолжается согласно списка.
    Ответ написан
    1 комментарий