Задать вопрос
  • Как сделать несколько авторизаций на laravel?

    fomvasss
    @fomvasss
    PHP developer
    В этом видео хорошо показано как сделать раздельную авторизацию юзеров и админов , там же есть ссылка на гит с кодом.
    Если авторизация через ВК, то добавьте пакет Laravel Socialite
    Ответ написан
    Комментировать
  • Определить тип трафика на сайте, 3G или WI-FI?

    vvpoloskin
    @vvpoloskin
    Инженер связи
    Через js получить локальный IP-адрес пользовательского устройства (сценарии есть в интернете), если он из 100.64.0.0/12 - мобильный оператор, из других частных диапазонов - фиксированный. Не поможет, если абонент подключен через wifi, у которого аплинк 3G/LTE.

    Если есть возможность выполнить http-запрос на клиентском устройстве, попробовать открыть личный кабинет четырёх операторов (типа lk.megafon.ru), если открывает без логина - вы нашли своего провайдера.
    Ответ написан
    2 комментария
  • Определить тип трафика на сайте, 3G или WI-FI?

    @vylegzhanin
    Есть список IP-адресов мобильных операторов (выдрано из мобильной партнерки).
    Ответ написан
    1 комментарий
  • Laravel 5 Как передать несколько аргументов в функцию join через конструктор запросов?

    JhaoDa
    @JhaoDa
    LaravelRUS Team
    А кто вам сказал, что туда можно передавать какие-то свои аргументы?
    Читаем — php.net/manual/ru/functions.anonymous.php, «Пример #4 Замыкания и область видимости». Ну и вообще изучаем сначала РНР, а уже потом ларавел.
    Ответ написан
    Комментировать
  • Попросили проверить код, на что смотреть нужно?

    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 комментариев
  • Как правильно спроектировать Laravel приложение с уклоном в enterprise?

    SowingSadness
    @SowingSadness
    web-разработчик
    Сейчас напишу немного высокомерно, но опыт позволяет. Уже почти 20 лет в разработке и около 15 в веб.
    Надо понимать, что почти все кто используют многочисленные Фреймворки не понимают что такое ООП. А уж тем более, что такое SOLID и т.д.
    И поэтому, что бы они не писали, в конце-концов превращается в какашку с костылями.
    Да, потом героически проект переписывается с учётом изменений (или ещё чаще умирает) Но, он по прежнему остаётся абсолютно не расширяемым и не поддерживаемым.

    И вот мы возвращаемся к Фреймворкам.
    Нужно брать тот Фреймворк, который писали с учётом определённых парадигм и принципов. Так как этих вот парадигм, достаточно описанных и изученных не так много (на самом деле их 2.5 штуки), то можно сразу ориентироваться на ООП + MVC(или MVP или MVVM) + SOLID
    Если Фреймворк что-то из этого нарушает, то он по умолчанию не может вам дать возможность написать хорошее, расширяемое приложение. А хороший Фреймворк, даже начинающим программистам должен прививать правильные подходы к разработке. Что-бы хочешь, не хочешь, а hello world уже не превращался в ад.

    Сразу оговорюсь, что я давно "забил" на Фреймворки. Есть один идеальный — это Pyramid. А оцениваю любой продукт по документации. Там сразу видны все огрехи и косяки. Буду писать и параллельно смотреть в доки.

    Larvel
    Первое что я вижу в этом Фреймворке, что большая часть работы каркасных компонентов завязана на статических вызовах. На этом можно уже, даже и остановиться. ООП, по большому счёту тут нет. Суть ООП в использовании объектов. Тут же класс выступает в качестве пространства имён функций.
    Раз нет ООП, то и нет всей теории и принципов связанных с ним.
    А раз под этим Фреймворком не заложено никакой теории, то в 99% случаев можно сказать, что на нём что-то правильно, написать невозможно.

    Если взглянуть глубже, то открывается ещё больше ада:
    ActiveRecord.
    Плох по умолчанию. С ним очень тяжело контроллировать целостность данных. Вам нужно придумать слой абстракции, где вы будете транзакционно записывать все данные вне бизнес логики. Фреймворк вам тут не поможет. Он предложит это делать в экшене (контроллере). И тут вы столкнётесь, что при написании чего-то сложнее чем бложик, вы будете терять целостность. Ибо бизнес логика и работа БД будет в одном методе. Отладка будет усложняться, ошибок плодиться и т.д.
    И не зависит это от программистов. Шаблон сам по себе провоцирует ошибаться.
    Далеко за примерами ходить не нужно, уже треш.

    Чем больше примеров я смотрю, тем больше не понимаю, как все это дело расширять. Как вставлять прозрачно через весь проект свои собственные аспекстные решения. Например RBAC. Или, если нужно, логику работы приложения отделить от БД и когда нужно, подставлять необходимую реализацию.
    Или сделать работу всех экшенов в рамках клиента, но производить авторизацию по пользователю(сотруднику)

    Все это предлагается зашивать прям в контроллерах, с помощью protected или private методов.
    Повеситься. Сложность приложения зашкалит.

    Symfony
    Только при выходе 2 версии я работал с этим чудом. Разработчики писали его под хапйом dependency injection. Мало того, что они взяли не самую хорошую стратегию для реализации всего костяка фреймворка, так ещё и сделали её не правильно.
    Они написали универсальный DI Container и кладут в него все что угодно, используя в качестве идентификатора строчку.
    Строчку, М**Ь ЕЁ! Не интерфейс — строчку!
    И знаете чем это аукнется? А тем, что при разработке своего приложения или очередного бандла, вам будет говорить, что в контейнере лежит что-то не то и вы подохните в конфигурационных настройках. А все потому что, подход: ВСЁ через DIC — строго навязывается.
    Расширение этого чуда, тоже причинит вам массу головной боли. Ведь, зачастую, вы будете работать с классами, которые ждут не интерфейс, а что-то из контейнера с ключём "я_твой_дом_шатал".

    Проблема с внедрением аспектов сквозь весь фреймворк, никуда не пропадает. Но тут по другой причине. Сложность платформенных компонентов зашкаливает. Все пишется с завязкой на конкретную реализацию, но получают все по строчке из DIC.
    Потому что это центральная концепция. Другой нет.

    Но, по правде говоря, слепить что-то годное возможность есть.
    Если взять микро ядро symfony, прикрутить Doctrine, то получится что-то годное.
    Но встаёт вопрос. А зачем вообще symfony, если можно взять doctrine и написать все остальное свое?
    И тут вы окажетесь правы — незачем.

    Ситуация с Symfony в enterprise очень схожа с ситуацией с Django. Повидал уже с десяток проектов, где последнюю брали для больших приложений. В итоге от Django оставались рожки да ножки. Всю её переписывали.
    Спрашивается — и зачем? Просто потратили кучу времени.

    Так что, если нужен суровый enterprise. Что бы писать что-то большое, с возможностью расширения — берите Pyramid и переходите на python.
    Ничего, даже близко с пирамидкой, по возможностью расширения, даже близко не лежало.
    Ответ написан
    33 комментария
  • Что делать при некорректном отображении HTML блоков, выведенных через PHP?

    @Yan-s
    Переверстать так, чтобы отображалось как вам требуется.
    Ответ написан
    Комментировать
  • Как решить проблему с "Смешанное содержимое HTTPS"?

    @inkvizitor68sl
    Linux-сисадмин с 8 летним стажем.
    Скрипты-картинки и прочее, подгружаемое по http всё ещё можно подменить, перехватив при этом данные пользователя или подменив страницу - такая возможность делает https бессмысленным на странице.
    Поэтому да, всё нужно отдавать по https. Картинки со сторонних сервисов можно проксировать через себя.
    Ответ написан
    Комментировать
  • Дерево категорий Laravel. Как уменьшить количество запросов в БД?

    @potkot
    PHP программист
    Я бы посоветовал вам вместо обычного дерева, использовать Nested Set дерево (вложенные множества). На чистом PHP как это делается хорошо написано тут www.getinfo.ru/article610.html. Для Laravel есть хороший пакет https://github.com/etrepat/baum (сам им пользуюсь).

    Пример моей таблицы
    db3d3f9781c442708531a6493d4ae153.png

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

    Я у себя с некоторых пор каталоги и страницы храню именно в таком дереве - получить хлебные крошки на странице - 1 запрос. Получить дерево каталогов - 1 запрос.
    Ответ написан
    3 комментария
  • Laravel Eloquent: как сделать сортировку по сумме значений в отношении модели?

    @Faim
    Можно так:
    $vendors = Vendor::with(['services' => function($query) {
        $query->selectRaw('SUM(price) as sum, vendor_id, type')
        ->groupBy('vendor_id')
        ->groupBy('type')
        ->orderBy('sum', 'desc');
    }])
    ->selectRaw('*, (SELECT SUM(price) FROM service WHERE service.vendor_id = vendor.id) as sum')
    ->orderBy('sum', 'desc')
    ->get();

    При этом можно во вью получить такой результат:
    @foreach($vendors as $vendor)
        <p><strong>{{ $vendor->title }} - сумма: {{ $vendor->sum }}</strong></p>
        @foreach($vendor->services as $service)
            <p>--- {{$service->type}}: {{ $service->sum }}</p>
        @endforeach
    @endforeach

    Vendor 1 - сумма: 3000
    --- development: 2000
    --- testing: 1000
    Vendor 2 - сумма: 2600
    --- development: 1800
    --- testing: 800
    Vendor 3 - сумма: 2200
    --- development: 1600
    --- testing: 600
    Ответ написан
    6 комментариев
  • Длительная задача в Laravel?

    Необходимо использовать очереди https://laravel.com/docs/5.3/queues
    Ответ написан
    Комментировать
  • Как заменить число на букву?

    goodwin74
    @goodwin74
    str_replace
    Ответ написан
    Комментировать
  • Почему не работает связь?

    belongsToMany вообще не применим в данной ситуации - это отношение многие ко многим. Вы можете использовать его для того, чтобы получить Itemы конкретных пользователей, да и то если пропишете таблицу Orders как промежуточную. Используйте hasMany для получения заказов и почитайте вдумчиво различие между всеми видами связей в документации. Очень вдумчиво. Потому что пока не осознаете различия в типах связи, не сможете их использовать.
    Ответ написан
    Комментировать
  • Почему не работает связь?

    Alex_Wells
    @Alex_Wells
    PHP/Kotlin
    Ну и снова ты со своим "$this->belongsTo". Я же уже тебе обьяснял, что "belongsTo" - "ЭТО принадлежит кому-то/чему-то".. так у тебя "User" (ЭТО = $this) принадлежит "App\Order"? Нет конечно, у юзера есть много ордеров, то-есть "$this->hasMany('App\Order')" - дословно в переводе "ЭТО имеет много ордеров", а "ЭТО" = $this = User.

    А вот уже Order belongs to User, то-есть Ордер принадлежит юзеру, и в модели ордера уже используешь belongs to User.

    Надеюсь понятно)

    PS: не юзай protected $table, это бесполезно.

    PS: https://vk.com/five_gsm_boss - им сайт делаешь?))0 Не называйте базу данных по названию проекта.
    Ответ написан
    7 комментариев
  • Как найти самый длинный элемент в массиве?

    Finesse
    @Finesse
    $maxLength = null;
    $maxLengthIndex = null;
    
    foreach ($array as $index => $value) {
      $length = strlen($value);
      if (is_null($maxLength) || $length > $maxLength) {
        $maxLength = $length;
        $maxLengthIndex = $index;
      }
    }
    
    echo 'Самая длинная строка "' . $array[$maxLengthIndex] . '" под номером ' . $maxLengthIndex . '.';
    Ответ написан
    Комментировать
  • Как правильно выводить дочерние категории?

    Alex_Wells
    @Alex_Wells
    PHP/Kotlin
    Код стыбзил из stackoverflow:

    public static function ancestors($id)
    {
        $ancestors = Model::where('id', '=', $id)->get();
    
        while ($ancestors->last()->parent_id !== null)
        {
          $parent = Model::where('id', '=', $ancestors->last()->parent_id)->get();
          $ancestors = $ancestors->merge($parent);
        }
    
        return $ancestors;
    }
    Ответ написан
    Комментировать
  • Какой алгоритм создания сайта для интернет магазина?

    xmoonlight
    @xmoonlight
    https://sitecoder.blogspot.com
    С понимания базовой архитектуры, чёткой постановки задачи: здесь

    UPD: Здесь выберите "Новый сайт" и там - тип сайта: "интернет-магазин" и посмотрите основные вопросы анкеты, которые помогут понять основные функциональные требования для создания ИМ (интернет-магазина).
    %25D0%2592%25D0%25B5%25D0%25B1-%25D1%258
    Ответ написан
    2 комментария
  • Правильно ли решил задачку о светофоре?

    xmoonlight
    @xmoonlight
    https://sitecoder.blogspot.com
    <?php
    /*Работа светофора запрограммирована таким образом: 
    с начала каждого часа, в течении трех минут горит зеленый сигнал, 
    следующие две минуты горит красный, 
    дальше в течении трех минут - зеленый и т. д. 
    Вам нужно разработать программу, которая по введенному числу определяла 
    какого цвета сейчас горит сигнал.*/
    
    error_reporting	(E_ALL); // включаем лог ошибок
    
    function numTail($m) {
     switch ($m) {
      case 0:case $m%10==0:default:return '';
      case $m!=11 && $m%10==1: return 'а';
      case ($m<10 || $m>20)&&($m%10==2||$m%10==3||$m%10==4):return 'ы';
     }
    }
    
    function svetofor($m) {
      if($m%5>=1 && $m%5<=3) return "зелёный";
      else if ($m>0) return "красный";
      else return 'никакой';
    }
    
    $m = date("i"); //0-59 минуты.
    $m=46; //для теста.
    //Сейчас 46 минут и горит зелёный.
    
    ?>
    <div>
    Сейчас <?=$m?> минут<?=numTail($m)?> и горит <?=svetofor($m)?>.
    </div>
    Ответ написан
    1 комментарий
  • Как сделать выборку из MySQL по количеству слов?

    27cm
    @27cm
    TODO: Написать статус
    Храните количество слов в отдельном проиндексированном столбце frase_words_count. По нему и осуществляйте выборку.
    Ответ написан
    4 комментария