Проблема с переносом функций PHP5 на PHP7

#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, который является довольно хорошим уровнем абстракции БД.