Задать вопрос
  • Как правильно писать catch в php?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Для того чтобы правильно писать catch, надо писать осмысленный код.

    А здесь мы наблюдаем очаровательный пример карго-культа.
    Узнав, что "толстый контроллер - это плохо, а сервисы - это хорошо", автор небрежным движением руки замел весь мусор под ковёр перенёс весь код из контроллера в "сервис". Ну а что? Контроллер худой, весь код в сервисе!
    Тот факт, что сама кривая структура проекта осталась, по сути, той же самой, нас не смущает.
    Как и то, что сервис вдруг начал выполнять функции НТТР контроллера и кидать почему-то НТТР исключения. Что с этими исключениями делать в случае, если тот же сервис будет вызван из консольной команды - загадка.

    Но самое забавное, что при всём при этом контроллер всё равно пытается выполнять работу модели. Казалось бы, какое отношение интерфейс для обслуживания НТТР запросов имеет к транзакциям в базе данных? А вот поди ж ты!

    Чтобы сделать этот код осмысленным, контроллеру всё-таки придется потрудиться, и выполнить какую-то работу самому, а не перекладывать на "сервис". А так же отдать модели то что ей принадлежит.

    В общем транзакцию перекинуть в createDefault. причём не напрямую, а ещё ниже - в слой для работы с БД. Стартовать транзакцию до валидации данных - это как бы *не совсем логично*, мягко говоря. И в итоге, как по волшебству, весь этот говнокод исчезнет как страшный сон.
    При этом в параметрах передавать не НТТР реквест чохом, а осмысленный набор параметров, вынутый предварительно из реквеста!
    В частности, если модель сама проверяет права доступа, то и передавать ид пользователя из авторизации.

    При этом модель не должна кидать НТТР исключения. Она должна кидать исключения бизнес-логики. Которые контроллер уже может ловить и транслировать в хттп. Но тут видимо уже сложнее, поскольку это ж ларавель судя по всему.

    В любом случае, уж catch (Exception $e)-у тут точно не место

    Но это если рассматривать твой конкретный случай.
    В общем же случае правильный код написал Илья.

    То есть внутри трая операции с БД и коммит.
    в кетче роллбэк и перевыброс исключения. Только ловить надо Throwable

    try {
      DB::beginTransaction();
      // запись в БД
      // запись в БД
      // запись в БД
      DB::commit();
    } catch (\Throwable $e) {
      DB::rollBack();
      throw $e;
    }
    Ответ написан
    2 комментария
  • На что проверять строку, введенную со стороны пользователя на php?

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

    Но если подумать, то ответ становится очевидным: не бывает таких "проверок", которые автоматически делают данные "безопасными".
    Поиск таких универсальных проверок - это такая же глупость, как поиск "базовых правил безопасности для человека". Ты встречал кого-нибудь, кто все время носит каску, наколенники, бронежилет и презерватив? Независимо от того, собрался он кататься на роликах, на войну, или на свидание?

    Данные не бывают "опасными" или "безопасными" сами по себе.
    Всё зависит от контекста.
    А любая обработка "просто на всякий случай" тупо испортит данные.
    К примеру твоя strip_tags() изуродует математический текст, в котором встречаются символы "больше" и "меньше".

    Поэтому и надо форматировать данные перед использованием, в зависимости от конкретного контекста, а не заранее. Используем в SQL? Применяем подготовленные выражения. Используем в HTML? Применяем htmlscpecialchars. Используем в URL? Применяем urlencode. Используем в яваскрипте? Применяем json_encode. И так далее. Тебе уже самому должно быть смешно, глядя на этот набор "базовых проверок", если их накатывать все скопом.

    Плюс не надо путать форматирование данных и их валидацию.
    Валидация, в принципе, хорошая вещь, но надо понимать что во-первых, она не имеет никакого отношения к безопасности, и не может заменить контекстное форматирование данных, а во-вторых, уж тем более не может быть "универсальной" по определению.
    Ответ написан
    5 комментариев
  • Как передать папку большого объема через windows по интернету?

    @unseriously
    Торрент
    Создаете торрент-файл, который указывает на вашу папку. Кидаете чуваку торрент-файл, который весит несколько килобайт - чувак через торрент качает папку - профит.
    Ответ написан
    6 комментариев
  • Как на развернуть весь сайт в index.php?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Сейчас в этом коде все поставлено с ног на голову.
    Я так понимаю, что всё затевается ради того, что "Шапка и футер сайта у меня везде одинаковые"
    И сначала идет шапка, потом этот матч, а потом футер.
    То есть у нас код начинается с вывода HTML, в то время как это должно быть самое последнее, что происходит в скрипте.
    А всё должно быть строго наоборот - сначала должна выполняться обработка данных РНР кодом, и только потом начинаться вывод HTML.

    Взять к примеру запрос /cart, который в обязательном порядке должен обрабатывать запросы POST
    после такого запроса обязательно должен выполняться редирект. А редирект мы сделать не можем, потому что у нас пол-сайта уже клиенту ушло.
    Не говоря уже о других НТТР загололовках, или о том, что хидер у тебя не статичный, и значительно меняется от страницы к странице.

    Для начала надо сделать вот так, phpfaq.ru/tech/tpl#example

    Потом, когда всё заработает, можно будет переделать на единый индекс, хотя это не будет иметь большого смысла на данном этапе. потом, когда сайт будет представлять из себя не отдельные страницы, а фабрику по отдаче контента - тогда можно будет переделать на единый индекс.
    Ответ написан
  • Чем PHPMailer отличается от обычной mail() функций??

    TemaSM
    @TemaSM
    Fullstack, DevOps, InfSec
    Функция mail() в PHP по сути вызывает встроенную в систему почтовую программу - стандартно, это sendmail в linux (также, возможно использовать qmail, postfix, но для этого надо сначала сконфигурировать PHP через .ini файл).
    Подробнее про Mail в PHP: https://www.php.net/manual/ru/book.mail.php
    И про основную проблему кроссплатформенного использования: https://habr.com/ru/post/26518/

    PHPMailer - это мощная библиотека, реализующая почтовые транспорты, а не использующая sendmail как стандартная mail() функция. Имеет из коробки большое количество возможностей, таких как (в списке представлена лишь малая часть):
    • полная поддержка SMTP, Qmail, POP3, IDN, DKIM;
    • поддержка SSL и TLS;
    • работает на любой win32 и *nix платформе;
    • гибкость отладки;
    • определяемые вручную заголовки писем;
    • совмещение нескольких сообщений и вложений;
    • встроенная поддержка изображений;
    • умеет посылать письма с множественными: адресатами (TO), копиями (CC), BCC и REPLY-TO;
    • многослойные/альтернативные сообщения для клиентов, которые не могут читать HTML письма;
    • поддержка 8 бит, base64, бинарного режима, и пригодного для печати формата;
    • перенос слов (word wrap);
    • сообщения в виде HTML (шаблоны);
    • библиотека проверена на множестве SMTP серверах: Sendmail, qmail, Postfix, Imail, Exchange, Mercury, Courier;
    • библиотека используется под капотом таких гигантов: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla;

    Подробнее можно прочитать тут:
    https://jino.ru/journal/articles/pochta-phpmailer/
    https://www.sesmikcms.ru/pages/read/ischerpyvajusc...

    Помимо PHPMailer существуют и другие крутые библиотеки, оставляю список для интересующихся:
    Swiftmailer
    (Symfony) Mailer

    Если вы активно пользуетесь функцией mail() при разработке на PHP и до сих пор ещё не сталкивались с проблемами при её использовании на хостингах или на своих собственных серверах без соответствующего правильно настроенного окружения, то mail() вам идеально подходит. А когда столкнётесь с проблемами или захотите иметь больше возможностей из коробки, станут очевидными плюсы PHPMailer и других специализированных библиотек.
    Ответ написан
    1 комментарий
  • Как добавить в базу данных несколько записей?

    @MikUrrey
    Ошибка в строке
    $query->execute(['nickname', 'email' => $nickname, $email]);

    вероятно, должно быть так
    $query->execute(['nickname' => $nickname, 'email' => $email]);

    и еще,
    'VALUES(:nickname, email)'
    должно быть так:
    'VALUES(:nickname, :email)'
    Ответ написан
    Комментировать
  • Как найти значение по ключу в объекте с неизвестной глубиной вложенности?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Рекурсия есть:

    const find = (data, key) => Object
      .entries(data instanceof Object ? data : {})
      .reduce((found, [ k, v ]) => found ?? (k === key ? v : find(v, key)), null);

    Рекурсии нет:

    function find(data, key) {
      for (const stack = [ data ]; stack.length;) {
        const n = stack.pop();
        if (n?.hasOwnProperty(key)) {
          return n[key];
        }
    
        stack.push(...Object.values(n ?? {}));
      }
    
      return null;
    }
    Ответ написан
    Комментировать
  • Как определить дату, отстоящую от другой даты на определённое количество дней?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const days = 46330;
    const date = new Date();
    date.setDate(date.getDate() + days);
    const dateStr = date.toLocaleDateString('ru-RU', {
      day: 'numeric',
      month: 'short',
      year: 'numeric',
    });
    
    console.log(dateStr);
    Ответ написан
    Комментировать
  • Почему киви при успешной оплате уведомляет меня пустым массивом?

    Spartak-2205
    @Spartak-2205
    Разработка и создание сайтов
    Потому что данные от киви приходят не в post
    $data = json_decode(file_get_contents('php://input'), true);
    print_r($data);
    Ответ написан
    5 комментариев
  • Как правильно прикрутить анимацию в файле JSON на сайт?

    Get-Web
    @Get-Web Куратор тега JavaScript
    Front-End Developer
    Анимацию разбить на кадры и создать спрайт, после чего используя animation steps запустить в нужное время с нужным кол-вом повторений.
    Ответ написан
    Комментировать
  • Как убрать эффект cursor:pointer на телефоне?

    notiv-nt
    @notiv-nt
    Как ваше ничего? Да, моё тоже
    -webkit-tap-highlight-color: transparent;
    Ответ написан
    Комментировать
  • Как заставить работать пагинацию?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Пусть в сторе кроме собственно массива данных также хранятся текущая страница и общее количество страниц; действие fetchCharacters - пусть загружает не дефолтную первую страницу, а какую будет указано:

    state: {
      characters: [],
      page: 0,
      pages: 0,
    },
    mutations: {
      setCharacters: (state, { characters, pages, page }) =>
        Object.assign(state, { characters, pages, page }),
    },
    actions: {
      async fetchCharacters({ commit }, page = 1) {
        try {
          const { data: { info, results } } = await axios.get(`${BASE_URL}?page=${page}`);
          commit('setCharacters', {
            page,
            pages: info.pages,
            characters: results,
          });
        } catch (e) {
          console.error(e);
        }
      },
    },

    В компоненте, где используется пагинация, делаем вычисляемое свойство, которое будет отвечать за текущую страницу - геттер достаёт значение из стора, сеттер вызывает действие fetchCharacters:

    computed: {
      currentPage: {
        get() {
          return this.$store.state.page;
        },
        set(page) {
          this.$store.dispatch('fetchCharacters', page);
        },
      },
    },

    Привязываем это вычисляемое свойство к экземпляру компонента пагинации:

    <el-pagination
      v-model:current-page="currentPage"
      :page-count="$store.state.pages"
      layout="prev, pager, next"
      background
    />

    https://jsfiddle.net/qbjc9onm/
    Ответ написан
    Комментировать
  • Почему не работает код?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вопрос бессмысленный - код работает. Между "не работает" и "работает не так, как задумано" есть существенная разница. Попытайтесь её осознать.

    params = format({

    Зачем здесь вызов format? Не нужен.

    params_list = Object.values(params)
    console.log(params_list)
    for (var v in params_list) {s=s+v+'='+params[v]+'&'}

    Вот это конечно дичь дикая. Чтобы такое написать, надо не знать, как работает цикл for-in. Разберитесь. Не нужен тут массив значений, перебирать надо было сразу params.

    А вообще, всё это делается гораздо проще:

    function format(params, method) {
      return `https://api.vk.com/method/${method}?${new URLSearchParams(params)}`;
    }
    
    console.log(format({ access_token, version }, method));
    Ответ написан
    4 комментария
  • Как просуммировать элементы массива, расположенные до нуля?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const sum = arr.reduceRight((acc, n) => n && acc + n, 0);

    или

    let sum = 0;
    for (let i = 0; arr[i]; sum += arr[i++]) ;

    или

    let sum = 0;
    for (const n of arr) {
      if (!n) {
        break;
      }
      sum += n;
    }

    или

    const sum = (function sum(arr, i = 0) {
      return arr[i] ? arr[i] + sum(arr, i + 1) : 0;
    })(arr);
    Ответ написан
    1 комментарий
  • Как тут происходит сложение a и b?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Это "сложение" (не сложение) работает только для целых чисел >= 0.

    Если передать в Array одно число, будет создан (будет попытка создания - отрицательные и нецелые числа приведут к ошибке) массив указанной длины. Метод push может принимать несколько значений, а возвращает - новую длину массива, после добавления элементов. Т.е., в массив из трёх элементов добавили ещё четыре, и получили длину.
    Ответ написан
    Комментировать
  • Как прочитать вторую строку .txt файла?

    nokimaro
    @nokimaro
    Меня невозможно остановить, если я смогу начать.
    <?php
    $fileObject = new \SplFileObject('file.txt');
    $fileObject->seek(1); //пропускаем одну (первую) строчку
    $line = $fileObject->current();
    Ответ написан
  • Что предпочтительнее insertAdjacentHTML или создавать элементы через createElement?

    y0u
    @y0u Куратор тега JavaScript
    dev
    Всё зависит от ситуации. Предпочтительнее createElement, так как в момент создания сохранится ссылка на элемент для последующей работы с ним. Если работать с этим элементом не нужно, например если с сервера пришел ответ в виде html строки и нужно всего лишь отобразить результат без дополнительных действий, то createElement здесь не нужен.
    Ответ написан
    Комментировать
  • Как сгенерировать код P-XXXXXXXX, где X - числа [PHP]?

    nokimaro
    @nokimaro
    Меня невозможно остановить, если я смогу начать.
    function generator($litera) {
        return mb_strtoupper($litera)."-".random_int(10000000, 99999999);
    }


    for($i = 1; $i <= 5; $i++) {
        $code = generator("P");
        echo $code."\n";
    }
    
    //P-10762100
    //P-85344418
    //P-57088151
    //P-14499009
    //P-24729321
    Ответ написан
    1 комментарий