@PetrovAnto

Почему не получается записать в базу данных?

Подскажите, почему происходит ошибка?

Notice: Undefined variable: link in /index.php on line 89
Warning: mysqli_query() expects parameter 1 to be mysqli, null given in /index.php on line 89

$host = 'localhost';
$user = '12';
$pass = '123';
$db_name = '1234';
$link = mysqli_connect($host, $user, $pass, $db_name); 

$query    = "INSERT INTO cat (image) VALUES ('$image_name')";
$result   = mysqli_query($link, $query); //#89
  • Вопрос задан
  • 508 просмотров
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
База данных всегда сама подробно расскажет, почему у неё не получилось выполнить запрос. Надо её только об этом попросить.

Поэтому сначала учимся правильно соединяться.
Весь этот детский лепет "не могу соединиться с БД" выкидываем и пишем нормальный код, который сам, без всяких проверок, сообщит нам об ошибках.
В случае mysqli это
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect($host, $user, $pass, $db_name);
$link->set_charset("utf8mb4");

Здесь первая строчка отвечает как раз за информирование об ошибках

Кроме того надо не забыть про ошибки РНР
Во-первых, всегда в коде должно быть error_reporting(E_ALL);
Плюс на домашнем компе ini_set('display_errors',1);, а на боевом - ini_set('display_errors',0);ini_set('log_errors',1);, и смотреть, соответственно, в логах.

После этого переписываем запрос. Причем так, чтобы данные в БД всегда попадали отдельно от самого запроса. Это непреложное правило, которое надо соблюдать всегда.
Для этого надо
  • Заменить все переменные в запросе на специальные маркеры, которые называются плейсхолдеры или параметры, а по сути - просто знаки вопроса
  • Подготовить запрос к исполнению с помощью функции prepare(). Эта функция принимает строку запроса и возвращает экземпляр специального класса stmt, с которым в дальнейшем и производятся все манипуляции
  • Привязать переменные к запросу.
  • Выполнить подготовленный ранее запрос с помощью с помощью execute()

В mysqli это будет так
$sql = "INSERT INTO `events` (`title`, `discription`, `date`, `img`) VALUES (?,?,?,?)";
$stmt = $link->prepare($sql);
$stmt->bind_param("sssss", $title, $discription, $date, $path);
$stmt->execute();

bind_param() принимает в качестве параметров все переменные, которые должны попасть в запрос, в том же самом порядке, в котором стоят плейсхолдеры в запросе. Но кроме того, сначала в этой функции должны быть указаны типы для всех переменных, в виде строки, где тип переменной обозначается одной буквой. То есть букв в этой строке должно быть ровно столько, сколько дальше будет переменных. К счастью, можно особо не париться с типами и для всех переменных указывать тип "s".

И тогда никаких ошибок запроса уже никогда не будет. Не говоря уже о том что при любых других вариантах твой сайт поломает любой пятиклассник

Но по-хорошему для работы с БД в РНР лучше использовать PDO, Тем более что там колупаться с bind_param не нужно, а можно сразу отправить все данные в execute

Подключение
$host = '127.0.0.1';
$db   = 'test';
$user = 'root';
$pass = '';
$port = "3306";
$charset = 'utf8mb4';
$options = [
    \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
    \PDO::ATTR_EMULATE_PREPARES   => false,
];
$dsn = "mysql:host=$host;dbname=$db;charset=$charset;port=$port";
$pdo = new \PDO($dsn, $user, $pass, $options);

Здесь за информирование об ошибках отвечает параметр PDO::ERRMODE_EXCEPTION, а остальные просто для удобства/корректности.

Выполнение запроса
$sql = "INSERT INTO `events` (`title`, `discription`, `date`, `img`) VALUES (?,?,?,?)";
$stmt = $link->prepare($sql);
$stmt->execute([$title, $discription, $date, $path]);
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
vilinyh
@vilinyh
Потому что подключение к базе данных не удалось.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Лучше создать класс базы данных и потом его использовать.
Инициализацию и запросы - решение FanatPHP.

Это и проще, и быстрее, и надёжнее, и правильнее.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы