Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Prepared statement [2]
Форумы портала PHP.SU » Серверное администрирование » Администрирование БД » Prepared statement

Страниц (2): « 1 [2]
 

16. esterio - 31 Января, 2014 - 12:01:43 - перейти к сообщению
ух ты как все скадно у Вас здесь.
Вам указать явные ошибки или промолчать.
По факту где вы увидели у Вас работу с подготовленими запросами не знаю
Первим параметром в query передайте сам запрос, а вторым массив с данными. Делов-то.

И да у Вас неверный синглтон. По факту синглтон должен возвращать екземпляр обьекта. В то время у вас там идет только создание. наименование getInstance не делает то что нужно. Exception-ы не использованы. Впрочем ето не ООП, а какая-то каша с спагетти. Рекомендую переделать все заново
17. IllusionMH - 31 Января, 2014 - 12:04:32 - перейти к сообщению
Kenshin, ИМХО вы неправильно используете этот синглтон.
Единственной задачей его должно быть вернуть инстанс и указатель на соедиение. Т.е. в итоге вам нужно в своей функции получить свойство MySQLi этого синглтона, а дальше работать как обычно.
В противном случае нужно еще и переписать все методы.

Ай, опередили Радость
18. Kenshin - 31 Января, 2014 - 20:02:42 - перейти к сообщению
у меня в голове уже каша после прочтения всех материалов и я полностью запутался...
Спасибо за советы. Прочитал материалы еще раз, многое понял по новому. Многое понял, что раньше не понимал. Начал заново писать. Получилось так:

PHP:
скопировать код в буфер обмена
  1.  
  2. class Database
  3. {
  4.     public      $pdo;
  5.     static private $instance;
  6.         public $dbOptions;
  7.        
  8.          public static function getInstance()
  9.     {        
  10.         if(empty(self::$instance))  
  11.             self::$instance = new self;
  12.        
  13.         return self::$instance;
  14.     }    
  15.  
  16.          private function __construct()
  17.     {
  18.        
  19.         $dbOptions = array(
  20.           'db_host' => 'localhost',
  21.           'db_user' => 'user',
  22.           'db_pass' => 'password',
  23.           'db_name' => 'database'  
  24.         );
  25.        
  26.        $pdo = new PDO("mysql:host=". $dbOptions['db_host'] .";dbname=". $dbOptions['db_name'], $dbOptions['db_user'], $dbOptions['db_pass']);
  27.     }
  28.        
  29.            
  30.     private function __clone(){}
  31. }
  32.  
  33. $obj = Database::getInstance();
  34.  
  35.  
  36.  
  37. $stmt = $obj->pdo->prepare("SELECT `mail` FROM `userdata` WHERE `username`= ? AND `password`= ?");
  38. $p->bind_param('ss', $log_d, $p_md5);
  39. $p->execute();
  40. $stmt->bind_result($mail);
  41. while ($stmt->fetch()) {
  42. echo $mail;
  43. }
  44.  


Выдает ошибку Fatal error: Call to a member function prepare() on a non-object

Что опять не так? Что я опять недопонял?
19. esterio - 31 Января, 2014 - 20:24:05 - перейти к сообщению
Kenshin пишет:
$pdo = new PDO


Но тогда нарушаеться инкапсуляция, ибо свойство публичное
20. OrmaJever - 31 Января, 2014 - 20:53:31 - перейти к сообщению
Kenshin пишет:
class Database

Нет, нет, нет. Класс Database нужно забыть. Я понимаю что вы сильно хотите сделать singletone, тогда вот вам функция (я использую mysqli место PDO, т.к. лучше знаю его)
PHP:
скопировать код в буфер обмена
  1. function mysqli()
  2. {
  3.         static $mysqli;
  4.         if(is_null($mysqli)) {
  5.                 $mysqli = new mysqli(DB_HOST, DB_LOGIN, DB_PASS, DB_NAME);
  6.                 $mysqli->query('SET NAMES `utf8`'); // если нужно - изменить кодировку
  7.         }
  8.         return $mysqli;
  9. }

DB_HOST, DB_LOGIN, DB_PASS и DB_NAME это константы которые определены где-то в конфиге.
Использовать функцию элементарно
PHP:
скопировать код в буфер обмена
  1. mysqli()->query(...);
  2. mysqli()->num_rows;
  3. $p = mysqli()->prepare(...);
  4. // и т.к. любые методы и свойства

Плюсы очевидны
1) 7 строк, не создаём лишний код
2) функция всегда глобальна (в отличии от переменых ($mysqli))

