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 :: Версия для печати :: MySQLi при ООП
Форумы портала PHP.SU » » Вопросы новичков » MySQLi при ООП

Страниц (4): [1] 2 3 4 »
 

1. teddy - 11 Июня, 2013 - 12:55:09 - перейти к сообщению
Доброго дня всем ) Уже 3ий день мучают несколько вопросов, в гугле лекарства нашел, но чую должно быть более оптимальное решение...

Решил перейти с MySQL на использование MySQLi и сразу же столкнулся с проблемой при написании своего первого класса с использованием MySQLi. Вот пример:

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. class baseCMS {
  3.  
  4.         public $mysqli;
  5.        
  6.                 function __construct () {
  7.                         $this->mysqli = new mysqli("localhost", "root", "", "CMS");
  8.                         $this->mysqli->query("SET NAMES 'cp1251'");
  9.                         echo "Соединение с БД открыто <br />";
  10.                
  11.                 }
  12.        
  13.         function addArticle($title, $content, $date, $author) {
  14.                
  15.                 $this->mysqli->query("INSERT INTO articles(title, content, date, author) VALUES('$title','$content','$date','$author')")or die($this->mysqli->error);
  16.                                                                                                                        
  17.         }
  18.                 function __destruct () {
  19.                        
  20.                         $this->mysqli->close();
  21.                         echo "Соединение с БД закрыто";
  22.                
  23.                 }
  24. }
  25. $obj = new baseCMS();
  26. ?>

А что если объектов будет больше? Каждый раз будет открываться и закрываться соединение... А нужно что бы было одно для всех, как например в MySQL создали 1 файл и инклюдим его повсюду где надо... Видел примеры в гугле с использованием сингл тона, но как то "грязно" выглядит на мой взгляд.

Получается нужно создать отдельный класс для соединения с БД? Если да, то какой от него толк? Выходит что опять же лишняя писанина... Проще в каждом методе просто открыть и закрыть соединение... Не могу разобраться, помогите пожалуйста Растерялся

И ещё заметил что начало глючить $mysqli->real_escape_string. При выводе с echo спецсимволы экранируется, а вот в БД опять же уходит без экранирования... Читал что проблема из за кодировки, пробовал с разными, результат один и тот же...
2. AlexAnder - 11 Июня, 2013 - 13:04:52 - перейти к сообщению
singleton Растерялся
3. LIME - 11 Июня, 2013 - 13:11:23 - перейти к сообщению
как вариант public static $mysqli;
хотя в ряде случаев singleton предпочтительнее для начала можно и просто статической переменной пользоваться
+ы статической переменной(она же и в singleton используется) в том что область видимости - везде
(Добавление)
PHP:
скопировать код в буфер обмена
  1. self::$mysqli->set_charset('utf8');

Цитата:
Это предпочтительный способ задания набора символов. Использование для этих целей функции mysqli_query() (например SET NAMES utf8) не рекомендуется.
4. teddy - 11 Июня, 2013 - 13:32:01 - перейти к сообщению
LIME
Мне проще будет в каждом методе открыть/закрыть соединение, стыдно признать, но в упор не понимаю что к чему...

LIME пишет:
set_charset('utf8');

Спасибо учту, а как быть с экранированием спец. символов? В конце первого поста описал проблему, как можно ее вылечить? Если использую mysql_real_escape_string или $mysqli->real_escape_string() и вывожу результат при помощи echo, то экранируется нормально, но в БД данные добавляются уже без экранирования...
5. DeepVarvar - 11 Июня, 2013 - 13:37:36 - перейти к сообщению
teddy пишет:
проще будет в каждом методе открыть/закрыть соединение
Бред.
teddy пишет:
но в БД данные добавляются уже без экранирования..
Так и должно быть.
6. LIME - 11 Июня, 2013 - 13:37:46 - перейти к сообщению
teddy пишет:
Мне проще будет в каждом методе открыть/закрыть соединение, стыдно признать, но в упор не понимаю что к чему...
простой пример
Спойлер (Отобразить)
7. teddy - 11 Июня, 2013 - 13:43:50 - перейти к сообщению
DeepVarvar пишет:
Бред.

Знаю, что бред ) затем и обратился на форум )) не знаю, бывает у меня такое, чего то не понимаю в упор, но спустя некоторое время начинаю смеяться над самим собой )) ну это тогда когда уже врубаюсь в тему ))

DeepVarvar пишет:
Так и должно быть.

