правильный способ написания подготовленного оператора MySQLi в функции? - PullRequest
5 голосов
/ 27 декабря 2011

Подготовленные операторы

Хорошо, я только начал смотреть на подготовленные операторы MySQLi.Это был большой шаг для меня, так как я в любом случае очень плохо знаком с MySQL и PHP, поэтому у меня очень слабое понимание концепции (возможно, около часа), поэтому ваши ответы должны быть сформулированы аналогично, извините за это,

Я хочу знать, правильно ли я пишу подготовленное заявление.Нет ничего хуже, чем изучить неправильный метод и привыкнуть к нему, поэтому неэффективно кодировать целые проекты.

Кстати, у меня есть функция, которая регистрирует пользователя, а затем возвращает вставленный идентификатор, который, следовательно, является ссылочным идентификатором пользователя.

Раньше я просто запрашивал базу данных.Мне сказали, что у нее были угрозы безопасности, несмотря на использование mysql_real_escape_string() и аналогичных мер безопасности.

Теперь это выглядит примерно так: (предположим, ради этого вопроса, что все ссылочные переменные определены, связанные параметры являются строками, а все вызываемые функции существуют и работают).

function registerUser($username, $fname, $email, $password, $region, $activation) {
    $uniqueSalt = uniqueSalt();
    $password = sha1($uniqueSalt . $password);

    $mysqli = mysqli_connect('localhost', 'root', '', 'database');

    if ($stmt = $mysqli->prepare("INSERT INTO `users` VALUES('', ?, ?, ?, ?, '$password', '$uniqueSalt', '$activation')") ) {
        $stmt->bind_param("ssss", $username, $fname, $email, $region);
        $stmt->execute();
        $stmt->close();
    } else {
        echo 'error preparing statement';
    }

    return mysqli_insert_id($mysqli);
}

Вопросы

Кажется, что это работает, но:

1) Это правильный синтаксис для выполнения подготовленного оператора?

2) Я включил файл, в котором находилась эта функция (назовите его function.php), в другой файл с именем init.php, который ранее определил переменную $mysqli.Я обнаружил, что если бы я не включил

$mysqli = mysqli_connect('localhost', 'root', '', 'database');

, я получил бы ошибку.Почему я должен был переопределить его внутри функции?

3) Когда я ранее заканчивал функцию, прежде чем использовал предварительно подготовленные операторы, с return mysql_insert_id(), который работал нормально, теперь я обнаружил, что должен использовать mysqli_insert_id($mysqli).

Если я не включу $mysqli в скобки, я получу ошибку mysqli_insert_id() expects exactly 1 parameter, 0 given.Почему это так и почему оно отличается от того, что у меня было раньше?

Приветствия, Люк.

Ответы [ 2 ]

2 голосов
/ 27 декабря 2011
  1. Ваше использование не имеет большого смысла. Из PHP Manual Пример :

    $stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
    $stmt->bind_param('sssd', $code, $language, $official, $percent);
    

    Сравните это с вашим использованием:

    $stmt = $mysqli->prepare("INSERT INTO `users` VALUES('', ?, ?, ?, ?, '$password', '$uniqueSalt', '$activation')");
    $stmt->bind_param("ssss", $username, $fname, $email, $region);
    

    Заметили что-нибудь странное? В примере вручную используется ? в качестве заполнителя, где вы затем используете ->bind_param() для создания набора замещения. Итак, ваш пример, я считаю, должен быть:

    $stmt = $mysqli->prepare("INSERT INTO `users` VALUES('', ?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param("sssssss", $username, $fname, $email, $region, $password, $uniqueSalt, $activation);
    

    Не зная, является ли $activation числовым или строковым значением. (Также я бы предложил использовать имена столбцов и не опускать их в запросе INSERT.)

    Теперь то, что вы сделали, должно работать во многих случаях просто потому, что вы создаете один оператор использования и используете расширение переменной для вставки $pass, $uniqueSalt, $activation в готовящуюся строку запроса. Случаи, когда этого не произойдет, если у вас случайно есть ' в одной или нескольких переменных, которые вы вводите в запрос, которые должны быть либо параметризованы (с использованием ->bind_param()), либо с использованием mysqli_real_escape_string(). Однако смешивание этих подходов является плохой практикой и отрицательно сказывается на цели использования подготовленных утверждений. Нет причин делать первые несколько, но не последние несколько.

  2. Ваша $mysqli переменная "выходит за рамки" , когда вы вызываете ее в функции, если она определена глобально, следовательно, когда она недоступна, вы не сможете использовать ее, пока не импортируете ее или создайте еще один локально (в функции). Вы можете импортировать его, используя синтаксис global $mysqli; внутри функции (при условии, что он создан глобально, а не локально в другой функции).

  3. Это та же проблема, что и # 2. Смотри: http://php.net/manual/en/mysqli.insert-id.php

Я рекомендую использовать PDO вместо функций mysql_ / mysqli_.

0 голосов
/ 27 декабря 2011

1) Это правильный синтаксис для выполнения подготовленного оператора?

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

2) Я ...

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

3) Когда я ранее завершал функцию до того, как использовал предварительно подготовленные операторы, с возвращением mysql_insert_id (), который работал нормально, теперь я обнаружил, что должен использовать mysqli_insert_id ($ mysqli) ...,

Функция mysql_insert_id отличается от функции mysqli_insert_id. Только одна и та же функция работает точно так же, поэтому нет ничего особенного в том, что обе функции разные, потому что это разные функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...