Задать вопрос
Ответы пользователя по тегу PHP
  • Php pdo почему возвращает false?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Потому что этот код дважды бессмысленный.
    Во-первых, бессмысленно добавлять try-catch, если не включил выброс исключений.
    Во-вторых, если выброс исключений включён, то чтобы увидеть ошибку, никакое try-catch не нужно - РНР прекрасно покажет её и так.

    Вместо этого сарая из травы и палок надо написать
    <?php
    $host = '127.0.0.1';
    $dbname = 'bdKIZ';
    $username = 'root';
    $pass = '';
    $dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4";
    
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
    
    $pdo = new PDO($dsn, $username, $pass);
    $pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
    
    $sql = "SELECT * FROM `Detail`";
    $stmt = pdo->query($sql);
    var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));


    И после этого выполнить код и ознакомиться с сообщением об ошибке.
    Ответ написан
    1 комментарий
  • Связи в ООП, Агрегация в PHP как часто используется?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Основа всех современных фреймворков - это контейнер зависимостей. Который, создавая на лету экземпляр требующегося для обработки НТТР запроса класса, "внедряет" в него (через конструктор или через параметры методов) необходимые этому создаваемому объекту/вызываемому методу зависимости. Создавая их на лету или используя готовые.
    И, в свою очередь, создавая эти зависимости, также внедряет нужные уже им сервисы. И так по цепочке.

    Если вы посмотрите на пример реализации контроллера в Симфони например, то вы нигде не увидите что-то вроде
    public function process()
    {
        $request = new Request();
        $param = $request->get('name')
    }

    а только
    public function process(Request $request)
    {
        $param = $this->request->get('name')
    }


    Заметил, что в PHP если и используется связи между объектами(ассоциация), то только в виде композиции,

    А вот тут я реально удивился. Скорее это я бы у вас попросил "пример кода" в котором "вы заметили" композицию. Потому что в современном РНР коде её днем с огнём не найти - везде сплошная агрегация. Даже там, где по сути подошла бы и композиция. Давно ли вы видели в коде создание new Сlass внутри класса вместо использования $this->object? И если да - то мне страшно любопытно - где?

    Хотя нет, кажется я понял. Есть такие гении, которые действительно, вместо
    class User
    {
        public function __construct(Database $db)
        {
            $this->db = $db;
        }
    }

    пишут
    class User
    {
        protected $db;
        public function __construct()
        {
            $this->db = new Database();
        }
    }

    Но тут надо понимать, что это дети, которые вчера увидели редактор кода. Больше никто так не пишет.
    (Тут надо оговориться, что это не догма, и внедрение через параметры не обязательно. Вполне можно создать какой-то объект и на лету, но это случается гораздо реже, чем использование уже готового)

    редко бывает, когда создаётся самостоятельный класс, а потом он ещё и в другой класс попадает.

    А здесь вы вообще какую-то чушь написали. Если говорить про классы, то они вообще почти никогда не создаются кодом на лету. Классы пишет программист, и сохраняет в коде программы. Которая потом выполняется, и создает из этих классов объекты.
    А если вы имели в виду объекты, то их создаётся миллион, и все они "попадают" в другие объекты. Даже при обработке НТТР запроса
    Ответ написан
    9 комментариев
  • Здравствуйте! На хосте fornex php сервер не передает данные в БД, хотя на локалке все работало отлично. Как это исправить?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Чтобы попытаться стать РНР разработчиком (а не бабкой-гадалкой из соседнего ответа), надо открыть для себя волшебный мир отладки.
    И для начала научиться получать от РНР сообщения об ошибках.
    Во-первых, надо убедиться, что никакие ошибки не подавляются. Для этого в коде всегда должна быть строчка

    error_reporting(E_ALL);

    В-вторых, если для работы с БД используется mysqli, то не лишне добавить настройку ошибок и для неё.
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

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

    ini_set('display_errors',1);

    На боевом - наоборот, выключаем вывод на экран и включаем вывод в лог
    ini_set('display_errors', 0);
    ini_set('log_errors', 1);

    После этого запускаем свой код и смотрим, что написано в сообщении об ошибке.
    Ответ написан
    Комментировать
  • Вывод определенной информации на страницах с конкретными именами в адресе URL с помощью strpos?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Надо один раз распарсить строку,
    $section = explode("/",trim($_SERVER['REQUEST_URI'],"/"))[0] ?: 'index';

    и потом уже использовать полученные из неё данные
    $other_page = in_array($section, ['news','info']);
    if (!$other_page) {
        echo 'вывод содержимого';
    } else {
        echo 'вывод содержимого';
    }
    Ответ написан
    Комментировать
  • Как лучше взять данные из большого файла по ключу не перебирая строки?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Удивительно. Судя по истории вопросов, человек вроде бы занимается программированием почти 10 лет, с 2016 года.
    Но до сих пор рассуждает, как Чебурашка:
    - Гена, давай я понесу чемоданы, а ты понесёшь меня!

    можно ли как-то эту нагрузку снизить


    Можно. Для этого надо разместить эти строки в базе данных.
    Ответ написан
    2 комментария
  • Почему ошибка 502 после миграции с PHP 8.2 на PHP 8.3?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Ошибка 502 обычно означает кривые настройки сервера. То есть надо или трясти админов этого "хостинга где всё кнопочками" или учиться настраивать сервер самостоятельно и переезжать на впс.

    И на будущее.
    было записано только то, что вызывается 502 ошибка, а не причина почему она вызвана.

    Правило: даже если вы не понимаете, что написано в сообщении об ошибке, или думаете, что оно бессмысленное, все равно его надо скопировать его в свой вопрос целиком.
    Ответ написан
    Комментировать
  • Не работает часть скрипта PHP при смены PHP 7 на 8?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    В 7 версии этот код тоже не работает
    Ответ написан
    Комментировать
  • Как отладить плавающий баг проверки капчи?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Так же, как и любое взаимодействие браузера с сервером - через инструменты разработчика, вкладка "Сеть".
    Если "сессия не записывается", в 99% случаев это значит что браузер не прислал сессионную куку.
    И в инструментах разработчика надо смотреть заголовки запросов браузера и ответов сервера, смотреть есть ли в куках идентификатор сессии, и если есть - то какой.

    Плюс обычная отладка на стороне сервера, в частности дамп массива $_SESSION при каждом запросе, отображение всех ошибок, и так далее. Не бином ньютона
    Ответ написан
  • Заполнить не существующими датами из бд в графике apexcharts?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Принцип заполнения пустых дат всегда один и тот же:
    • получаем данные запроса в массив, который индексируем датой
    • создаем итоговый массив в цикле, подставляя значение из БД, если оно существует


    // получаем
    $sql = 'SELECT DATE(datetime) `date`, count(id) `count` FROM sells WHERE id != 1 GROUP BY DATE(datetime)';
    $result = $conn->query($sql);
    $sales = [];
    // индексируем
    while($row = mysqli_fetch_array($result)) {
        $sales[$row['date']] = $row['count'];
    }
    // создаем нужный интервал
    $begin = new DateTime($date_begin);
    $end = new DateTime($date_end);
    $interval = DateInterval::createFromDateString('1 day');
    $period = new DatePeriod($begin, $interval, $end);
    // заполняем итоговый массив
    $result = [];
    foreach ($period as $day) {
        $date = $day->format("Y-m-d");
        $result[$date] = $sales[$date] ?? 0;
    }
    // выводим
    echo "var rows=".json_encode(array_keys($result));
    echo "var values=".json_encode(array_values($result));


    Даты начала и конца обычно задаются заранее. Но если их надо получить из результатов запроса, то
    $date_begin = array_key_first($sales);
    $date_end = array_key_last($sales);
    Ответ написан
  • Функция str_replace() не работает?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    В строке не должно быть никакого&quot;
    Надо взять железную линейку, и надавать по рукам тому, кто писал этот код.
    После этого убрать из кода все вызовы функции htmlscpacialchars, все filter_var c идиотским FILTER_SANITIZE_STRING и вообще никак не портить входящие данные
    И после этого спокойно удалять из строки обычную двойную кавычку.

    А выводить любые данные через нормальный шаблонизатор.
    Ответ написан
    1 комментарий
  • Интеграция Telegram с CRM системой. Что посоветуете?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Классический вопрос "как на... обмануть систему".
    Если хотите нормальный сервис - то никак. Не надо. Никого. Обманывать.
    И никогда не строить на этом архитектуру.

    Если речь действительно о том, что "на той стороне будет отвечать живой человек", то сделайте общий аккаунт, в котором будут сидеть сотрудники плюс бота, который будет сидеть в этом аккаунте и осуществлять интеграцию с CRM.

    А вот если речь о том, чтобы сотрудники (или скорее всего CRM) сами писали пользователям, то через бота. А заказчик пусть спускается из мира грёз на землю.
    Ответ написан
    Комментировать
  • Почему в консоли вылетатет ошибка unexpected character at line 1 column 1 of the JSON data, когда поля формы не заполнены?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    1. Ошибки взаимодействия с сервером надо смотреть не в консольке, а во вкладке Сеть. Там в подвкладке Response или как она там в переводе называется, вы увидите ответ сервера.

    2. Как правильно написал в комментариях ProjectSoft, проблема в том, что вы определяете переменные только при успешном прохождении проверки. Но если данных нет, то ни переменной $name, ни $phone, ни $message в коде не существует. И в итоге РНР вам законно выводит ошибку при попытке обратиться к этим переменным.
    По итогам проверки переменная должна быть объявлена в любом случае. Это можно сделать либо с помощью конструкции else, либо как показано в примере ProjectSoft, с помощью тернарного оператора.
    Переменную $OK можно определить как результат логического выражения, без всяких условий
    $OK = $name and $phon and $message;
    Но сама по себе она не имеет смысла. У вас результатом кода $name and $phon and $message УЖЕ является логическое выражение, которое вы УЖЕ можете подставить в условие. И зачем это делать с пересадкой - непонятно.

    3. При этом надо понимать, что и isset, и empty в данном случае это подавление ошибок. И без нужды их лучше не применять. А просто написать
    $name = $_POST['name'];
    $phone = $_POST['phone'];
    $message = $_POST['message'];

    Тогда РНР сможет сообщить и об ошибках при составлении формы.

    Но чтобы эти ошибки зря не лезли при запросе файла, лучше весь код целиком заключить в проверку типа
    if ($_SERVER['REQUEST_METHOD'] === 'POST')

    Как вариант - проверять каждую переменную на существование и пустоту отдельно, и выдавать соответствующие ошибки, типа "Поле name не отправлено", "Поле name не заполнено", и т.д.
    Ответ написан
  • Почему не выводит первую строку в select?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Потому что она зачем-то была получена до начала вывода.

    Откуда вы все берете учебники с таким дебильным кодом? Тут все делается в три строчки
    $result = $mysql->query("SELECT * FROM `postavshik`");
    while ($row = $result->fetch_assoc()) {
        echo  "<option>" . htmlspecialchars($row['Name_pred']). "</option>\n";
    }

    И возьмите нормальное руководство.
    Ответ написан
    1 комментарий
  • Почему запрос возвращает пустоту?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Если запрос выполняется без ошибок но не возвращает ни одной строки, это значит что в БД отсутствуют данные, подходящие под указанные в запросе условия.
    Ответ написан
    Комментировать
  • Почему данные входящего запроса не сохраняются в файл?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Если РНР не может записать информацию в файл, он всегда сообщает - по какой причине.
    Вам надо всего лишь посмотреть сообщение об ошибке. На нормально настроенном сервере ошибки обычно пишутся в лог файл.
    (Скорее всего файл создан одним пользователем, а скрипт запускается другим, а права не выставлены. Но гадать в любом случае бессмысленно, надо прочитать сообщение об ошибке).

    Как вариант, что-то ещё дергает этот скрипт. Для надёжности, я бы добавил FILE_APPEND в оба вызова.
    Ответ написан
    Комментировать
  • Как при возникновения ошибки php показывать своё сообщение, вместо стандартного?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Во-первых, данная ошибка - это проблема валидации. И в этом конкретном примере никакие ошибки РНР перехватывать не надо. А надо проверить значение (и существование ) $_GET['val1'] и $_GET['val2'] и вернуть клиенту соответствующие ошибки.

    В целом же ошибки РНР перехватываются функциями set_exception_handler() для исключений, set_error_handler() для нефатальных ошибок и register_shutdown_function() для фатальных. Пример можно посмотреть здесь https://phpdelusions.net/articles/error_reporting

    Важно при этом помнить, что сам текст ошибки клиенту не показывается, а доводится только сам факт ошибки, "Что-то пошло не так, зайдите позже".
    Ответ написан
    Комментировать
  • Как вставлять записи в базу данных со значением null, если переменная пустая?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Сначала надо определиться с тем, что такое "пустая переменная".

    Если она содержит значение null, то просто вставить через подготовленный запрос, так же, как это надо делать всегда,
    выполняя запросы с переменными
    $sql = NSERT INTO `table` (`id`, `value_1`, `value_2`) VALUES (?,?,?)";
    $connection->prepare($sql)->execute([null,$var1, $var2]);

    (если у вас устаревшая версия РНР, то так)
    $sql = NSERT INTO `table` (`id`, `value_1`, `value_2`) VALUES (null,?,?)";
    $stmt = $connection->prepare($sql);
    $stmt->bind_param("ss",$var1, $var2)
    $stmt->execute();


    Если же переменная содержит пустую строку, то сначала присвоить ей null, например
    $var1 = ($var1 !== '') ? $var1 : null;
    И потом точно так же подставить в запрос
    Ответ написан
    Комментировать
  • Как сделать поиск по картинке?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Комментировать
  • Как с помощью php отдать react?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Как я уже не раз говорил, чтобы получить ответ на свой вопрос, надо сначала разобраться с кашей у себя голове.
    Вас же на первом же шаге унесло не туда.

    jQuery уже в прошлом

    это правда

    его теснят фреймворки типа react

    а это уже чушь собачья
    jQuery - это был костыль, позволявший выполнять определенные задачи, которые было невозможно или слишком сложно выполнить на чистом JavaScript. Но уже больше 10 лет нужда в этом костыле полностью отпала
    К фреймворкам типа React этот костыль не имеет никакого отношения вообще.
    Для замены jQuery вам нужно просто выучить Яваскрипт.

    Реакт же - это, условно говоря, способ построения приложения. Его можно учить, а можно не учить. Вы можете продолжать использовать обычный подход, когда HTML рендерится на сервере в ответ на каждый запрос.

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

    Но повторюсь, это только если вам действительно нужен реакт. А для замены jquery он не нужен.

    404й редирект

    для начала, такой вещи, как "404й редирект" в природе не существует.
    Бывает либо редирект (коды ответа 3хх), либо 404. Два НТТР статуса вы никогда не отдадите.

    при этом сама по себе дурацкая задача "если пользователь пришёл с определенного ip и ему нужно отдать 404" вообще никакого отношения к обсуждаемому вопросу не имеет. И решать ее по-хорошему надо на уровне веб-сервера. Если вообще надо, в чем есть большие сомнения.
    Ответ написан
    4 комментария