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

    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 комментария
  • Почему в ответе скрипта появляется закрывающий тег РНР?

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

    Человек с адекватным восприятием реальности сделает очень простое умозаключение: если в ответе появляются посторонние символы, то это значит, что они присутствуют в скрипте. После этого найдет эти символы и удалит. Тупо проверив все файлы, которые участвуют в обработке запроса.
    А для неразрешимой проблемы "почему на локалке посторонних символов нету" найдет простое рациональное объяснение: файлы "на локалке" и "не на локалке" отличаются.

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

    Ну и поскольку у меня глаза не могут смотреть на эти хаотичные телодвижения, то вот как этот код может выглядеть на самом деле

    файл init.php
    <?php
    $conn = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASSWORD);  
    $conn -> setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); 
    
    set_exception_handler(function ($e)
    {
        http_response_code(500);
        error_log($e);
        echo json_encode([
                'code' => 'error',
                'message' => 'Internal server error'
        ]);
    });

    файл с кодом
    <?php
    // Подключаемся к базе данных
    require 'init.php';
    
    // Получаем данные
    $list = get_list($conn);
    
    echo json_encode([
        'code' => 'success',
        'data' => $list
    ]);


    Без всей этой кропотливой возни и самоповторов.
    Отсутствие данных ошибкой не является. В JS можно проверить массив data и вывести сообщение, что он пустой. Никакой специальный код для этого передавать не нужно.
    А настоящие ошибки надо обрабатывать единообразно, в одном месте. А не писать обработку после каждой строчки, причем каждый раз по-разному.
    Ответ написан
    3 комментария
  • Почему возникает ошибка Maximum execution time exceeded?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Потому что долгоиграющие задачи надо выполнять не через браузер, а в консоли.
    Либо ручками, либо по крону (ну или через очереди, но этот вариант явно не соответствует уровню вопроса).
    Ответ написан
    2 комментария
  • Почему не записывает в бд?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Не очень понятно, что имеется в виду под "подключением", но будем считать что речь про добавление данных в БД. Это может присходить по трем причинам:
    1. Код добавления вообще не вызывался.
    2. При добавлении произошла ошибка.
    3. Данные добавились в одну базу, а результат смотрим в другой.

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

    <?php
    # Настройка ошибок
    # Для локального сервера
    ini_set('display_errors', 1);
    # Всегда
    error_reporting(E_ALL);
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

    Добавив этот код, надо запустить свой скрипт еще раз и смотреть, ошибки, которые он выведет.

    Плюс обязательно прочесть статью https://habr.com/ru/articles/662523/
    Ответ написан
    5 комментариев
  • Почему у меня неправильно определяется IP пользователя?

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

    Сначала надо задать себе вопрос, а какое вообще отношение имеет Ipconfig к адресу клиента. И после долгих мучительных размышлений вдруг сообразить, что все три адреса совпадают, когда разрабатываешь сайт на уютном домашнем компике, а при размещении у провайдера адрес в Ipconfig никогда не будет совпадать, поскольку внезапно там будет будет адрес сервера, а не клиента

    После этого надо посмотреть на сам адрес. В котором, скорее всего, тоже будет адрес из приватной сети.
    И нелепые фантазии про чебурнет вдруг превратятся в провайдера, который поставил нормальный веб-сервер проксировать запросы к ламерским сайтам хомячков.
    После этого выяснить у провайдера, в каком именно НТТР заголовке передается исходный IP клиента, и использовать только его, а не перебирать наугад все возможные. Причем настроить на уровне веб-сервера (mod_remoteip / ngx_http_realip_module)
    Ответ написан
    Комментировать
  • Что стоит использовать для защиты PHP-кода на текущий момент?

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

    Сам по себе код мёртв. Он устарел ещё до релиза. В работе софта важна не дискетка с исходниками, а поддержка. Вот поддержку и надо продавать. И не дрожать над каждым вором. Потому что защита от одного вора отпугивает 10 честных покупателей.

    Плюс всегда есть SAAS.
    Ответ написан
    4 комментария
  • Как правильно задать запрос UPDATE где название столбца переменная?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Этот вопрос - прекрасная иллюстрация того факта, что нормализация базы данных - это не блажь оторванных от жизни теоретиков, а насущная необходимость. И её отсутствие приводит к проблемам на ровном месте.

    Уже по наличию нумерованных столбцов сразу видно, что структура БД кривая. А текущая проблема делает это еще более наглядным: собственно, сама постановка вопроса, "как задать имя столбца через переменную", говорит о том, что имя колонки используется в условии. То есть оно должно быть значением в строке.

    Здесь нужна связанная таблица, один ко многим, и она сразу снимет все проблемы, а запросы станут мягкими и шелковистыми:

    UPDATE link_count SET count=count+? WHERE link_id=? and number=?
    Ответ написан
    3 комментария
  • Как решить ошибку отправки почты, с использованием PHPMailer?

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

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Надо прочитать сообщение об ошибке.
    В нем говорится, что код на 71 строке в файле vendor\smi2\phpclickhouse\src\Client.php не видит элемент массива $config c ключом 'username'.

    После этого надо убедиться, что в передаваемом в класс Cilent массиве присутствует элемент с ключом username и этот ключ написан правильно, без опечаток.
    Ответ написан
  • Возникает ошибка "Заполните все поля". Все заполнено. Что не так с кодом?

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

    Например.
    Обычно эту бессмысленную фразу выводят примерно таким говнокодом:
    if (empty($_POST['pole1']) || empty($_POST['pole2']) || empty($_POST['pole3'])) {
        die("Заполните все поля");
    }

    Для того, чтобы разобраться с этой неразрешимой проблемой, вам понадобится немного логики.
    Я уверен, вам вполне по силам сделать умозаключение вида, "Если этот код выводит ошибку, то как минимум одно из полей содержит пустое значение".
    Сделав такой логический вывод, его следует проверить.
    Например таким кодом:
    var_dump($_POST['pole1'],$_POST['pole2'],$_POST['pole3']):

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

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

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

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

    Во-первых, при создании соединения с БД, надо сказать ПДО, чтобы он сообщал об ошибках.
    $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    Во-вторых, временно, на период разработки, включить отображение ошибок РНР. Чтобы тупо увидеть, если произошла какая-то ошибка.
    ini_set('display_errors', 1);

    И в-третьих, начать собственно отладку.
    Для начала убедившись, что РНР код в принципе запускается, и проблема в нем, а не в форме.
    Для этого в самом начале action.php пишем большими буквами
    die("пхп хотя бы запустился");
    И если после нажатия на кнопку мы этот текст не увидели, то начинаем тупить в свою форму - а с чего она вообще должна что-то посылать в файл action.php (и попутно задаваться вопросом - а какое отношение наш вопрос имеет к php и sql?)?
    Если форма отправляется аяксом, то смотрим ответ пхп в инструментах разработчика, вкладка Сеть.

    Если обработку формы мы начали, то заезжаем внутрь условия
    die("начали обработку формы");

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

    А в целом, конечно, код очень жестокий.
    Вот прямо хочется спросить -
    зачем здесь функция test_input?
    зачем здесь try {}catch (){echo 'Error : '.$e-getMessage();}?
    зачем class Auth extends Database?
    почему showMessage - это часть класса Database? Ну вот серьёзно, каким местом вывод сообщения в браузер в виде HTML хоть как-то относится к работе с базой данных?

    Чтобы сделать этот код минимально осмысленным, надо
    выкинуть класс Database
    в класс Auth добавить
    public function __construct($pdo){
                $this->conn = $pdo;
        }

    и выкинуть из него require_once 'config.php';

    В config.php оставить только соединение с PDO
    в action написать
    require 'config.php';
    $user = new Auth($pdo);

    и выкинуть условие при регистрации, оставив только
    $user->register($name,$email,$hpass);
    $_SESSION['user'] = $email;

    И тогда этот код станет минимально осмысленным
    Ответ написан
    Комментировать
  • Как исправить не правильное форматирование css который вставляет php?

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

    некоторые файлы он вставляет с форматированием , а другие нет.


    РНР не вставляет никакие файлы. Из РНР вы получаете ссылку. Её читает браузер. Который дальше и читает файл, и "вставляет" код, и форматирует его.
    При чем то, что браузер показывает в инструментах разработчика, может не иметь вообще ничего общего с тем, что на самом деле лежит в файле. Если хотите посмотреть реальное "форматирование", то надо смотреть сам файл, а не то что браузер рисует в инспекторе
    Ответ написан
    4 комментария
  • Как получить данные из строки mysqli?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Чтобы получить одну строку из результата запроса, в mysqli есть функции
    • fetch_assoc(): возвращает всю строку в ассоциативный массив
    • fetch_row(): возвращает нумерованный массив (список)
    • fetch_obj(): возвращает объект класса stdClass
    • fetch_column(): возвращает значение из первой колонки запрошенной строки

    В общем случае случае осмысленный код для получения значения единственной колонки будет таким
    $sql = "SELECT link FROM tablet where id=?";
    $result = $conn->execute_query($sql, [$a]); 
    $link = $result->fetch_column();

    Но как правильно замечено в комментариях, правильнее будет рандомизировать сразу в запросе, причем все делать одним запросом, а не тремя
    function Axelmo($conn) {
        $sql2 = "SELECT link FROM tablet ORDER BY rand() LIMIT 1";
        return $conn->query($sql)->fetch_column();
    }

    Ну и чисто для иллюстрации, как сделать запрос с ограничением по id
    function Axelmo($min, $max, $conn) {
        $sql2 = "SELECT link FROM tablet where id >= ? AND id <= ? ORDER BY rand() LIMIT 1";
        return $conn->execute_query($sql, [$min, $max])->fetch_column();
    }
    Ответ написан
    1 комментарий
  • Как записать массив PHP в базу данных MySQL?

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

    Если же говорить про проблему медленной записи, то она происходит из того факта, что mysql по умолчанию убеждается в успешности записи каждой строки, перед тем как записывать следующую. Отсюда будут и варианты её решения

    Вариант 1, при котором никакой код менять не надо. Отключаем эти проверки устанавливая переменную mysql innodb_flush_log_at_trx_commit=0. Для этого надо обладать правами рута.
    Вариант 2: заключить все вставки в транзакцию
    Вариант 3: добавлять все записи одним запросом. Это можно сделать либо кодом Slava Rozhnev, либо запросом LOAD DATA INFILE

    Да, и между вашими вариантами 2 и три нет никакой разницы. Это один и тот же вариант, про который в любом случае надо забыть: он вообще никогда не должен применяться. Переменные должны попадать в запрос только через плейсхолдеры.
    Ответ написан
    2 комментария