Prepared statement

Serhiy

Новичок
Как использовать, создавать Prepared statement?
например у меня есть код:
$query = Database::query("SELECT `mail` FROM `userdata` WHERE `username`='$log_d' AND `password`='$p_md5'");
$base = $query->fetch_object();

if ($mail_d == $base->mail && !empty($_POST['login']) && !empty($_POST['password']) && !empty($_POST['mail']))
{...}
Как это сделать через Prepared statement? :rolleyes:
 

Serhiy

Новичок
Например так http://www.phpfaq.ru/safemysql (Примеры: http://www.phpfaq.ru/examples#basic )
или, на худой конец, так: http://www.phpfaq.ru/pdo
А точнее можно на моем примере? у меня например ниженаписанный код выдает ошибку:

$p = $mysqli->prepare("SELECT `mail` FROM `userdata` WHERE `username`= ? AND `password`= ?");
$p->bind_param('ss', $log_d, $p_md5);
$p->execute();
$stmt->bind_result($mail);
while ($stmt->fetch()) {
echo $mail;
}

ошибка:
Notice: Undefined variable: mysqli in.....
Fatal error: Call to a member function prepare() on a non-object in.....
 

Serhiy

Новичок
прочти уже текст по ссылкам.
Читал инструкции.... но так и не разобрался как решить проблему...
Пробывал так

$query = $pdo->prepare("SELECT `mail` FROM `userdata` WHERE `username`='?' AND `password`='?'");
$query->execute(array($log_d, $p_md5));
$base = $query->fetch_object();

Не работает...

Notice: Undefined variable: pdo
Fatal error: Call to a member function prepare()
 

peon

Lok'tar ogar
Читал инструкции.... но так и не разобрался как решить проблему...
Пробывал так

$query = $pdo->prepare("SELECT `mail` FROM `userdata` WHERE `username`='?' AND `password`='?'");
$query->execute(array($log_d, $p_md5));
$base = $query->fetch_object();

Не работает...

Notice: Undefined variable: pdo
Fatal error: Call to a member function prepare()
Serhiy, у тебя код в функцию завернут? объект pdo создан?
 

Serhiy

Новичок
Не получается у меня разобраться....
Расскажу подробней что и как...
Есть класс Database, в нем Singleton pattern подключения к Mysql:

PHP:
require_once 'Db_log.php';
class Database //Klass fцr koppling till databas
{
    private static $instance;
    private $MySQLi;
     
    private function __construct(array $dbOptions)  // Konstruktцr av klass
    {
        // Koppling till MySQL server
        $this->MySQLi = @ new mysqli($dbOptions['db_host'],
                                    $dbOptions['db_user'],
                                    $dbOptions['db_pass'],
                                    $dbOptions['db_name']
                                    );
       
        if(mysqli_connect_errno())// Undantag om ska vara problem under koppling till databas
        {
            throw new Exception('Problem med koppling till Databas');
        }
             
        $this->MySQLi->set_charset("utf8"); // Typ av kodning
    }
    public static function getInstance(array $dbOptions) // Metod fцr ofarlig koppling
    {
        if(self::$instance instanceof self)
        {
            return false;
        }
       
        self::$instance = new self($dbOptions);
    }
    public static function getMySQLiObject()
    {
        return self::$instance->MySQLi;
    }
         
    public static function query($q) // Frеga till databas
    {
        return self::$instance->MySQLi->query($q);
    }
    public static function esc($str) // Skydd mot SQL Injection
    {
        return self::$instance->MySQLi->real_escape_string(htmlspecialchars($str));
    }
}
   
Database::getInstance($dbOptions); // Koppling
Другой класс выполняет операции с Mysql

