Задать вопрос
Ответы пользователя по тегу PHP
  • Как сформировать AJAX запрос для базы данных?

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

    Сначала надо добавить одну запись в БД руками.
    Потом так же в БД учиться писать запрос SELECT
    потом учиться выполнять SQL запросы в РНР.
    потом учиться получать результат SQL запроса в массив.
    потом учиться выводить многомерный массив
    потом учиться выводить многомерный массив в виде требуемого HTML, чтобы получить свою таблицу
    после этого можно сесть и отдохнуть.

    И после хорошего отдыха начать учиться работать с формами в HTML
    и как их обрабатывать в РНР
    написав в итоге код для добавления данных формы в БД

    и только после этого, если силы останутся, навешивать рюшечки в виде запроса и обновления аяксом
    Ответ написан
  • Как перенаправлять пользователя, если возникла ошибка 500?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Насколько я знаю, у РНР есть какие-то проблемы во взаимодействии с апачем.
    Для 400-х ErrorDocument работает, а для 500-х почему-то нет.

    Но на самом деле это и не требуется. Все ошибки РНР прекрасно может обработать и сам.
    Тем более, что заголовок вопроса представляет собой оксюморон (не путать с известным говорителем слов под музыку).
    Перенаправлять при возникновении ошибки никуда нельзя: потому что это разные НТТР коды ответа. И хотя в тексте вопроса мы видим, что никакого перенаправления и не планировалось, но заголовок из песни не выкинешь.

    Поэтому куда проще (и удобнее) настроить обработчик ошибок в РНР, и для 99.99% ошибок он будет показывать нужный HTML сам.
    Для этого понадобятся функции set_exception_handler() и register_shutdown_function()
    примеров реализации море, например здесь: https://phpdelusions.net/articles/error_reporting#code
    Только error handler на самом деле не нужен, потому что не фатальные ошибки не вызывают 500-ю ошибку и могут просто логироваться автоматом, без всякого хендлера.
    Ответ написан
  • PHP header('Content-Disposition: inline - почему не работает?

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

    Собака зарыта в том, что Content-Disposition: inline не имеет смысла с filename=file.htm, Никакое имя в адресной строке этот заголовок не поменяет и никогда не делал ничего даже близко к этому.

    Изменить адрес во время обращения сервер уже не может. Можно или сообщить клиенту, чтобы он запросил другой адрес (что делает совсем другой заголовок - Location), но в этом случае скрипт ничего не может вывести, или клиент должен был сразу запрашивать file.htm, а сервер при этом будет выполнять script.php
    Ответ написан
  • Почему шифруются данные в БД mysql?

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

    1. ini_set('display_setup_errors', 1); надо убрать вообще, это бессмысленный карго-культ
    2. ini_set('error_reporting', E_ALL); и ini_set('display_errors', 1); надо вынести в общий файл, который инклюдится во все остальные. Иначе на бою придется редактировать в каждом файле, чтобы заменить 1 на 0.
    3. empty после trim надо убрать, проверять на существование заведомо существующее значение не имеет смысла. То есть, переписать так
      if(trim($_POST['user_name']) && trim($_POST['user_email']) && trim($_POST['user_password']))

      Но и это будет неправильно, поскольку trim не применяется к добавляемым в БД значениям
      То есть, потримать отдельно в переменные, а потом проверить просто
      if($user_name && $user_email && $user_password)

    4. проверка if(isset($_SESSION['user_data'])) явно не на месте. А если форма запрошена не постом? Показывать её уже авторизованному пользователю? Зачем?
    5. после header('Location: '); всегда должен идти exit. в данном случае не принципиально, но это должно делаться на автомате.
    6. _once из require_once надо убрать вообще, это бессмысленный карго-культ
    7. require('database/ChatUser.php'); - это стыдоба. Сделайте простенький автозагрузчик, это три строчки. Например
      spl_autoload_register(function ($className) {
          $ds = DIRECTORY_SEPARATOR;
          $className = str_replace('\\', $ds, $className);
          $filename = __DIR__ . "{$ds}..{$ds}database{$ds}$className.php";
          require($filename);
      });
      автозагрузчик тоже кладется в общий подключаемый файл.

    8. проверку if($user->saveData()) надо убрать вообще, это бессмысленный карго-культ, и - вдобавок - ошибка. Если POST запрос был обработан без ошибок, то после него всегда должен быть редирект, без всяких success_message. А "Something went wrong" выводится совсем другим кодом. Я ещё посмотрю в database, но если что, то исправлять надо будет там
    9. вывод сообщений об ошибках в хтмл части лучше сделать в едином стиле
      <? if($errors !== ''): ?>
          <?=htmlspecialchars($errors) ?><br><br>
      <? endif ?>

    10. хорошим тоном считается при ошибке выводить пользователю уже введенные значения (кроме пароля, разумеется)
      <input type="text" name="user_name" value="<?= htmlspecialchars($user_name ?? '') ?>">



    Так, в database более серьезные ошибки.
    В целом неплохой ActiveRecord, но в конструкторе прям всё очень плохо.
    1. В обязательном порядке переделать
      • Во-первых, require в коде класса - это сразу профнепригодность. Всю необходимую информацию класс должен получать только через методы.
      • Во-вторых, new DatabaseConnection в каждом конструкторе - это совсем детская ошибка. Давно TOO MANY CONNECTIONS от mysql не получали?

      Этот класс должен принимать уже созданное соединение, через параметр конструктора.

    2. createAvatar я бы вынес в отдельный класс
    3. Непонятно, зачем вам вообще понадобился цикл foreach ($params as $key => $value), если проще и удобнее написать $statement->execute($params); Для кого специально этот функционал создатели PDO писали?
    4. return $user_data; после условия - это логическая ошибка. Будет undefined variable $user_data если условие не выполнится. Но главное, что здесь все неправильно изначально. Никаких проверок быть в принципе быть не должно.


    DatabaseConnection

    Тут две основные ошибки, не буду уж нумеровать

    • Во-первых, данные для подключения к БД (как и другие, отличающиеся для разных окружений настройки) пишутся в отдельном файле, который не добавляется в систему контроля версий (пишется в .gitignore). И, соответственно, никаких констант, а обычные параметры конструктора. И в этом контексте становится непонятно, зачем вообще нужен класс DatabaseConnection, если все что он делает - это создает инстанс PDO? Правильно, он становится совершенно не нужен
    • Во-вторых, и самое главное - в PDO не включен режим информирования программиста об ошибках. Я даже не представляю, у какого инфоцыгана вы брали этот код - уже, вроде бы, даже до самых тупых из них дошло, что оставлять программиста без сообщений об ошибках - это садизм. Поэтому при создании инстанса ПДО надо в обязательном порядке включать режим информирования об ошибках. Для этого добавить еще один параметр в виде массива, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]; и пока оставить так. А потом, со временем, добавить к проекту централизованный вывод сообщения "что-то пошло не так"

    Ответ написан
    Комментировать
  • Как правильно организовать систему контроллеров в mvc паттерне?

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

    В данном случае notebooks_and_computers/notebooks - это просто SEO мусор, который вообще не нужен для отображения товара. Для которого нужен только айди товара. Ну вот и запускается контроллер витрины с экшеном отображения карточки товара.
    Ответ написан
    2 комментария
  • Как получить "хеш"/сравнить изображение?

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

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Это какой-то странный сайт, который зачем-то показывает данные в виде json, хотя в запросе он отсутствует.
    А весь массив целиком передается в полях запроса.
    То есть это будет $_POST['fields']['name']['value']
    Ответ написан
    2 комментария
  • Как лучше прикрепить файлы к записи в блоге?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Первый вариант отдает лаптями и портянками, а смысл второго варианта от меня ускользает.
    Я не вижу, какая проблема передать на сервер все "публичные ссылки" вместе со статьей, и записывать нормальным порядком после статьи.
    Ответ написан
  • Как мне сделать фильтрацию по категориям, из базы данных (mysql)?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Для начала надо выучить русский язык и узнать, что означает слово "сортировка"
    Потом надо выучить SQL, чтобы узнать, каким образом можно ограничить выборку по условию.
    Потом надо выучить HTML чтобы узнать, как можно передать выбор пользователя на сервер
    Потом надо выучить РНР чтобы узнать, как можно взять переданное из HTML значение и подставить его в SQL запрос, выполнить этот запрос, и вывести результат.
    Ответ написан
    Комментировать
  • Как сохранить старое значение для input type file?

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

    Причем в данном конкретном случае это еще и бессмысленно.
    Админу не нужна картинка, чтобы отредактировать пост. Она уже загружена, и заново ее загружать просто не имеет смысла.
    Ответ написан
    6 комментариев
  • Как исправить ошибку php Call to a member function bind_param() on boolean in?

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

    Да нет, дело не в умственных способностях. Просто всё поколение такое. Не умеет пользоваться интернетом. Только тикток смотреть в телефоне.

    Вот, я погуглил за вас: Не добавляются данные в таблицу

    Соответственно, после исправления ошибки надо будет ещё переписать кусок после bind_param, убрав бессмысленную проверку и оставив только
    $stmt->execute();
    return [
        'error' => false,
        'message' => 'Дело успешно добавлено'
    ];
    Ответ написан
  • Как работает поиск по таблице в PhpMyAdmin?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Непонятно, что именно здесь может быть непонятно
    PhpMyAdmin - тупейшая программа, которая на веб странице показывает результат запроса, с разбивкой на страницы.
    Если запрос вида SELECT * FROM table, то показывает все содержимое таблицы
    Если запрос вида SELECT * FROM table WHERE col=value, то показывает только те строки, в которых выполняется условие поиска.

    Если вопрос в том, как PhpMyAdmin запоминает условие поиска между страницами - точно так же, как запоминает всё остальное, включая авторизованного пользователя - в сессии.
    Ответ написан
  • Ошибка 500 php?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Если это локальный сервер то добавить строчку
    php_ini("display_errors", "on");
    Если боевой, то смотреть ошибку в логах
    Ответ написан
    Комментировать
  • Занесение данных из формы в базу данных?

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

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $conn = new mysqli("зачем", "вам", "это", "знать?");
    
    $name = $_POST["name"];
    $login = $_POST["login"];
    $pass = $_POST["password"];
    
    $sql = "INSERT INTO admins (login, pass, name) VALUES (?,?,?)";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("sss", $login, $pass, $name);
    $stmt->execute();
    
    $id = $conn->insert_id;
    header("Location: profile.php?id=$id");


    Пара замечаний
    • отдельная таблица админов обычно не делается, достаточно общей таблицы пользователей
    • id вставлять не надо, его должна генерировать БД
    • после успешной обработки прямого POST запроса обязательно должен быть редирект. Обычно это либо созданная учетка, или страница входа или список пользователей или что-то ещё
    • при обработке прямого запроса никаких echo в коде быть не должно
    Ответ написан
  • Можно ли как-то использовать абсолютный путь до папки/файла в php?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Не только можно, но и нужно.
    Всегда надо использовать только абсолютные пути.
    Ответ написан
    Комментировать
  • Как сделать поиск данных из mysql которые сохраненны в формате unicode?

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

    Но для этого надо сначала научиться пользоваться базой данных, потом разработать нормальную структуру, и хранить данные как положено - каждое поле отдельно, а не всё одной в помойной куче.
    Ответ написан
  • В чем может быть проблема при подключении к API через PHP?

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

    Для отладки полезно вывести содержимое специальной переменной, которая содержит заголовки ответа, var_dump($http_response_header);

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

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    $data = json_decode(file_get_contents('php://input'), TRUE);

    Вот тут в $data у вас не только сообщение, но и много другой информации. В частности, айди юзера.
    я думаю, что этот айди можно использовать в качестве идентификатора сессии, передавая в session_id() перед вызовом session_start()
    Во всяком случае можно попробовать
    если сессия не взлетит, то эмулировать её на любом другом хранилище, используя идентификатор юзера чтобы сохранять состояние бота для него

    Попробовал, сессия через юзер айди не работает потому что идентификатор телеграма не подходит под стандарт идентификатора сессии.
    Если эмулировать (просто добив до нужной длины) то сессия начинает работать.
    Ответ написан
    Комментировать
  • Как записать данные в переменную PHP и вызывать их в любом участке кода?

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

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

    в одном из блоков if записываю данные в переменную. Проблема в том, что когда я пытаюсь вызвать его в другом блоке elseif - она выводиться пустая


    А вот этот вопрос говорит о том, что вы, видимо, даже не понимаете, как работают конструкции if и else. Что сам принцип этих конструкций состоит в том, что если выполнилась одна ветка, то по определению другие выполняться не будут.

    Поскольку вы не удосужились написать, какая именно переменная вызывает проблему, я предполагаю, что речь о $channelUsername. Учитывая, что она передается по ссылке, то дело не в том, что она "перезаписывается". А в том, что её попросту неоткуда взять, если в $message лежит число
    Ответ написан
    Комментировать
  • Почему форма заявки не работает?

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

    Но в данном случае надо прочитать, что вам пишут, и дальше гуглить Не работает POST запрос 405 Not Allowed

    Скорее всего, попросту не установлен РНР.
    Ответ написан
    Комментировать