Странно, я почему то думал в БД должно добавляться уже экранированные данные, иначе какой толк от функции? Если мне не изменяет память, то видел даже своими глазами в одном из обучающих видеоуроков... месяца 2-3 назад было конечно, поэтому могу ошибаться...

LIME пишет:
baseCMS::addArticle($title, $content, $date, $author);

Ах вот оно что, точно, видел такое )) Но почему то в голове крутилась мысль "mysqli же более совершеннее чем mysql", значит там все должно быть проще! ) Оно и сбивало меня с толку... я думал что это бред и есть более простое решение спасибо за помощь! )
8. LIME - 11 Июня, 2013 - 13:49:08 - перейти к сообщению
смысл экранирования в невозможности sql инъекции
например
PHP:
скопировать код в буфер обмена
  1. $query="SELECT * FROM tbl WHERE login='{$_GET['login']}' AND psw='{$_GET['psw']}'";

что будет если ввести в поле логина и пароля например
' OR 1=1 AND id<>'
9. teddy - 11 Июня, 2013 - 13:57:24 - перейти к сообщению
LIME
А-а, теперь понятно.. тоесть экранирование действует в момент выполнения запроса, если я правильно понял, таким образом "внедренный" скрипт остается в ауте в момент запроса и не срабатывает, а то что он добавится в БД - это не страшно...

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

ну чтож, закрываем тему наверное )) Спасибо ещё раз, теперь могу кодить дальше.. а то тупил почти 3 дня )
10. LIME - 11 Июня, 2013 - 14:04:33 - перейти к сообщению
тебе надо уяснить одно простую весч
сервер бд работает отдельно
и строка запроса передается в него
именно строка
которую формирует пых
и экранированные символы бд воспринимает как часть значения
11. esterio - 11 Июня, 2013 - 14:10:31 - перейти к сообщению
teddy пишет:
Странно, я почему то думал в БД должно добавляться уже экранированные данные, иначе какой толк от функции? Если мне не изменяет память, то видел даже своими глазами в одном из обучающих видеоуроков... месяца 2-3 назад было конечно, поэтому могу ошибаться...

В виду последним массовым напливом вопросов про mysql_real_escape_string
небольшое отступление. есть запрос
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM users WHERE user='teddy'

Теперь перенесем ето на ПХП
PHP:
скопировать код в буфер обмена
  1. $_POST['user'] = 'teddy';
  2. $query = "SELECT * FROM users WHERE user='{$_POST['user']}'";

Теперь немного изменим POST[user]
PHP:
скопировать код в буфер обмена
  1. $_POST['user'] = 'teddy\'; DROP TABLE users; --';

В итоге получим запрос вида
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM users WHERE user='teddy'; DROP TABLE users; --'

Что произедет: будет возвращен пользователь с ником teddy и удалена таблица users
Теперь воспользуемся екранацией данных
$query = "SELECT * FROM users WHERE user='".mysql_real_escape_string($_POST['user'])."'";[/PHP]
в итоге получим запрос:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM users WHERE user='teddy\'; DROP TABLE users; --'

Тоесть таблица не будет удалена
12. LIME - 11 Июня, 2013 - 14:29:43 - перейти к сообщению
вообще-то она итак не будет удалена))
пых в общем случае не позволяет выполнять несколько запросов))
13. teddy - 11 Июня, 2013 - 14:48:26 - перейти к сообщению
LIME пишет:
тебе надо уяснить одно простую весч
сервер бд работает отдельно
и строка запроса передается в него
именно строка
которую формирует пых
и экранированные символы бд воспринимает как часть значения

ага, получается я просто не совсем правильно представлял себе как оно работает )


esterio
Спасибо за подробное описание ) заметил разницу в подсветке SQL запроса, в последнем случае запрос на "удаление" не подсвечивается как "удаляющий"... надеюсь правильно объяснил то, что хотел сказать )) Почти такие же примеры увидел в одной статье про sql иньекции на хабре )
14. esterio - 11 Июня, 2013 - 14:59:29 - перейти к сообщению
teddy
LIME прав. мушу извинится за дизинформацию. только что протестил. и правда таблица не удалилась. но суть одинакова. думал пример с удалением таблиц будет виглядеть более угрожающе
15. LIME - 11 Июня, 2013 - 15:02:57 - перейти к сообщению
страшный пример
CODE (SQL):
скопировать код в буфер обмена
  1. DELETE FROM mesages WHERE id=100500 OR 1=1

(Добавление)
так жк апдейт можно применить ко всем рядам
тоже цепенею от ужаса как представлю))
(Добавление)
http://php.net/manual/ru/mysqli.multi-query.php

 

Powered by ExBB FM 1.0 RC1