PHP:
class User 
{
    public function readUser()
    {
    .........
   
    $query = Database::query("SELECT `mail` FROM `userdata` WHERE `username`='$log_d' AND `password`='$p_md5'");
    $base = $query->fetch_object();
.....
}
Как из этого всего, чтобы был singleton pattern сделать чтобы было с prepared statement?
Если можете подскажите, но не кидайте ссылки... начитался но так и не разобрался...
 

peon

Lok'tar ogar
PHP:
public static function query($q, $log_d, $p_md5) {
  $stmt = self::$instance->MySQLi-> prepare($q);
  $stmt -> bind_param("ss", $log_d, $p_md5);
  $stmt -> execute();
  return $stmt;
}
$query = Database::query("SELECT `mail` FROM `userdata` WHERE `username`=? AND `password`=?", $log_d, $p_md5);
$query-> bind_result($mail);
$query-> fetch();
echo $mail;
 

hell0w0rd

Продвинутый новичок
Ошибку вообще кто-то прочитал?
Notice: Undefined variable: mysqli in.....
Fatal error: Call to a member function prepare() on a non-object in.....
У человека дергается метод у необъекта
 

Вурдалак

Продвинутый новичок
дык ему дальше Фанат даёт ссылку на PDO и в итоге:
Код:
Не работает...

Notice: Undefined variable: pdo
Fatal error: Call to a member function prepare()
И тут же:
Код:
Как из этого всего, чтобы был singleton pattern сделать чтобы было с prepared statement?
Это клиника. Или троллинг.
 
Последнее редактирование:

Serhiy

Новичок
дык ему дальше Фанат даёт ссылку на PDO и в итоге:
Код:
Не работает...

Notice: Undefined variable: pdo
Fatal error: Call to a member function prepare()
И тут же:
Код:
Как из этого всего, чтобы был singleton pattern сделать чтобы было с prepared statement?
Это клиника. Или троллинг.
Просто у меня в голове уже каша после прочтения всех материалов и я полностью запутался....

Прочитал материалы еще раз, многое понял по новому. Многое понял, что раньше не понимал. Начал заново писать. Получилось так:

Код:
class Database
{
    public    $pdo;
    static private $instance;
    public $dbOptions;
   
    public static function getInstance() 
    {        
        if(empty(self::$instance))  
            self::$instance = new self;
       
        return self::$instance;
    }    

    private function __construct()
    {
   
    $dbOptions = array(
          'db_host' => 'localhost', 
          'db_user' => 'user', 
          'db_pass' => 'password', 
          'db_name' => 'database'  
        );
   
       $pdo = new PDO("mysql:host=". $dbOptions['db_host'] .";dbname=". $dbOptions['db_name'], $dbOptions['db_user'], $dbOptions['db_pass']);
    }
   
           
    private function __clone(){}
}

$obj = Database::getInstance();



$stmt = $obj->pdo->prepare("SELECT `mail` FROM `userdata` WHERE `username`= ? AND `password`= ?");
$p->bind_param('ss', $log_d, $p_md5);
$p->execute();
$stmt->bind_result($mail);
while ($stmt->fetch()) {
echo $mail;
}
Выдает ошибку Fatal error: Call to a member function prepare() on a non-object

Что опять не так? Что я опять недопонял?
 

peon

Lok'tar ogar
Просто у меня в голове уже каша после прочтения всех материалов и я полностью запутался....

Прочитал материалы еще раз, многое понял по новому. Многое понял, что раньше не понимал. Начал заново писать. Получилось так:

Код:
class Database
{
    public    $pdo;
    static private $instance;
    public $dbOptions;

    public static function getInstance()
    {     
        if(empty(self::$instance))
            self::$instance = new self;
    
        return self::$instance;
    } 

    private function __construct()
    {

    $dbOptions = array(
          'db_host' => 'localhost',
          'db_user' => 'user',
          'db_pass' => 'password',
          'db_name' => 'database'
        );

       $pdo = new PDO("mysql:host=". $dbOptions['db_host'] .";dbname=". $dbOptions['db_name'], $dbOptions['db_user'], $dbOptions['db_pass']);
    }

        
    private function __clone(){}
}

$obj = Database::getInstance();



$stmt = $obj->pdo->prepare("SELECT `mail` FROM `userdata` WHERE `username`= ? AND `password`= ?");
$p->bind_param('ss', $log_d, $p_md5);
$p->execute();
$stmt->bind_result($mail);
while ($stmt->fetch()) {
echo $mail;
}
Выдает ошибку Fatal error: Call to a member function prepare() on a non-object

Что опять не так? Что я опять недопонял?
Смотрим ошибку:
Фатальная ошибка: Вызвана функция-член prepare() у не объекта.

Смотрим строку на которой произошла ошибка.

$stmt = $obj->pdo->prepare("SELECT `mail` FROM `userdata` WHERE `username`= ? AND `password`= ?");

У кого мы вызываем prepare? У pdo.
На что ссылается pdo? Вроде бы должен на объект для работы с бд. Так, где же мы присваиваем объект для работы с бд этому свойству? Здесь:

$pdo = new PDO("mysql:host=". $dbOptions['db_host'] .";dbname=". $dbOptions['db_name'], $dbOptions['db_user'], $dbOptions['db_pass']);

Ага вот в чем проблема, тут мы присваиваем значение локальной переменной, а не к свойству класса.
 
Сверху