Профиль пользователя заблокирован сроком с 10 апреля 2022 г. и навсегда по причине: систематические нарушения правил сервиса
  • Как создать БД для чекбоксов?

    glaphire
    @glaphire Куратор тега PHP
    PHP developer
    Один из вариантов поиска:
    database design for checkbox values.
    Самые частые подходы - отдельная таблица с набором опций как колонок или же поле в основной таблице, где варианты ответов это побитовая маска.
    Ответ написан
    3 комментария
  • По какому волшебству в Laravel работает Hash::check() - ведь хэши генерируемые Hash::make() всегда разные?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Если посмотрите на хэш, то его можно разделить на несколько частей
    $2y$10$jSAr/RwmjhwioDlJErOk9OQEO7huLz9O6Iuf/udyGbHPiTNuB3Iuy
    2y - тип хэша, BCRYPT.
    10 - алгоритмическая сложность bcrypt.
    jSAr/RwmjhwioDlJErOk9 - 21 символ соли.
    OQEO7huLz9O6Iuf/udyGbHPiTNuB3Iuy - собственно хэш.
    При генерации хэша задаётся случайная соль, поэтому хэш каждый раз разный.
    При проверке пароля параметры хэширования берутся из строки проверяемого хэша, поэтому при правильном пароле хэши совпадут.
    Ответ написан
    1 комментарий
  • Как вывести список клиентов с непрерывной историей за год?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT ID_client
    FROM Transactions_info
    WHERE date_new BETWEEN @first_day_of_period
                       AND @last_day_of_period
    GROUP BY ID_client
    HAVING COUNT(DISTINCT date_new) = DATEDIFF(@last_day_of_period, @first_day_of_period) + 1
    Ответ написан
    6 комментариев
  • Как сделать период дат для if else php?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    $simpleDate = date('m-d');
    if ($simpleDate >= '12-20' || $simpleDate <= '01-11') {
        ...
    }

    P.S. А вообще, можно сделать гораздо универсальнее. Описать в конфиге интервалы и соответствующие им логотипы.
    class Config
    {
        public const LOGOS = [
            ['from' => '01-01', 'to' => '01-11', 'logo' => 'logo-newyear.png'],
            ['from' => '04-25', 'to' => '05-03', 'logo' => 'logo-firstmay.png'],
            ...,
            ['from' => '12-20', 'to' => '12-31', 'logo' => 'logo-newyear.png']
        ];
    }
    ...
    $simpleDate = date('m-d');
    $logoName = 'logo-standard.png';
    foreach (Config::LOGOS as $logoDef) {
        if ($simpleDate >= $logoDef['from'] && $simpleDate <= $logoDef['to']) {
            $logoName = $logoDef['logo'];
        }
    }
    Ответ написан
    Комментировать
  • Как вывести данные из БД по последней дате?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Во первых код в вопрос нужно вставить как текст, в соответствующий тег, дабы можно было нормально цитировать ваш "код".
    Во вторых - неплохо было бы изучить хотя бы базовые основы sql
    В третьих - запросы нужно всегда создавать через подготовленные выражения, это должно быть на уровне привычки, кроме того - выносите код sql в отдельные строковые переменные, чтобы их можно было в любой момент вывести и посмотреть. Ну и нормальное форматирование для кода, в том числе и для строк запроса, очень помогает.

    Если хотя бы отформатировать сам запрос, скорее всего сразу увидишь ошибку, если хоть какое-то понимание sql есть.
    Ответ написан
    Комментировать
  • Чем 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
    Связь не устанавливается - такие утверждения нужно конкретизировать)
    Наверное, выдает ошибку о том, что foreign key ссылается на несуществующие записи?
    В таком случае, нужно сначала все связуемые таблицы проверить JOIN'ами и найти потенциальные несоответствия, потом решить что с ними делать - либо удалить, либо создать недостающие записи.
    (Прошу прощения - ошибку на скрине не сразу заметил).
    Ответ написан
    4 комментария
  • Везде ли нужно проверять на существование элемента в массиве?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    Правы оба.
    Лучше раньше упасть, чем обработать кривые данные так, как будто они нормальные. Но и просто бездумно падать в самую базовую ошибку неправильно - потом задолбаетесь выяснять при каких обстоятельствах код упал. Лучше провалидировать и кинуть осмысленное исключение, которое поможет отловить проблему.
    Ответ написан
    1 комментарий
  • Как запретить срабатывание POST метода?

    @MikUrrey
    В upload.php в самом конце сделайте редирект на эту же страницу:
    //определяем протокол - HTTP/HTTPS
    $proto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')? 'https': 'http';
    //шлем заголовок для "обновления" страницы без пересылки формы.
    //все последующие "ручные" обновления страницы будут происходить без отправки формы
    header('Location: ' . $proto . '://' . $_SERVER['HTTP_HOST'] . '/' . $_SERVER['REQUEST_URI']);
    exit;

    Вообще, это "best practice", перебрасывать редиректом после обработки формы, если не было ошибок при сохранении формы.
    Exit в конце прерывает выполнение остального кода.
    Ответ написан
    3 комментария
  • Почему не срабатывает обратная перекодировка json?

    DevMan
    @DevMan
    и это абсолютно нормально и по стандарту.
    если вам упало видеть кириллицу, то есть флаг JSON_UNESCAPED_UNICODE
    Ответ написан
    Комментировать
  • Как добавить запись в определенный столбец MYSQL?

    rozhnev
    @rozhnev Куратор тега MySQL
    Fullstack programmer, DBA, медленно, дорого
    UPDATE table_name SET control = 'what_you_need_here' WHERE id = 1;


    https://habr.com/ru/post/123636/
    Ответ написан
    Комментировать
  • Как сплюсовать количество часто встречающихся слов из массива строк?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Сначала решите подзадачу с единственным предложением:
    1. разбейте на слова по пробелам
    2. удалите по краям слов не-буквы — знаки препинания
    3. приведите все в маленькие буквы

    Покажите, что получилось, потом поговорим.
    Ответ написан
    2 комментария
  • Interface для Repository и Service, как правильно сделать?

    AmdY
    @AmdY
    PHP и прочие вебштучки
    Вы плодите лишние сущности, которые к тому же занимаются дублированием.
    Ваш UserService должен принимать UserRepository и работать с данными через него.
    Так же и контроллер должен работать с UserService и не работать напрямую с UserRepository.
    Простая цепочка UserModel -> UserRepository -> UserService -> UserController. Если вы начнёте переставлять звенья, то цепочка запутается и будет хуже чем прямая работа с UserModel.

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

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    опрашиваем api пока не получим нужные данные
    В вашей постановке уже есть большая часть ответа - формулировка "пока не" чётко указывает на необходимость использования цикла.

    foreach (['anime-tv-series', 'show-tv-series', 'tv-series'] as $type) {
      $json = json_decode($this->videocdn_get($data, $type), true);
    
      if ($json['status'] == 'true') {
        return $json;
      }
    }
    
    return ['status' => 'false'];


    Ну или то же самое, но без return:
    $response = ['status' => 'false'];
    
    foreach (['anime-tv-series', 'show-tv-series', 'tv-series'] as $type) {
      $json = json_decode($this->videocdn_get($data, $type), true);
    
      if ($json['status'] == 'true') {
        $response = $json;
        break;
      }
    }
    Ответ написан
    2 комментария
  • Исправить ошибку в запросе. Какая ошибка может быть?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    data_issued + 10 < curdate()
    Что вы хотели здесь сделать?
    Во-первых, прибавлять число к дате беcсмыссленно, надо прибавлять (или вычитать) специальную величину - интервал. Во-вторых, чтобы была возможность использовать индекс, надо менять не значение поля, а то, с чем его сравниваем.
    `date_issued` < CURDATE() - INTERVAL 10 DAY
    Ответ написан
    1 комментарий
  • Как правильно работать с большим количеством данных?

    batyrmastyr
    @batyrmastyr
    - получение данных об общем количестве записей для построения пагинации, это SELECT count(id)

    1. count(*), а не count(id)
    2. если вас не сильно интересует абсолютно точное значение для миллионов результатов, то делаете оценку количества, начать проще с EXPLAIN <текст запроса> вы можете получить оценку количества результатов. Мы для себя решили, что если по оценке меньше 50 000 строк, то вслед за этим делаем обычный SELECT count(*) для получения точного количества.
    Потом дергается запрос для получения данных на экспорт

    1. Пожалуй, вам от этого нужно избавляться в первую очередь. Нажал человек на кнопку "экспортировать" - экспортируете, а до этого и дёргаться нет смысла. Фильтры можно получить либо при клике, либо из заголовка referer
    2. Если вам нужно абсолютно все данные, то ставите задание на экспорт в очередь и выполняете его в отдельном процессе, сохраняете в файл. Для пользователя рисуете прогресс выполнения и выводите его в нажатую пользователем кнопку, хотя можно тупо на отдельной странице выводить список "заказанных" выгрузок и ссылки на скачивание.
    Запросы на каждый выпадающий список в фильтрах - SELECT distinct field_name

    Можно с какой-то периодичностью выгружать выхлоп таких запросов в материализованное представление / справочную таблицу / ENUM. Для обновления таких справочников "в реальном времени" можно повесить триггер на вставку в основную таблицу который будет делать INSERT INTO dictionary (value, column_oid) ON CONFLICT / ALTER TYPE ADD VALUE IF NOT EXISTS
    После чего в основной таблице заводите рядом поле под идентификатор в справочнике и индексируете уже его.
    Запрос при фильтрации и сортировке - SELECT * FROM some_table WHERE field_name LIKE '%value%'

    1. если у вас значения длинные (от 8 - 10 символов), то стоит попробовать триграммные индексы. Но на коротких значениях они могут замедлить поиск раза в полтора-два.
    2. Полнотекстовый поиск. В частности есть поиск лексемы по префиксу ts_tsquery('сло:*') (быстро найдёт и "слово" и "словарь", но не найдёт "однословное")
    3. Для полей по которым вы сделаете словари лучше делать поиск через словарь SELECT * FROM table WHERE column_dictionary_id IN (SELECT id FROM dictionary WHERE value LIKE '%текст%'). В словаре у вас наверняка на порядок - три меньше значений, а несколько сотен или тысяч значений в IN постгрес нормально пережуёт.
    Полей много, разные даты, guid, названия проектов, данные из поля типа json, цены.

    Активнее используйте функциональные и частичные индексы.
    Например, у нас есть кадастровые номера. Триграммный индекс по ним весит 56 мбайт, а BTREE по номерам урезанным до кадастровых кварталов - 15 мбайт, в поиске к "cadastre_id LIKE '11:22:333333:1%'" добавился "AND to_quarter(cadastre_id) = '11:22:333333'", но сам поиск получается на порядок быстрее (~5 мсек вместо 50 - 70).
    Главное не забывайте о стоимости этих самых функций - индекс по to_quarter может строиться всего в 1,5 раза дольше нефункционального, если делать LEFT(cadastre, -(position(':' IN reverse(cadastre))), а может и в 100 раз, если использовать регулярку.
    На все индексы не поставишь, тем более что один индекс может добавить гигов 5-10 к весу.

    Если ещё не обновились, то обновляйтесь на 13-ю версию, там размер BTREE индексов уменьшили в 3 раза. Ну и посмотрите, возможно вам где-то нужны GIST, GIN или BRIN индексы.
    Ответ написан
    2 комментария
  • Как взять последнюю часть ссылки в php?

    DevMan
    @DevMan
    $link = 'http://website/tag/culture/';
    echo basename( $link );
    Ответ написан
    1 комментарий
  • Как починить добавление коментариев?

    rozhnev
    @rozhnev Куратор тега PHP
    Fullstack programmer, DBA, медленно, дорого
    Во-первых: поставьте запись в базу после условия
    Во-вторых: прочитайте про SQL-injection и используйте prepared satatements
    if( empty($errors))
    {
        //добавить коментарий
        $stmt = $connection->prepare("INSERT INTO `comments` (`author`,`email`,`text`,`pubdate`,`articles_id`) VALUES (?, ?, ?, NOW(), ?)");
        $stmt->bind_param("sssi", $_POST['author'], $_POST['email'], $_POST['text'], $art['id']);
        $stmt->execute();
        echo '<span style ="color:green;font-weight: bold;margin-bottom: 10px;display: block;">Коментарий успешно добавлен!</span>';
     }
    Ответ написан
    1 комментарий
  • Как записать дату в таблицу MySql и в чём может быть проблема?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    prepared statements
    prepared statements
    prepared statements
    prepared statements
    Ответ написан
    3 комментария