• Какова роль интерфейсов в ООП?

    Приведу пример на коленке. Хотим, например, написать абстрактную файловую систему. Для начала, определим интерфейс, для ФС:

    interface FileSystemInterface {
      public function write($file, $data);
      public function read($file);
    }


    Затем, хочу реализацию интерфейса ФС для работы с файликами:

    class OSFileSystem implements FileSystemInterface {
      public function write($file, $data) {
         // открываем файлик, пишем данные
      }
    
      public function read($file) {
        // открываем файлик, возвращаем данные
      }
    }


    Вдруг, кому-то захотелось файловую систему в облаке. Окей, не проблема, реализуем это:
    class CloudFileSystem implements FileSystemInterface {
      public function write($file, $data) {
         // открываем соединение с облаком, пишем данные
      }
    
      public function read($file) {
        // открываем соединение с облаком, возвращаем данные
      }
    }

    Пусть у нас есть кой-то код, работающий с файловой системой, назовем его "Хранилище файлов". Пусть он выглядит примерно так:

    class FileStorage {
      protected $Fs;
      
      public function __construct(FileSystemInterface $Fs) {
        $this->Fs = $Fs;
      }  
    
      public function saveFile() {
        $this->Fs->write('file.txt', 'file data');
      }
    
      public function getFile() {
        return $this->Fs->read('file.txt', 'file data');
      }
    }


    Отлично! Теперь мы можем хранилищу файлов отдать любой объект с реализованным интерфейсом FileSystemInterface. Пример:

    // Хранилище файлов работает с файловой системой ОС:
    $FS = new OSFileSystem();
    $FileStorage = new FileStorage($Fs);
    $FileStorage->getFile();
    
    // Хранилище файлов работает с файловой системой в облаке:
    $FS = new CloudFileSystem();
    $FileStorage = new FileStorage($Fs);
    $FileStorage->getFile();


    Использование интерфейса, в данном случае. позволяет нам писать только реализацию работы файловой системы, а бизнес-логика, работающая с файловой системой никак не меняется, она знает, что в любом случае файловая система реализует интерфейс FileSystemInterface и может без опаски использовать методы этого интерфейса.
    Ответ написан
    14 комментариев
  • Как лучше возвращать ошибку API?

    myks92
    @myks92
    Нашёл решение — пометь вопрос ответом!
    1. Если у вас есть доступ к беку, то вам лучше ошибки переводить на нем. Отображение ошибки в зависимости от локали. Переводить лучше тут, так как клиентов вашего api может быть много и будет очень странно если одна и та же ошибка на web будет переведена не так, как в mobile.
    2. Если у вас доступа к беку нет, то я бы на уровне ApiClient сделал обработку и перевод всех ошибок в одном месте. Например, axios может сделать это в одном месте.

    Но есть список ошибок, которые не нужно переводить и выводить их на frontend. Например, ошибки со статусом ответа от 400 до 499 могут быть отображены клиенту, а остальные особого смысла для детализации и перевода не имеют смысла.

    Кроме обработки статуса ответа можно ещё и смотреть на код ответа, как написали в соседнем ответе. Коды ответов не всегда удобны для простой разработки. Так как требуют дополнительной разработки со стороны api и дополнительной обработки со стороны клиента.
    Ответ написан
    Комментировать
  • Как правильно делать запросы в цикле?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    it depends

    • если запросы зависимые, то в цикле
    • если запросы можно выполнить "параллельно", то можно асинхронно сделать сразу все 4 запроса и подождать самый медленный


    например через multi curl, тогда все 4 запроса будут выполняться за время самого медленного из них, а не за сумму времени, удобно через Guzzle Async

    $promise1 = $client->getAsync('http://www.example.com/foo1');
    $promise2 = $client->getAsync('http://www.example.com/foo2');
    $promise3 = $client->getAsync('http://www.example.com/foo3');
    $promises = [$promise1, $promise2, $promise3];
    
    $results = GuzzleHttp\Promise\settle($promises)->wait(); // тут все результаты


    в обоих случаях не понятно, зачем таймаут, тк синхронно второй запрос начнется только ПОСЛЕ выполнения предыдущего, а в асинхронном варианте они просто выполнятся "одновременно" и вы получите результат сразу от всех запросов... таймаут ни к селу ни к городу
    Ответ написан
    1 комментарий
  • Проблемы со стилями Laravel что делать?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    Всё у вас правильно.
    В последних версиях используется Vite для сборки и по умолчанию есть всего два скрипта

    npm run build
    npm run dev


    Когда вы запускаете dev, то никакие файлы в public и не должны создаваться. Vite запускает свой сервер на localhost:5173, куда и "складывает" билды. Если откроете код страницы, то увидите там такое
    <script type="module" src="http://[::1]:5173/@vite/client"></script>
    <link rel="stylesheet" href="http://[::1]:5173/resources/assets/css/app.scss" />


    Этот режим предназначен для разработки, все изменения в файлах применяются "на лету".

    Когда вам нужно сбилдить готовые ассеты, выполните npm run build - и все нужные файлы появятся в public/build/.
    Ответ написан
    Комментировать
  • Как сгрупировать запрос в Laravel?

    pLavrenov
    @pLavrenov
    Разработка сайтов
    Этим вопросом есть смысл заниматься только если это вопрос с собеседования.
    Три простых запроса лучше чем один упоротый.
    Ответ написан
    Комментировать
  • Фреймворки, действительно ли важно?

    neuotq
    @neuotq
    Прокрастинация
    Самое важное это повторение уже сделанной работы.
    Фреймворки для вас это уже сделанная работа, которую не нужно повторять. Более того, если фреймворк популярный - это качественная работа, с высокой насмотренностью, известными проблемами и тп.
    И вот будет ли у вас такое же качество?
    Почитайте ещё про фактор автобуса - вас сбил грузовик/автобус, вы погибли. Что делать с вашим наследием, копаться в нём? Делать новое? Кто этим займётся?
    Отдельный вопрос что ваши штуки нужно будет другим людям специально изучать, если подключаться к проектам что вы ведёте или вели. И зачем это бизнесу? как найти людей которые знают ваши инструменты ваш подход?
    К примеру даже у крупных компаний проблемы с подобным: например движок EA frostbite, который они мучают и при наёме новых людей их нужно прям обучать обучать всем фишкам, костылям и тп. С UE, Unity таких проблем нет.

    Так что, если делаете лично для себя, само развитие и тп - это круто и праивльно, делать свои костыли, экспериментировать.
    Если вы делаете для кого-то другого - вы подставляете заказчика, подкладываете бомбу под бизнес. Которая может потом сильно затруднить развитие.
    Ответ написан
    7 комментариев
  • Как ограничить или оптимизировать доступ к валидации параметров на laravel в request?

    iMedved2009
    @iMedved2009
    Не люблю людей
    php artisan make:policy OrderPolicy

    class OrderPolicy
    {
        use HandlesAuthorization;
    
        public function update(User $user, Order $order)
        {
             if (!$user->isEmployee()) {
                    return false;
             }
             if ($user->id !== $order->user_id) { // остальной кусок ифа не понял - но он должен быть здесь.
                    return false;
              }
    
              return in_array($order->status, [Order::NEW, Order::WORK]);
        }
    
    }
    
    class OrderUpdateRequest extends FormRequest
    {
        public function authorize()
        {
              return $this->user()->can('update', $this->order);
        } 
    }
    Ответ написан
  • Дублирующиеся столбцы - это плохо?

    rozhnev
    @rozhnev
    Fullstack programmer, DBA, медленно, дорого
    Дупликация данных в двух таблицах - это плохо.
    Столбец дата активации в таблице клиентов - это нормальное решение, пока клиент не активирован в ячейке - NULL
    Ответ написан
    2 комментария
  • Отношение первой таблицы к третьей таблице через вторую таблицу, как?

    iMedved2009
    @iMedved2009
    Не люблю людей
    1. Открываем Laravel naming conventions и избавляемся от всех этих model_index. Фреймворк это не только набор инструментов, но так же набор соглашений которые стоит наблюдать

    2. Открываем доку на пункте Has Many Through

    class AutoMark extends Model
    {
        use HasFactory;
    
        public function models()
        {
            return $this->hasMany(AutoModel::class, 'mark_index', 'index');
        }
    
        public function modifications()
        {
            return $this->hasManyThrough(AutoModification::class, AutoModel::class);
        }
    }
    Ответ написан
    4 комментария
  • Как исправить проблему с регистрацией пользователей администратором в laravel9?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    Мне советовали регистрировать пользователя, высылать ему одноразовую ссылку, по которой он перейдет и установит свой пароль, прежде чем воспользуется системой.
    Ответ написан
    3 комментария
  • Как создать БД в Laravel и потом сделать миграцию?

    pLavrenov
    @pLavrenov
    Разработка сайтов
    Есть два пути: Путь джедая для тех кто хочет познать силу и Короткий путь для тех кто хочет получить ответ на задание.
    Ответ написан
    1 комментарий
  • Как в laravel сделать массовый апдейт уникальными значениями?

    nokimaro
    @nokimaro
    Меня невозможно остановить, если я смогу начать.
    используйте
    https://github.com/iksaku/laravel-mass-update - под капотом CASE/WHEN/THEN

    сырым sql такое можно сделать через CASE/WHEN/THEN
    UPDATE table
    SET column2 = (CASE column1 WHEN 1 THEN 'val1'
                     WHEN 2 THEN 'val2'
                     WHEN 3 THEN 'val3'
             END)
    WHERE column1 IN(1, 2 ,3);


    или как работает UPSERT в laravel
    INSERT into `table` (id, fruit)
        VALUES (1, 'apple'), (2, 'orange'), (3, 'peach')
        ON DUPLICATE KEY UPDATE fruit = VALUES(fruit);


    в postgress вместо `ON DUPLICATE KEY UPDATE` будет `ON CONFLICT (xxx) DO UPDATE `
    Ответ написан
    1 комментарий
  • Как сделать Tabs (табуляция) на inertia vue laravel с подгрузкой данных из базы?

    megakor
    @megakor
    Go/PHP developer | Вконтакте
    Если хотите использовать подход Inertia и не хотите чтобы при обращении к методу контроллера грузились сразу все данные, то нужно использовать ленивую загрузку и в JS запрашивать определенные ключи.
    Что-то типа:

    public function index(TabRepository $repository)
    {
        return inertia()->render('Index', [
            'default_tab' => fn () => $repository->getDefaultTabData(), // отдаст по умолчанию и по требованию
            'tab2' => Inertia::lazy(fn () => $repository->getTab2Data()), // отдаст только по требованию
            'tab3' => Inertia::lazy(fn () => $repository->getTab3Data()), // отдаст только по требованию
        ]);
    }


    <Link class="tab" href="route('blabla')" :only="['default_tab']">default_tab</Link>
    <Link class="tab" href="route('blabla')" :only="['tab2']">tab2</Link>
    <Link class="tab" href="route('blabla')" :only="['tab3']">tab3</Link>
    Ответ написан
    Комментировать
  • Laravel 9 и PHP SDK VK, как связать?

    AmdY
    @AmdY
    PHP и прочие вебштучки
    Пользуйтесь нормальной IDE PHPStrom. Она и сама use подставит и предупредит, если что-то сделали не так. Это же детская ошибка в синтаксисе.
    Ответ написан
    Комментировать
  • Как в Laravel выполнить задачу время которой указано в БД?

    neuotq
    @neuotq
    Прокрастинация
    Самый простой способ это начать с планировщика https://laravel.com/docs/9.x/scheduling, там допустим сделать задание(уже вам виднее Job или ещё как), который будет в момент запуска проверять вашу БД на текущие задачи и делать их.
    Ну те сделали, например каждую минуту
    $schedule->call(new DoCurrentJobsFromDb)->everyMinute();

    А в DoCurrentJobsFromDb запрос к базе, выборка по времени текущих заданий и отправка их на немедленное выполнение(тут снова тем или иным способом, подходящим под вашу архитектуру).
    Параметры частоты уже выбираете из ваших соображений.
    Ответ написан
    2 комментария
  • Где лучше всего формировать URL для файлов на laravel перед отправкой на клиент?

    iMedved2009
    @iMedved2009
    Не люблю людей
    Defing accessor
    class Project extends Model{
    ............
    
    public function getFullUrlAttribute(){
               return функция которая делает из атрибута полной путь();
    }
    .........
    }


    во вью {{$project->full_url}}
    Ответ написан
    21 комментарий
  • Как удалить объект с помощью условия из получаемых данных с запроса с пагинацией?

    pLavrenov
    @pLavrenov
    Разработка сайтов
    Надо использовать whereHas который будет добавлять условие group.id == 2, тогда будут получаться только студенты имеющие отношения группы с нужными условиями.
    Ответ написан
    Комментировать