• Правильно ли реализованы классы?

    php666
    @php666
    PHP-макака
    Высокоуровневые методы (например, find****) должны быть обёрткой над кодом, который использует билдер запросов. У тебя дубляж низкоуровневого кода работы с PDO повсеместно.

    Когда я свою ORM писал, у меня это выглядело так:

    // высокоуровневый метод делающий ТОЛЬКО выборку по id
        public function findModelById($id): Model
        {
                return $this->findModelByParams(
                    array('where' => array('`id` = ?i' => array($id)))
                );
        }
    
        // УНИВЕРСАЛЬНЫЙ низкоуровневый метод, находящий объект модели по любым параметрам
        public final function findModelByParams(array $params=array()): Model
        {
            $res = parent::createQuerySelect($params);
    
            $object = $this->createModelFromDatabaseResult( is_object($res) && $res->getNumRows() ? $res->fetch_assoc() : array() );
    
            return $object;
        }
    
        // построитель любого sql-запроса на SELECT, его исполнение и возвращение объекта типа РЕЗУЛЬТАТ
        protected final function createQuerySelect(array $params)
        {
            $params = self::makeSqlFromParams($params); // это сам билдер!!!!!!!!!!!!!!
    
            $sql = 'SELECT' . $params['what'] . 'FROM ?f' . $params['join'] . $params['where'] . $params['order'] . $params['limit'];
    
            array_unshift($params['args'], $this->getTableName());
            array_unshift($params['args'], $sql);
    
            $result = call_user_func_array(array($this->getDb(), 'query'), $params['args']);
    
            return $result;
        }


    Аналогично был метод на удаление:

    protected final function createQueryDelete(array $params)
        {
            $params = self::makeSqlFromParams($params);
    
            $sql = 'DELETE FROM ?f ' . $params['where'] . $params['limit'];
    
            array_unshift($params['args'], $this->getTableName());
            array_unshift($params['args'], $sql);
    
            return call_user_func_array(array($this->getDb(), 'query'), $params['args']);
        }


    insert/update в подобном билдере не нуждались, они были частью метода save, в точности как у тебя.

    Твоя обертка будет работать, но дубляжа кода много, это прям бросается в глаза. Ты можешь не писать билдер запросов, но тогда ты будешь описывать каждый новый метод и в каждом методе у тебя везде будет написано одно и тоже - prepare/execute/fetch

    Это всё будет давить, особенно когда тебе понадобится сделать методы типа findUserByIdOrNameAndSurname($id, $name, $surname)
    где нужно будет исполнить запрос вида select * from users where id = ? OR name = ? AND surname = ?

    Тут уже не спасет твой метод findByAttribute.

    Тебе захочется иметь "красивый" метод высокого уровня, в итоге ты либо напишешь его в привычной стилистике

    public static function findUserByIdOrNameAndSurname($id, $name, $surname)
        {
            $stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE id = ? or name = ? and surname = ?');
            $stmt->execute([$id, $name, $surname]); // или как тут правильно, не знаю..
            $r = $stmt->fetch();
    
            return $r ? new static($r) : null;
        }


    либо сам придешь к необходимости создать метод findModelBySql($sql).

    Но и то и то будет нагромождением повторяющихся кусков кода.

    spoiler
    PS дзен AR ты познал, крайне советую остановиться и не повторять моих ошибок. Я тоже писал свою ОРМ, только это никому нахер не нужно. И твоя ОРМ тоже не нужна, даже тебе. Есть проверенные решения, тот же eloquent. Не занимайся ерундой.
    Ответ написан
    Комментировать
  • Можно ли хуки вынести в отдельную функцию. И если нет, то как быть?

    @paoluccio
    И пытаюсь вызвать ее из pushForm()

    это против правил, хуки должны жить на верхнем уровне в компонентах или же других(кастомных) хуках.

    В вашем случае, как один из вариантов, логику обработки формы можно вынести в кастомный хук. Затем использовать его в LoginUser.
    Приблизительная структура:
    // Custom hook
    export const useAuthHandler = () => {
      const [token, setToken] = useState(null);
    
      useEffect(() => {
        if (token) { // чтобы не диспатчить с начальным null на первом рендере
          // диспатчим экшн с полученным токеном
        }
      }, [token]); // будет следить за token
    
      return () => { // возвращаем функцию-обработчик
        // запрашиваем токен, в then вызываем setToken(token)
      };
    };
    
    // Component
    export default function LoginUser() {
      const handleSubmit = useAuthHandler();
    
      return (
        <div>
          <form id="auth_form">
            {/* ... */}
            <Button autofocus="true" onClick={handleSubmit}>Авторизоваться</Button>
          </form>
        </div>
      );
    };
    Ответ написан
    Комментировать
  • Сборка i3 9100F + 1650 super?

    Zoominger
    @Zoominger Куратор тега Компьютеры
    System Integrator
    А зачем i3-то? Можете немного накинуть и взять гораздо более мощный Ryzen.
    Ответ написан
    Комментировать
  • Как организовать пользовательские классы?

    megakor
    @megakor
    Go/PHP developer | Вконтакте
    Да, всю логику нужно выносить в отдельные классы.

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

    Я обычно делаю сервисы, как вы написали, но еще и:
    /app/Repositories - репозитории. Позволяют в контроллере брать информацию из БД, типа такого:
    $this->postsRepository->getPostsForHomePageLoop();

    А вообще способов много - можете прочитать про паттерны проектирования.

    Главное помните про SRP из SOLID. Что каждый класс отвечает за свою функциональность и не может выходить за её рамки.
    Ответ написан
    1 комментарий
  • Когда кончатся ipv4 адреса?

    fzfx
    @fzfx
    18,5 дм
    завтра ближе к обеду закончатся.
    но говорят, что уже в понедельник завезут ещё.
    Ответ написан
    Комментировать
  • Как обрезать длину строки, если в БД есть ограничение на кол-во символов?

    megakor
    @megakor
    Go/PHP developer | Вконтакте
    public function update(Request $request)
    {
        $request->validate([
            'title' => 'max:255', // где 255 - макс. длина строки
        ]);
    
        // ...
    }

    Но лучше соблюдать принцип SRP из SOLID и делать валидацию в отдельном файле Request.

    Ещё в html можно добавить ограничение для input:

    maxlength="50"
    Ответ написан
    Комментировать
  • В чем преимущества ILO от HP, по сравнению с тем же подключением по SSH?

    paran0id
    @paran0id
    Умный, но ленивый
    ssh -это подключение в ОС, а iLO - это по сути, удалённый монитор с клавиатурой. Если ваша система повиснет, отвалится от сети, или иным способом уйдёт в себя, по ssh вы в неё не попадёте, а по iLO - сможете. Даже больше того, по iLO вы можете подключиться к пустому серверу, на котором вообще нет операционной системы, и установить её удалённо.
    Ответ написан
    Комментировать
  • Как с Vue CLI использовать несколько SPA приложений?

    При сборке (npm run build) в dist создаются два .html файла, index.html и admin.html.
    И в данном случае, при переходе на /admin, я получаю 404.


    Судя по всему, необходимо настроить веб-сервер на отдачу правильного html файла.

    nginx для SPA, например, настраивается так, чтобы по любым путям отдавать index.html

    Вам нужно что-то вроде этого:

    server {
      listen 80;
    
      location /admin {
        root   /usr/share/nginx/html;
        index  admin.html
        try_files $uri $uri/ /admin.html;
      }
    
      location / {
        root   /usr/share/nginx/html;
        index  index.html
        try_files $uri $uri/ /index.html;
      }
    }


    Ссылки из основного приложения в admin должны быть ссылками, а не router-link (и наоборот)
    Инстанс роутера в admin должен иметь опцию base: '/admin/'.
    Ответ написан
    Комментировать
  • Как правильно раздавать видео?

    @Drno
    Сервера - гляньте хетзнер

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

    А кешируется видео у юзера или нет, зависит от Ваших настроек) чем и как будете отдавать
    Ответ написан
    Комментировать
  • Нормальная windows 10. Миф или реальность?

    Jump
    @Jump Куратор тега Windows
    Системный администратор со стажем.
    Я считаю 10-ку худшей системой всех времён и народов, а людей, которые используют и советуют Windows 10 можно назвать либо пропагандистами, которые на зарплате у Microsoft, либо это просто ребята с приветом (вас больше), потому что эту "Г" даже нормальной не назвать. Но увы я вынуждена переходить на неё из-за NVidia.
    Вы конечно извините - но это просто бред и вкусовщина.
    Я прекрасно пользуюсь и Windows 7, и Windows 8 и Windows 10. Кое где даже еще XP прекрасно работает.
    Все системы отличные, все имеют свои достоинства и недостатки. Десятка посвежее поэтому все новые фишки на ней.
    Да там есть такая проблема как излишняя самостоятельность системы - но с этим научились бороться, в идеале если хочется стабильности есть LTSC версия.

    Наверное, обновления - это главная проблема 10
    Да это проблема, но какая ОС без проблем? К тому же проблема решаемая.
    Наглое использование трафика тоже решается, если еще и роутер настроить - мышь без спросу не проскочит.

    Что отправляет? Куда отправляет?
    Это проблема не Windows 10 а всего современного софта. Весь софт - и графические редакторы и простенькие утилиты для бэкапа лезут в сеть сливают какую-то информацию, качают обновления и все это без спроса. Особенно браузеры - это вообще жуть. ОС на их фоне выглядит довольно скромно в этом плане!

    Поэтому я ищу какую-нибудь сборку или твики где:
    Если хотите чтобы работало нормально - никаких левых сборок! Только оригинальные дистрибутивы. Если цена не смущает - берите LTSC.
    Если не покупаете - тем более LTSC.
    Там гораздо меньше обновлений, они легко настраиваются и не ставятся без спроса. И нет ничего лишнего.
    Ответ написан
    Комментировать
  • Как реализовать "защиту" авторизации по номеру телефона?

    Vamp
    @Vamp
    1. Проверьте синтаксическую корректность номера телефона. Все мобильные номера в РФ начинаются на +79 и имеют длину ровно 11 цифр. Проверку можно даже добавить в веб форму на уровне js. Это нельзя назвать защитой от хулиганов, но она отсеет реальные ошибки и опечатки, облегчив жизнь обычным пользователям.

    2. Пробейте номер по базе россвязи (файл DEF-9xx). Так вы определите номера, на которые 100% не будет доставки. В отличии от проверки синтаксиса, не выдавайте пользователю ответ о некорректном номере. На все номера отвечайте "Одноразовый код отправлен, введите его сюда", но на невалидные номера не отправляйте сообщение.

    3. Добавьте ограничение на количество отправляемых форм в минуту с одного IP и количество отправляемых сообщений на один и тот же номер (независимо от IP).

    4. Оцените сколько может быть отправок форм в день и поставьте общий лимит на все отправки смс за день. Это единственный реальный способ контролировать атаку на сливание бюджета. Да, реальные пользователи пострадают при достижении лимита, но вы не должны доводить до него - настройте мониторинг количества отправляемых смс и алертинг при достижении порога в 90% от лимита, чтобы у вас было время среагировать на атаку и отбить её до полного исчерпания лимита. Либо если это всплеск реальных пользователей (например, неожиданно удачная реакция на рекламу), то у вас будет время скорректировать лимит. Можно рассчитывать лимит как 2 * среднее количество отправок смс за последние Х дней, чтобы не приходилось править его вручную по мере естественного роста посещаемости. Формулу и процент для алертинга, разумеется, подберёте под свои требования. Но можете взять и мои за основу.

    Отдельно хочу рассказать про так называемые прямые мобильные номера. Они выглядят как городские (например, +7495), но в реальности являются мобильными и могут принимать смски. Проверка в пункте 1 не пропускает такие номера и нет никакого способа проверить без отправки смс является ли отдельно взятый городской номер прямым мобильным. Прямых номеров мало по сравнению с настоящими мобильными или настоящими городскими. К тому же у каждого прямого номера есть мобильный аналог, начинающийся на +79, которым пользователь может воспользоваться для регистрации. Поэтому предлагаю просто забить на прямые номера, а в случае жалоб на невозможность регистрации с прямым номером, рассказывать про существование мобильного аналога, который может быть прописан где-то в договоре с оператором на оказание услуг связи или узнать в техподдержке оператора и с которым можно спокойно зарегистрироваться.

    Обязательное требование email'а не усилит схему защиты, так как не проблема наштамповать реальных адресов со скриптом, автоматически прокликивающим подтверждающие ссылки во входящих письмах.

    Альтернативным вариантом является аренда входящего номера. В этом случае не вы отправляете сообщения пользователям, а они вам. Обычно за входящий номер берут фиксированную плату в месяц независимо от количества смс, так что не придётся в принципе волноваться за бюджет. Но тогда у вас будут в пролёте пользователи с отключенной услугой отправки смс. А таких немало, могу сказать. Благодаря интернет-мессенджерам.
    Ответ написан
    2 комментария
  • Как правильно хостить и проигрывать видео в 2020?

    gbg
    @gbg
    Любые ответы на любые вопросы
    Почитайте статьи про niginx-rtmp
    Когда я делал свой стриминг, я делал несколько разных способов доставки с выбором способа, в зависимости от того, что за клиент подключился.
    Для андроидов, например, я слал webm.
    Для маков HLS
    Для писюков - тоже webm
    У меня был живой поток, так что архитектура была такая - один сервер делал транскодирование во все видеоформаты и все разрешения, (порядка 12 вариантов, 6 разрешений в двух форматах), и еще три энджайникса заворачивали расклонированные по udp-multicast потоки куда надо.

    Ваша проблема, скорее всего, не в формате, а в затыках дисковой подсистемы. Подумайте о кластере типа ceph.
    Ответ написан
    1 комментарий
  • Почему Facebook использует sha256 вместо blowfish?

    Lillipup
    @Lillipup
    Allons-y, Алонсо!
    Работает? Не трогай.
    Ответ написан
    Комментировать
  • Как организовать совместную работу верстальщика и программиста (Pug + Laravel)?

    zavoloklom
    @zavoloklom
    Fullstack разработчик
    Во-первых имеет смысл делать это все через git.

    А дальше либо объяснять верстальщику blade (что лучше, так сейчас у вас фактически 2 шаблонизатора и одна и та же работа выполняется два раза), либо выстроить какую-то такую систему:
    - при изменении верстки верстальщик меняет pug/html и делает pull request
    - программист ревьюит изменения и вносит соотвтствующие правки в blade шаблон
    Ответ написан
    Комментировать
  • Как правильно сегментировать сеть предприятия?

    @tamogavk
    @deni4ka
    Могу разработать и предоставить план по переходу на отказоустойчивую схему с возможностью расширения, также иерархический айпиплан, подбор оборудования, резервирование и и.д. Нарисую подробную схему как все будет работать. За деньги естественно. Бесплатно никто вас консультировать не будет
    Ответ написан
    18 комментариев
  • Laravel vs WordPress?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Если я выберу WordPress, то не выйдет мне это боком, если проект будет расти?
    Выйдет конечно, нет в вп ни нормальной архитектуры, ни гибкости, ни целостности. 90% плагинов и надстроек никем и никогда не тестировались нормально, ну там тесты, квалити контрол, кодестайл и вот это все.
    Все фреймворки же в основном:
    1) Гибкие и с нормальной архитектурой
    2) Покрыты тестами и удовлетворяют кодестайлу
    3) Весь новый функционал пишется поверх оттестированных компонент, если нужно что-то особенное - не надо думать как скрестить ежа с ужом, все можно сделать в едином стиле и без костылей.

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

    Совет - если это проект выстрелит/не выстрелит 50/50 - фигачьте мвп на вордпрессе, если взлетит - переписывайте. Худо-бедно оценить проект можно и на таком велосипеде. Дальше все равно надо будет писать нормальный проект.
    Ответ написан
    Комментировать
  • Оцените сборку ПК?

    Stalker_RED
    @Stalker_RED
    TDP процессора 75, видяхи 130 кажись. то есть блока питания хватит с приличным запасом, можно даже вместо 600 bronze взять 500 сильвер или голд (меньше жрет электричества, меньше греется).

    Самым шумным компонентом будет видеокарта, если это важно - ищите обзоры с указанием уровня шума, среди 2060 есть из чего повыбирать.

    Корпус многие выбирают или по внешнему виду (подсветка, стеклянные окна, вот это все) или по удобству ковыряния внутри корпуса (а потом не модифицируют ничего годами, ага), или по звукоизоляции. Лет 10-15 назад еще сравнивали как "организованы воздушные потоки", но сейчас они вроде у всех норм.
    В целом - толстый металл будет лучше глушить шумы чем тонкий пластик. Можно смотреть тупо по весу. Иногда можно найти шедевры.

    Ну и для продвинутых любителей тишины есть и блоки питания с пассивными радиаторами, и водяное охлаждение для видео и проца.
    Ответ написан
    Комментировать
  • Как правильно реализовать автозагрузку в PHP, не жертвуя использованием use?

    gluck59
    @gluck59
    Виртуальный глюк
    "У меня есть чемодан с инструментами. Мне нужно закрутить болт, но я не могу жертвовать использованием отвертки".

    Расшифруйте плиз, кто у вас жертва и почему.
    Ответ написан
    1 комментарий
  • Как расшифровать открытые данные пользователей инстаграмм?

    dimonchik2013
    @dimonchik2013
    non progredi est regredi
    так там же все видно

    что именно непонятно?
    Ответ написан
    1 комментарий
  • Mtproto - действительно безопасен?

    dimonchik2013
    @dimonchik2013
    non progredi est regredi
    на 100500%

    если. конечно, ключи у кого надо ключи
    Ответ написан
    Комментировать