Ответы пользователя по тегу Laravel
  • Использование транзакций в сервисах?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Если сервис 1 и сервис 2 должны юзаться еще где-то, имеет смысл вынести их функциональность либо полностью отдельно, без транзакций, либо частично в публичный метод. В 3-ем юзать одну транзакцию.

    Если так не делать - работа с событиями после flush, и ему подобными становится как минимум сложной.
    Ответ написан
  • Doctrine vs Eloquent и других ORM?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Логика программы ужасно сложная на первый взгляд и занимает больше времени на изучение, написание и поддержку, или нет?

    только на первый взгляд

    Что я точно знаю, займет больше времени на показать новенкьу что да как работает, в отличии от Eloquent.

    Для говносайтиков с простенькими crud-ами Eloquent вполне подойдет. Для чего-то по серьезней - нет.

    Не пойму зачем он?

    Читаем, посвящаемся: Попросили проверить код, на что смотреть нужно?

    В чем его преимущество и отличия от Eloquent в Laravel?

    * SOLID
    * Безопасность
    * Простота тестирования
    * Простота расширения
    * Простота поддержки

    Что и когда использовать?

    Лучше раз разобраться в Doctrine и забыть об ActiveRecord

    Почему?

    Потому, что низкий уровень вхождения оплачивается кучей магии, рано, или поздно вам вылезет боком, это Домоклов меч.
    Ответ написан
  • Как использовать repository pattern в Laravel?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Это путь боли. Лучшим решением будет полный отказ от ларковской орм.
    Ответ написан
  • Как максимально быстро изучить Laravel в домашних условиях?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Быстрее всего можно научиться в офисе, когда тебя окружают спецы, круче тебя.
    Крупные сложные проекты это тоже в офисе.

    FYI: ларка это опасный фреймворк для крупных проектов.
    Ответ написан
  • Репозиторий и ActiveRecord, хорошая ли идея возвращать модели?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Ну и основной вопрос, в правильном ли я направлении формирую мысли, и как подобный подход с репозиториями можно реализовать правильно ?

    Если хотите по правильному - не используйте ларавелевскую ORM, "воевать" с фреймворком - это дело не благодарное.
    Паттерн Repository как правило предполагает еще наличие Entity. Entity - это объект, умеющих хранить в себе данные и проверять их при установке. Репозиторий работает только с Entity и только с БД. Никаких bcrypt, работы с файлами, никаких уведомлений...
    Не стоит использовать публичные свойства. В противном случае вы не сможете гарантировать корректность данных в вашем Entity, как следствие всюду их придется проверять. Используйте тайпхинтинг.
    Так же рекомендую почитать: Попросили проверить код, на что смотреть нужно?
    Ответ написан
  • Как правильно организовать обработку данных в экшене контроллера?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    По хорошему валидацию должен делать реквест

    Неа. Request - это просто набор данных.

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

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

    Опережая ваш вопрос: "это ж сколько дублировать проверки придется?". Да, много, но поверьте, оно стоит того.

    В добавок к этому иногда логика может быть достаточно замысловатой

    Если вы пытаетесь в одной точке захватить множество контекстов - безусловно. Если же будете делать необходимые проверки всюду - эта сложность не возникнет.

    Мне не очень нравится идея выносить куски логики в реквест

    Мысль здравая.

    Соответственно получается неудобная ситуация, когда часть валидации нужно разместить в реквесте, а часть в сервисе.

    Не нарушайте SRP.

    <?php
    
    namespace Vendor\Project\AppBundle\Controller;
    
    use KoKoKo\assert\Assert;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Vendor\Project\Path\Authorization\UserNotFoundException;
    use Vendor\Project\Path\Authorization\InvalidCredentialsException;
    
    class LoginController extends Controller
    {
        /**
         * @Route("/login", name="login")
         * @Method({"POST"})
         * @param Request $request
         * @return JsonResponse
         */
        public function loginAction(Request $request) : JsonResponse
        {
            try {
                $login = $request->request->get('login');
                $pass  = $request->request->get('pass');
    
                Assert::assert($login, 'login')->string()->notEmpty()->match('/^[a-z\d]{3,32}$/i');
                Assert::assert($pass, 'pass')->string()->notEmpty()->lengthBetween(6, 32);
            } catch (\Throwable $exception) {
                return new JsonResponse($exception->getMessage(), JsonResponse::HTTP_BAD_REQUEST);
            }
    
            try {
                $user = $this->get('UserAuthorizator')->authorize($login, $pass);
    
                return new JsonResponse($user->getId());
            } catch (UserNotFoundException $exception) {
                return new JsonResponse('User not found', JsonResponse::HTTP_BAD_REQUEST);
            } catch (InvalidCredentialsException $exception) {
                return new JsonResponse('Invalid login or path', JsonResponse::HTTP_BAD_REQUEST);
            } catch (\Throwable $exception) {
                $this->get('logger')->error($exception->getMessage(), ['exception' => $exception]);
    
                return new JsonResponse('Something went wrnog :((', JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
            }
        }
    }
    Ответ написан
  • Исключения или проверка?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Однако не совсем понятно, было бы верным делать исключения в контроллере или все же сначала спросить сервис о например существовании мыла?

    Вы и так обрабатываете этот момент в catch блоке. Ваша реализация - ок.

    switch ($e->getCode())

    Лучше заведите больше исключений и используйте несколько catch.

    придется создавать отдельный метод someAuth где например не нужны сессии и требуется отправить сообщение о входе.

    Когда понадобится - напилите под этот тип авторизации отдельный сервис.
    Ответ написан
  • Чем Codeigniter легче от Laravel?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Господин Эскобар дурного не скажет (18+)

    CI - это мертвый фреймворк, возьмите за исходную.
    Чем он легче?
    Легче всего разобраться в том, в чем нечего разбирать. Это очень куцый мертвый фреймворк.

    Laravel - это большой ком из антипрактик. За "простоту" вы будете платить непониманием как оно работает и сложностью в поиске ошибок.

    Посмотрите Silex, когда насмотритесь - Symfony. Так же рекомендую почитать: Попросили проверить код, на что смотреть нужно?
    Ответ написан
  • Как узнать список методов?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Так вот о методе latest() IDE ничего не знает! Шо же делать, как же быть? :)

    Не используйте статику и магию, тогда IDE будет все отлично находить)). Про ларавелевские фасады - тоже забудьте, это в принципе говноподход.
    Ответ написан
  • Первый проект для изучения PHP фреймворков - что делать?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    nepster09 В основном по делу сказал, но вот Laravel - погорячился. Хотите качественный фреймворк - Symfony, Zend. Из маленьких фреймворков могу посоветовать Silex.
    Встаёт 2 вопроса: какой фреймворк лучше выбрать - Yii2 vs Laravel?

    Symfony
    ...а ещё лучше и коммерческий потенциал/общественная польза?

    Symfony
    Может быть, не хватает какого-то специфичного сервиса или агрегатора?

    Ну это вам писать, так что не хватает того, что сможете реализовать))

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

    Вообще говоря под такой запрос подходит в принципе любой.

    Также буду признателен, если поделитесь годными ссылочками по организации рабочего процесса под фреймворк.

    Git - святое
    Vagrant - окружение
    Ansible - для конфигурирования виртуалки под Vagrant
    Плагины шторма: Symfony2 Plugin, Symfony2 - Clickable Views, PHP Annotations

    Рекомендую почитать на досуге
    Ответ написан
  • Как вызвать класс из другого проекта?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Похоже на какую-то херню, если честно. Если у вас в проект А не включен проект Б - то видимо это так задумано, иначе вы бы просто подключили Б как зависимость в композере.
    То, что хотите несколько раз подключать классы из одних и тех же неймспейсов - плохая идея, работать НЕ будет.

    Покретно под ваш кейс использования - вам ничто не мешает в каталоге каждого проекта завести например yml, или 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
    Ответ написан
  • Cтоит ли переходить на Laravel 5?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Неправильный вопрос)) Правильный: есть проект на 4.2, решающий такие задачи ...., в 4.2 не устраивает 1, 2, 3, что даст 5.1 при переходе?
    Ответ написан
  • Как обработать 250 000 строк таблицы в Laravel?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Вам обязательно для этого использовать php? Частичную (или полную обработку) по идее можно самим мускулом, результаты - во временную таблицу. На поля с поиском (не полнотекстовым) имеет смысл поставить индексы.

    DB::table('table_name')->limit(10)->chunk(10, function($rows)


    Я не силен в Laravel, но судя по доке limit не нужен + чанкуйте по больше записей, например 500
    Ответ написан
  • Курица или яйцо? Как создать запись в одной из двух таблиц, завязанных друг на друга внешними ключами?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Я правильно понял, зачем такое может понадобится - это связка MANY-MANY?
    Если да - выбросьте двойную связку и желательно так не делайте. Вместо нее используйте дополнительную таблицу для связки. Например: есть 2 таблицы users[id, name] И groups[id, name]. Для них создайте еще одну groupsHasUsers[groupId, userId].
    Ответ написан