Ну и вот далее вы используете так как я написал во втором посте этой темы (только место $mysqli пишем mysqli())
PHP:
скопировать код в буфер обмена
  1. $p = mysqli()->prepare("SELECT `mail` FROM `userdata` WHERE `username`= ? AND `password`= ?");
  2. $p->bind_param('ss', $log_d, $p_md5);
  3. $p->execute();
  4. $stmt->bind_result($mail);
  5. while ($stmt->fetch()) {
  6.    echo $mail;
  7. }

Что тут сложного?
21. Kenshin - 31 Января, 2014 - 21:43:41 - перейти к сообщению
OrmaJever пишет:
Kenshin пишет:
class Database

Нет, нет, нет. Класс Database нужно забыть. Я понимаю что вы сильно хотите сделать singletone, тогда вот вам функция (я использую mysqli место PDO, т.к. лучше знаю его)
PHP:
скопировать код в буфер обмена
  1. function mysqli()
  2. {
  3.         static $mysqli;
  4.         if(is_null($mysqli)) {
  5.                 $mysqli = new mysqli(DB_HOST, DB_LOGIN, DB_PASS, DB_NAME);
  6.                 $mysqli->query('SET NAMES `utf8`'); // если нужно - изменить кодировку
  7.         }
  8.         return $mysqli;
  9. }

DB_HOST, DB_LOGIN, DB_PASS и DB_NAME это константы которые определены где-то в конфиге.
Использовать функцию элементарно
PHP:
скопировать код в буфер обмена
  1. mysqli()->query(...);
  2. mysqli()->num_rows;
  3. $p = mysqli()->prepare(...);
  4. // и т.к. любые методы и свойства

Плюсы очевидны
1) 7 строк, не создаём лишний код
2) функция всегда глобальна (в отличии от переменых ($mysqli))

Ну и вот далее вы используете так как я написал во втором посте этой темы (только место $mysqli пишем mysqli())
PHP:
скопировать код в буфер обмена
  1. $p = mysqli()->prepare("SELECT `mail` FROM `userdata` WHERE `username`= ? AND `password`= ?");
  2. $p->bind_param('ss', $log_d, $p_md5);
  3. $p->execute();
  4. $stmt->bind_result($mail);
  5. while ($stmt->fetch()) {
  6.    echo $mail;
  7. }

Что тут сложного?


С этим всё понятно...
Но у меня была другая задача. Незнаю или вообще можно так сделать или нет... но дело было так, напишу еще раз...
Была задача:
1. написать Класс синглетон для подключения к базе данных используя mysqli или PDO...
и другой класс, где уже обрабатывались данные с БД.
Это я вроде бы сделал... хотя криво по не опыту и не знанию... но все равно все работало....
2. Мой учитель взглянул на это все и дал задание, всё хорошо, но я должен подумать о prepared statement для минимизации SQL-инъекций...

Вот поэтому я и начал ломать голову, как это сделать и или вообще это можно сделать....
По задаче Класс синглетон должен остаться...
Вот я и не могу понять... или я совсем дурак и не понимаю.... или это мой учитель дурак и мне дурацкое задание дает....
22. OrmaJever - 31 Января, 2014 - 21:51:24 - перейти к сообщению
Kenshin пишет:
1. написать Класс синглетон для подключения к базе данных используя mysqli или PDO...

Браво, я вам только что это сделал, только это не класс, а функция, но разницы абсолютно никакой.
Kenshin пишет:
и другой класс, где уже обрабатывались данные с БД.

Ну вот и займитесь этим. Как обрабатывать данные с бд я тоже писал в предыдущем посте.
Kenshin пишет:
Мой учитель

Вот оно что))) Я верен что вы его удивите функцией синглтона Закатив глазки
Kenshin пишет:
но я должен подумать о prepared statement для минимизации SQL-инъекций...

Опять же, всё есть в моём предыдущем посте.
Kenshin пишет:
По задаче Класс синглетон должен остаться...
Вот я и не могу понять... или я совсем дурак и не понимаю.... или это мой учитель дурак и мне дурацкое задание дает....

Синглтон это паттерн (шаблон), а вот реализация уже идёт в классе. Но я вам могу сказать что конкретно для класса работы с бд(mysqli, PDO) реализация в классе бессмысленна, лучше делать как я показал используя функцию. Если ваш учитель захочет именно реализацию с классом, попросите его обосновать чем класс лучше моей функции.

 

Powered by ExBB FM 1.0 RC1