Я полностью смущен mySQLi. Хотя я использую процедурные вызовы mysql в течение многих лет, я хочу привыкнуть к подготовке подготовленных инструкций для защиты от db security / mySQL, которую он предлагает. Я пытаюсь написать простой оператор select (да, я знаю, что процедура процедурного вызова для этого предлагает повышение производительности). Когда я запускаю, я получаю все эхо-сигналы, пока не нажму $result = $stmt->get_result();
компонент. Мне все это кажется довольно простым, но я теряю время после чтения инструкций по mySQLi. Любые идеи, почему это будет неудачно?
* note: это тестовая среда, и пока не происходит дезинфекция / экранирование символов, я передаю только действительный контент в переменные $ username и $ email. Кроме того, я все посмотрел, чтобы найти решение моей проблемы.
function checkUsernameEmailAvailability($username, $email) { //Instantiate mysqli connection @$mysqli = new mysqli(C_HOST,C_USER,C_PASS,C_BASE) or die("Failed to connect to MySQL database..."); if (!$mysqli) { echo 'Error: Could not connect to database. Please try again later...'; exit; } else { echo 'mysqli created'; } /* Create a prepared statement */ if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) { echo '<br />MYSQLi: '; /* Bind parameters s - string, b - boolean, i - int, etc */ $stmt -> bind_param("ss", $username, $email); echo '<br />paramsBound...'; /* Execute it */ $stmt -> execute(); echo '<br />Executed'; $result = $stmt->get_result(); echo '<br />Result acquired'; /* now you can fetch the results into an array - NICE */ $myrow = $result->fetch_assoc(); echo '<br />Fetched'; /* Close statement */ /$stmt -> close(); echo '<br />Done mysqli'; } }
Кроме того, мне нужно создавать экземпляр mysqli каждый раз, когда я вызываю функцию? Я предполагаю, что они не являются постоянными db-соединениями, как в процедурной mysql. Да, я знаю, что это проблема с областью видимости, и нет, я не смог понять область этой переменной класса. Когда я объявлял его вне функции, он не был доступен, когда я вошел в функцию.
ОБНОВЛЕНИЕ, если я изменю строку 12:
if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
чтобы:
$stmt = $mysqli->stmt_init(); if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) { if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
Я не делаю заявление НЕ подготовленным. Теперь я еще более смущен ….
ОБНОВЛЕНИЕ. Я связался с моим хостинг-провайдером и, по-видимому, поддерживает mySQLi, и присутствует драйвер mysqlnd. Возможно, есть способ просто проверить это? Хотя в прошлом они обычно давали мне довольно хорошо осведомленные ответы.
UPDATE … СНОВА: Я сам проверил возможности своего сервера и обнаружил, в то время как mysqli и PDO присутствуют, mysqlnd – нет. Таким образом, я понимаю, почему get_result () не будет работать (mysqlnd требуется, я думаю), я до сих пор не понимаю, почему сам подготовленный оператор не будет работать.
Через некоторую проверку, даже если mysqli установлен на моем хосте, видимо, драйвер mysqlnd отсутствует. Поэтому get_result () не может быть использован (php manual определяет get_result как зависимый от mysqlnd), и вместо этого потребуется дополнительное кодирование, чтобы обработать мой результат так, как хотелось бы.
Поэтому я решил попробовать и узнать, как работает PDO, и в течение нескольких минут, вуаля !!!
Замените приведенный выше код следующим:
function checkUsernameEmailAvailability($username, $email) { echo 'pdo about to be created'; $dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST; $user = C_USER; $password = C_PASS; try { $dbh = new PDO($dsn, $user, $password); } catch (PDOException $e) { echo 'Connection failed: ' . $e->getMessage(); } $params = array(':username' => $username, ':email' => $email); try{ $sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email '); } catch(PDOException $e) { echo 'Prepare failed: ' . $e->getMessage(); } try{ $sth->execute($params); } catch(PDOException $e) { echo 'Execute failed: ' . $e->getMessage(); } $result = $sth->fetch(PDO::FETCH_ASSOC); print_r($result); }
Столь же большая ошибка, как я мог придумать, и никаких проблем вообще не трескаться!
Окончательный код
function checkUsernameEmailAvailability($username, $email) { $dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST; $user = C_USER; $password = C_PASS; new PDO($dsn, $user, $password); $params = array(':username' => $username, ':email' => $email); $sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email '); $sth->execute($params); $result = $sth->fetch(PDO::FETCH_ASSOC); print_r($result); }
Какая у вас версия php? Вы должны проверить это:
Что случилось с mysqli :: get_result?
Похоже, что это тоже немного.
mysqli_stmt :: get_result доступен только с пакетом mysqlnd . удалите пакет php5-mysql и установите вместо него php5-mysqlnd