#php #mysqli
#php #mysqli
Вопрос:
В моем проекте есть основной файл, который содержит все функции PHP, которые я использую. Все это написано на PHP5. Недавно я решил изучить и перейти на PHP7.
Итак, это мое основное содержимое файла (упрощенное):
<?php
$db_host='localhost';
$db_user='root';
$db_pass='';
$db_name='migration';
$link = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
if (mysqli_connect_errno()) {
echo mysqli_connect_error();
exit();
}else{
mysqli_query($link, "SET NAMES utf8");
mysqli_query($link, "SET CHARACTER SET utf8" );
}
function dbquery($query) {
$result = mysqli_query($link, $query);
if (!$result) {
echo mysqli_error($link);
return false;
} else {
return $result;
}
}
function dbarray($query) {
$result = mysqli_fetch_assoc($query);
if (!$result) {
echo mysqli_error($link);
return false;
} else {
return $result;
}
}
// Fetch the Site Settings from the database and store them in the $settings variable
$settings = dbarray(dbquery("SELECT * FROM site_settings"));
?>
Теперь дело в том, что при запуске файла я получаю следующие ошибки:
Warning: mysqli_query() expects parameter 1 to be mysqli, null given
Warning: mysqli_error() expects parameter 1 to be mysqli, null given
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, bool given
Warning: mysqli_error() expects parameter 1 to be mysqli, null given
Итак, что я здесь делаю не так?
ДОБАВЛЕНИЕ
Когда я запускал этот файл, у меня была mysqli_connect
отдельная функция. Таким образом, соединение на самом деле выглядело так:
$link = dbconnect($db_host, $db_user, $db_pass, $db_name);
function dbconnect($db_host, $db_user, $db_pass, $db_name) {
$db_connect = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
if (mysqli_connect_errno()) {
echo mysqli_connect_error();
exit();
}
mysqli_query($db_connect, "SET NAMES utf8");
mysqli_query($db_connect, "SET CHARACTER SET utf8" );
}
Но, похоже, это mysqli_connect
тоже не работает внутри функции.
Позже я изменил коды, чтобы они выглядели так, как я там написал.
Я действительно ценю некоторую помощь здесь.
Редактировать
Я также пытался создать $link
глобальную переменную. Но это не помогло.
Комментарии:
1. Обязательно ли использовать mysqli? Почему вы не можете переключиться на PDO?
2. @Dharman Я всегда использовал структуру PHP5, и я не профессиональный программист. Поэтому, когда я решил перейти на PHP7, я подумал
mysqli
, что будет проще реализовать и использовать. Я понятия не имею, как работает PDO.3. Я рекомендую изучить PDO. Он доступен с PHP 5, и он намного проще в использовании и предлагает больше функциональности. Начните изучать это здесь phpdelusions.net/pdo
4. @Dharman Большое спасибо. Я обязательно посмотрю на PDO и попытаюсь его изучить. Но только для моей собственной информации, не могли бы вы сказать мне, что было не так с кодом, с которым я пытался
mysqli
? Я прочитал несколько базовых руководств, и все было написано на основе этих руководств. Я просто помещаю их в свои собственные функции.
Ответ №1:
Если вы должны использовать mysqli, то неплохо иметь функции-оболочки. Однако то, что у вас есть на данный момент, бесполезно. Ваши функции не связаны между собой, вы не используете параметризованные подготовленные операторы и не включили исключения mysqli.
Ошибка, которую вы получаете, заключается в том, что вы не определили переменную в области, в которой вы находитесь. Каждый раз, когда вам требуется переменная внутри метода / функции, вы должны передавать ее в качестве аргумента функции.
Я бы рекомендовал вместо этого создать класс. Этот класс должен иметь хотя бы одну вспомогательную функцию, которая позволит вам быстро выполнить подготовленную инструкцию.
class DBClass extends mysqli {
public function __construct($host = null, $username = null, $passwd = null, $dbname = null, $port = null, $socket = null) {
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
parent::__construct($host, $username, $passwd, $dbname, $port, $socket);
$this->set_charset('utf8mb4');
}
/**
* Executed prepared statement
*
* @param string $sql SQL query with placeholders e.g. SELECT * FROM users WHERE Id=?
* @param array $params An array of parameters to be bound
* @return array|null
*/
public function safeQuery(string $sql, array $params = []): ?array {
// prepare/bind/execute
$stmt = $this->prepare($sql);
if ($params) {
$stmt->bind_param(str_repeat("s", count($params)), ...$params);
}
$stmt->execute();
// If the query produces results then fetch them into multidimensional array
if ($result = $stmt->get_result()) {
return $result->fetch_all(MYSQLI_BOTH);
}
// return nothing if the query was successfully executed and it didn't produce results
return null;
}
/**
* Executed prepared statement but fetch a single row only
*
* @param string $sql SQL query with placeholders e.g. SELECT * FROM users WHERE Id=?
* @param array $params An array of parameters to be bound
* @return array|null
*/
public function row(string $sql, array $params = []): ?array {
// prepare/bind/execute
$stmt = $this->prepare($sql);
if ($params) {
$stmt->bind_param(str_repeat("s", count($params)), ...$params);
}
$stmt->execute();
// If the query produces results then fetch them into an array
if ($result = $stmt->get_result()) {
// here we use fetch_assoc to get a single associative array
return $result->fetch_assoc();
}
// return nothing if the query was successfully executed and it didn't produce results
return null;
}
}
Это всего лишь демонстрация, но вы могли бы следовать тому же дизайну. Тем не менее, я бы рекомендовал использовать существующее решение вместо того, чтобы изобретать велосипед. Я рекомендую EasyDB, который является довольно хорошим уровнем абстракции БД.