Здравствуйте любители и профессионалы PHP. Вот решил на днях написать класс роботы с базой данных MySQL . Я не профессионал и хочу, чтобы вы посмотрели на него своим профессиональным взглядом, дали свою рецензию и может, посоветовали, как его улучшить. Очень интересует вопрос безопасности, не люблю когда кто-то портит мне настроение. Буду рад выслушать ваше мнение. Скажу сразу, что он написан не полностью мной, проверка данных перед вводом была скромно мною украдена :wink: PHP: <?php /** * Ксасс для роботы с базой данных */ class Database { private $pconn; private $host; private $port; private $user; private $pass; private $base; private $char; private $debug; private $loging; private $antihack; private $conn_id; private $query_id; private $counter = '0'; private $work_time; private $error; private $error_exp; function Connect(){ if($this->pconn){ $this->conn_id = @mysql_pconnect($this->host, $this->user, $this->pass); } else { $this->conn_id = @mysql_connect($this->host, $this->user, $this->pass); } if($this->conn_id){ $dbselect = @mysql_select_db($this->base); if(!$dbselect){ @mysql_close($this->conn_id); $this->error = 'Невозможно выбрать базу данных'; return false; } } else { $this->error = 'Невозможно подключится к серверу базы данных'; return false; } return $this->conn_id; } function Disconnect(){ if($this->conn_id){ if($this->query_id){ @mysql_free_result($this->query_id); } $result = @mysql_close($this->conn_id); return $result; } else { return false; } } function Query($query,$file,$line){ if ($this->antihack) { $clean = ''; $old_pos = '0'; $pos = '-1'; while (true) { $pos = strpos($query, '\'', $pos++); if ($pos === false) break; $clean .= substr($query, $old_pos, $pos - $old_pos); while (true) { $pos1 = strpos($query, '\'', $pos++); $pos2 = strpos($query, '\\', $pos++); if ($pos1 === false) break; elseif ($pos2 == false || $pos2 > $pos1) { $pos = $pos1; break; } $pos = $pos2++; } $clean .= '%s'; $old_pos = $pos++; } $clean .= substr($query, $old_pos); $clean = trim(strtolower(preg_replace(array('~\s+~s', '~/\*!40001 SQL_NO_CACHE \*/~', '~/\*!40000 USE INDEX \([A-Za-z\_]+?\) \*/~'), array(' ', '', ''), $clean))); // Мы не используем UNION. Зато они удобны для инекций. if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0) $this->error = true; // Комментарии? Мы не используем комментарии в запросах! elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, ';') !== false) $this->error = true; // Попытка подмены паролей, замедления сервера или чего-то еще? elseif (strpos($clean, 'set password') !== false && preg_match('~(^|[^a-z])set password($|[^[a-z])~s', $clean) != 0) $this->error = true; elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0) $this->error = true; // Под выборы? Мы их не используем. elseif (preg_match('~\([^)]*?select~s', $clean) != '0') $this->error = true; if (!empty($this->error)){ $this->Log($query,$file,$line); die('Что хакер да?'); } } if ($this->debug) { $StartTimer = microtime(1); } $this->query_id = mysql_query($query, $conn_id); if (!$this->query_id){ $this->Log($query,$file,$line); die('Ошибка выполнения запроса'); } if ($this->debug) { $this->work_time = microtime(1) - $StartTimer; } $this->counter++; return $this->query_id; } function Fetch_Row($query_id = "") { if ($query_id == "") { $query_id = $this->query_id; } return mysql_fetch_array($query_id, MYSQL_ASSOC); } function Get_Counter() { return $this->counter; } function Get_Result_Fields($query_id = "") { if ($query_id == ""){ $query_id = $this->query_id; } while ($field = mysql_fetch_field($query_id)){ $Fields[] = $field; } return $Fields; } function Free_Result($query_id = "") { if ($query_id == "") { $query_id = $this->query_id; } @mysql_free_result($query_id); } function Log($query,$file,$line){ if($this->loging){ if ($this->work_time > 0.1){ $time = "<span style='color:red'><b>$this->work_time</b></span>"; } if (preg_match("/^select/i", $query)){ $explain = mysql_query("EXPLAIN $query", $this->conn_id); if ($explain !== true){ $this->error_exp .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FEFEFE' align='center'>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'><b>Недопустимый запрос</b></td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-family:courier, monaco, arial;font-size:14px'>".$query."</td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'>"; $this->error_exp .= "<b>Дата</b>: ".date("y.m.d H:i:s")."<br />"; $this->error_exp .= "<b>Файл</b>: ".$file."<br />"; $this->error_exp .= "<b>Строка</b>: ".$line."<br>"; $this->error_exp .= "</tr>"; $this->error_exp .= "</table><br />\n\n"; } else { $array = mysql_fetch_array($explain); $type_col = '#FFFFFF'; if ($array['type'] == 'ref' or $array['type'] == 'eq_ref' or $array['type'] == 'const'){ $type_col = '#D8FFD4'; } else if ($array['type'] == 'ALL'){ $type_col = '#FFEEBA'; } $this->error_exp .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FFE8F3' align='center'>\n"; $this->error_exp .= "<tr>\n"; $this->error_exp .= "<td colspan='8' style='font-size:14px' bgcolor='#FFC5Cb'><b>Select Запрос</b></td>\n"; $this->error_exp .= "</tr>\n"; $this->error_exp .= "<tr>\n"; $this->error_exp .= "<td colspan='8' style='font-family:courier, monaco, arial;font-size:14px;color:black'>\n".$query."</td>"; $this->error_exp .= "</tr>\n"; $this->error_exp .= "<tr bgcolor='#FFC5Cb'>\n"; $this->error_exp .= "<td><b>table</b></td><td><b>type</b></td><td><b>possible_keys</b></td>\n"; $this->error_exp .= "<td><b>key</b></td><td><b>key_len</b></td><td><b>ref</b></td>\n"; $this->error_exp .= "<td><b>rows</b></td><td><b>Extra</b></td>\n"; $this->error_exp .= "</tr>\n"; $this->error_exp .= "<tr bgcolor='#FFFFFF'>\n"; $this->error_exp .= "<td>".$array[table]." </td>\n"; $this->error_exp .= "<td bgcolor='".$type_col."'>".$array[type]." </td>\n"; $this->error_exp .= "<td>".$array[possible_keys]." </td>\n"; $this->error_exp .= "<td>".$array[key]." </td>\n"; $this->error_exp .= "<td>".$array[key_len]." </td>\n"; $this->error_exp .= "<td>".$array[ref]." </td>\n"; $this->error_exp .= "<td>".$array[rows]." </td>\n"; $this->error_exp .= "<td>".$array[Extra]." </td>\n"; $this->error_exp .= "</tr>\n"; $this->error_exp .= "<tr>\n"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'>"; $this->error_exp .= "<b>Дата</b>: ".date("y.m.d H:i:s")."<br />"; $this->error_exp .= "<b>Файл</b>: ".$file."<br />"; $this->error_exp .= "<b>Строка</b>: ".$line."<br>"; $this->error_exp .= "<b>Время выполнения</b>: ".$time; $this->error_exp .= "</tr>"; $this->error_exp .= "</table><br />\n\n"; } } else { $this->error_exp .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FEFEFE' align='center'>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'><b>Не Select Запрс</b></td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-family:courier, monaco, arial;font-size:14px'>".$query."</td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'>"; $this->error_exp .= "<b>Дата</b>: ".date("y.m.d H:i:s")."<br />"; $this->error_exp .= "<b>Файл</b>: ".$file."<br />"; $this->error_exp .= "<b>Строка</b>: ".$line."<br>"; $this->error_exp .= "<b>Время выполнения</b>: ".$time; $this->error_exp .= "</tr>"; $this->error_exp .= "</table><br />\n\n"; } return $this->error_exp; //Временно! } } function Config($array){ if(empty($array)){ $this->error = 'Конфигурация БД не задана'; return false; } $class_vars = get_object_vars($this); foreach ($class_vars as $key => $val){ if (array_key_exists($key, $array)) { $this->$key = $array[$key]; } } return true; } } ?> Что будет из меня толк?
Понравилось. Хорошая идея. Расширяемая. абсолютно напрасно. Ибо г*вно. Не надо ничего проверять. Надо просто исключить возможность SQL-инъекции. Укради лучше отсюда — http://www.dklab.ru/lib/DbSimple/manual.html#cont7
Однако я заранее не знаю какие запросы буду передавать базе? а хочу реализовать проверку именно в этом классе чтобы потом даже не думать про это.
oligarx вот именно. Плейсхолдеры для этого и нужны. Но не странным отметанием UNION, которым я пользуюсь, а именно ЭКРАНИРОВАНИЕМ ВХОДЯЩИХ ДАННЫХ.
Ну, если кому приглянется класс, то используйте на здоровье! Думаю мою роботу ссылочкой не обидите. Если кто-то его будет усовершенствовать или дополнять сообщите, мне очень интересно.
Тогда получается мне надо проститать все возможные запросы к моей БД и для каждого создать метод? Другого рационального пути я не вижу т.к. я хочу, чтобы вся безопасность обрабатывалась именно в классе БД (мне кажется, это избавит от многих щелей в программе, а для меня это важно).
oligarx, ты прочитал ссылку? там вообще ничего просчитывать не надо. Там надо экранировать входящие данные. И все. Никаких SQL-иньекций.
Прочитал, понял – был не прав! Только правда надо следить за тем чтобы все запросы использовали именно placeholder’ы, а то напишет кто-то код без них и все минус зашита, точнее появится щель.
Нужно написать парсер но я не очень понимаю как работают регулярные выражения. Вот что надо заменить из строчки запроса ‘?’ на первый элемент массива $array. Что я уже сделал: PHP: <?php $i = '0'; foreach ($array as $key => $data){ $query = preg_replace('?', $array[$i], $query, '1'); $i++; } ?> Подскажите, а то у меня как раз мысль пошла. У нас нововведение? Что-то я раньше капатчи тут не видел. Проблема в другом сервер работать будет у меня, а програмеров несколько. Придется за всеми следить и проверять что они пишут.
oligarx Регулярками бесполезно, я пробовал... только простейшие конструкции, сложные запросы они не в силах обработать, точнее я просто не смог такие сделать. Тут надо разбирать посимвольно код запросов и делать автомат, который занимаеться разбором и анализом. Короче, полноценный парсер SQL запросов.
Ну вот приблизительно то что говорил Горбунов Олег в моем классе. Можно еще много чего добавить. Но это уже по необходимости. Какие в методе классы, думаю понятно и без дополнительного описания. А вот составляем запрос мы вот так: $DB->Query($mask, $array_var, __FILE__, __LINE__); Пример: PHP: <?php // include mysql.php $DB = new Database; $DB-> Config($array); $DB-> Connect(); $DB-> Query(“SELECT * FROM `banner` WHERE `id` = ?”, “2”,__FILE__,__LINE__); ?> То есть сначала мы задаем маску $mask, по которой будет выполнен запрос: “SELECT * FROM `jos_banner` WHERE `bid` = ?” Как видно на этом примере в маске присутствует знак вопроса “?”. Вот он и задает маску. Вместо «?» автоматически будет подставлена значение массива $array_var. Знаков “?” может быть несколько в таком случае они просто будут по очереди замещаться на следующее значение массива $array_var. ВНИМАНИЕ! Маска не должна содержать “’”; $array_var это численный массив. Если произойдет ошибка при выполнении запроса то пользователь получит сообщение об ошибке и сработает команда die(). Стандартно пользователь увидит системную информацию о происхождении ошибки (метод предназначен для создания лога). Конфигурация класса. Для задания конфигурации вам надо передать значения классу через метод Config($array) где $array ассоциативный массив с ключами pconn, host, port, user, pass, base, char, debug, loging. Думаю всем понятно для чего они и что в них вносить. Ладно хватит болтовни вот собственно обновлена версия класса: PHP: <?php /** * Ксасс для роботы с базой данных */ class Database { private $pconn; private $host; private $port; private $user; private $pass; private $base; private $char; private $debug; private $loging; private $conn_id; private $query_id; private $counter = '0'; private $work_time; private $error; private $error_exp; function Connect(){ if($this->pconn){ $this->conn_id = @mysql_pconnect($this->host, $this->user, $this->pass); } else { $this->conn_id = @mysql_connect($this->host, $this->user, $this->pass); } if($this->conn_id){ $dbselect = @mysql_select_db($this->base); if(!$dbselect){ @mysql_close($this->conn_id); $this->error = 'Невозможно выбрать базу данных'; return false; } } else { $this->error = 'Невозможно подключится к серверу базы данных'; return false; } return $this->conn_id; } function Disconnect(){ if($this->conn_id){ if($this->query_id){ @mysql_free_result($this->query_id); } $result = @mysql_close($this->conn_id); return $result; } else { return false; } } function Query($query,$var,$file,$line){ $holder_count = substr_count($query, '?'); $var_count = count($var); if($holder_count != $var_count || substr_count($query,"'") > '0'){ $var_merge = ''; foreach ($var as $key => $data){ $var_merge .= $data; } $query = 'Маска: '.$query.' Ключи: '.$var_merge; $this->Log($query,$file,$line); die(); } $i = '0'; foreach ($var as $key => $data){ $query = preg_replace('\?', "'".$var[$i]."'", $query, '1'); $i++; } if ($this->debug) { $StartTimer = microtime(1); } $this->query_id = mysql_query($query, $this->conn_id); if (!$this->query_id){ $this->Log($query,$file,$line); die('Ошибка выполнения запроса'); } if ($this->debug) { $this->work_time = microtime(1) - $StartTimer; } $this->counter++; return $this->query_id; } function Fetch_Row($query_id = "") { if ($query_id == "") { $query_id = $this->query_id; } return mysql_fetch_array($query_id, MYSQL_ASSOC); } function Get_Counter() { return $this->counter; } function Get_Result_Fields($query_id = "") { if ($query_id == ""){ $query_id = $this->query_id; } while ($field = mysql_fetch_field($query_id)){ $Fields[] = $field; } return $Fields; } function Free_Result($query_id = "") { if ($query_id == "") { $query_id = $this->query_id; } @mysql_free_result($query_id); } function Log($query,$file,$line){ if($this->loging){ if ($this->work_time > 0.1){ $time = "<span style='color:red'><b>$this->work_time</b></span>"; } if(preg_match("/^fatal error/i",$query)){ $this->error_exp .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FEFEFE' align='center'>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'><b>Критическая Ошибка</b></td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-family:courier, monaco, arial;font-size:14px'>".$query."</td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'>"; $this->error_exp .= "<b>Дата</b>: ".date("y.m.d H:i:s")."<br />"; $this->error_exp .= "<b>Файл</b>: ".$file."<br />"; $this->error_exp .= "<b>Строка</b>: ".$line."<br>"; $this->error_exp .= "</tr>"; $this->error_exp .= "</table><br />"; }elseif (preg_match("/^select/i", $query)){ $explain = mysql_query("EXPLAIN $query", $this->conn_id); if ($explain !== true){ $this->error_exp .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FEFEFE' align='center'>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'><b>Недопустимый запрос</b></td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-family:courier, monaco, arial;font-size:14px'>".$query."</td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'>"; $this->error_exp .= "<b>Дата</b>: ".date("y.m.d H:i:s")."<br />"; $this->error_exp .= "<b>Файл</b>: ".$file."<br />"; $this->error_exp .= "<b>Строка</b>: ".$line."<br>"; $this->error_exp .= "</tr>"; $this->error_exp .= "</table><br />\n\n"; } else { $array = mysql_fetch_array($explain); $type_col = '#FFFFFF'; if ($array['type'] == 'ref' or $array['type'] == 'eq_ref' or $array['type'] == 'const'){ $type_col = '#D8FFD4'; } else if ($array['type'] == 'ALL'){ $type_col = '#FFEEBA'; } $this->error_exp .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FFE8F3' align='center'>\n"; $this->error_exp .= "<tr>\n"; $this->error_exp .= "<td colspan='8' style='font-size:14px' bgcolor='#FFC5Cb'><b>Select Запрос</b></td>\n"; $this->error_exp .= "</tr>\n"; $this->error_exp .= "<tr>\n"; $this->error_exp .= "<td colspan='8' style='font-family:courier, monaco, arial;font-size:14px;color:black'>\n".$query."</td>"; $this->error_exp .= "</tr>\n"; $this->error_exp .= "<tr bgcolor='#FFC5Cb'>\n"; $this->error_exp .= "<td><b>table</b></td><td><b>type</b></td><td><b>possible_keys</b></td>\n"; $this->error_exp .= "<td><b>key</b></td><td><b>key_len</b></td><td><b>ref</b></td>\n"; $this->error_exp .= "<td><b>rows</b></td><td><b>Extra</b></td>\n"; $this->error_exp .= "</tr>\n"; $this->error_exp .= "<tr bgcolor='#FFFFFF'>\n"; $this->error_exp .= "<td>".$array[table]." </td>\n"; $this->error_exp .= "<td bgcolor='".$type_col."'>".$array[type]." </td>\n"; $this->error_exp .= "<td>".$array[possible_keys]." </td>\n"; $this->error_exp .= "<td>".$array[key]." </td>\n"; $this->error_exp .= "<td>".$array[key_len]." </td>\n"; $this->error_exp .= "<td>".$array[ref]." </td>\n"; $this->error_exp .= "<td>".$array[rows]." </td>\n"; $this->error_exp .= "<td>".$array[Extra]." </td>\n"; $this->error_exp .= "</tr>\n"; $this->error_exp .= "<tr>\n"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'>"; $this->error_exp .= "<b>Дата</b>: ".date("y.m.d H:i:s")."<br />"; $this->error_exp .= "<b>Файл</b>: ".$file."<br />"; $this->error_exp .= "<b>Строка</b>: ".$line."<br>"; $this->error_exp .= "<b>Время выполнения</b>: ".$time; $this->error_exp .= "</tr>"; $this->error_exp .= "</table><br />\n\n"; } } else { $this->error_exp .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FEFEFE' align='center'>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'><b>Не Select Запрс</b></td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-family:courier, monaco, arial;font-size:14px'>".$query."</td>"; $this->error_exp .= "</tr>"; $this->error_exp .= "<tr>"; $this->error_exp .= "<td style='font-size:14px' bgcolor='#EFEFEF'>"; $this->error_exp .= "<b>Дата</b>: ".date("y.m.d H:i:s")."<br />"; $this->error_exp .= "<b>Файл</b>: ".$file."<br />"; $this->error_exp .= "<b>Строка</b>: ".$line."<br>"; $this->error_exp .= "<b>Время выполнения</b>: ".$time; $this->error_exp .= "</tr>"; $this->error_exp .= "</table><br />\n\n"; } return $this->error_exp; //Временно! } } function Config($array){ if(empty($array)){ $this->error = 'Конфигурация БД не задана'; return false; } $class_vars = get_object_vars($this); foreach ($class_vars as $key => $val){ if (array_key_exists($key, $array)) { $this->$key = $array[$key]; } } return true; } } // Конец класса ?> Предупреждаю! класс я полностью не тестировал. Завтра прогоню его и исправлю. Если найдете ошибки, подождите до завтра может я их сам исправлю. Пишите, обсуждайте, буду рад.
На самом деле есть MySQLi где уже есть Prepared Statments. Так что лучше юзать их А вообще, я считаю, что в классе не надо заморачиваться с проверками. Это должно лежать на плечах самого программиста. Если он составил криво запрос - это его проблемы. А проверять, парсить, экранировать... бесполеная работа, пожирающая порой много процесорного времени. P.S. Я вообще работаю напрямую с mysql_* функциями. А если юзаю MySQLi и мне нужен какой-то дебагинг, я просто переопределяю метод query и всё. Большего там практически не надо.
Согласен, но только в том случае если параметры запроса задаются не пользовательским вводом. А если запрос составляется динамически? Что каждый раз делать довольно не малый код проверки данных? Или писать сложное регулярное выражение, которое будет проверять правильно указаны параметры или нет? Думаю, что такие способы будут не намного быстрее, чем этот класс. Зато объемы кода резко увеличатся, да и читаемость явно не возрастет. По крайней мере, мне будет неудобно разобраться у куче кода, который делает проверку каждой переменной (в запросе) которую передал пользователь.
а почему не сделать функцию проверки? почему не разделить входящие параметры на типы и важность, и проверять в зависимости от них?
Не всегда хорошая идея приходит сразу. Но все равно надо проверять ,так какая разница в классе или нет?
Обычно всё же данные часто бывают разнородные. Где то это может быть цифра, а пришлют строку - как функция поймёт что это должна быть цифра? Задавать конфиги - тоже нудно. А если надо проверить регулярками, или разбить данные на части и.т.д.? Тупая проверка не занимает много места и пишеться быстро. Удобно использовать Exceptions в этом случае. Если код написан правильно, такие коды будут минимальны и просты и писаться за минуты. У меня всё время уходит обычно на другие вещи, проверка данных пишеться в течении буквально от 2-3 до 30 (совсем запущенный случай) минут в зависимости от их кол-ва и сложности проверок. В текущем проэкте я писал форум, проверка данных заняла буквально 3-4 строки с выводом ошибки. Так что заморачиваться с их проверкой на самом деле глупо. Писать мега функции, которые только будут тормозить, когда решение на самом деле очень простое, не логично. Пример. У вас приходит из URL'a ID. Конечно надо защититься от SQL Injection. Тупо делаем так: PHP: <?php $result = mysql_query('SELECT * FROM table WHERE id = '.(int)$_GET['id'], $db); if (mysql_num_rows($result)){ // обрабатываем и выводим результат }else{ exit('Хакирь, да?'); } ?> SQL Injection не случиться 100%. Введут левый ID? Ну и что, выведит просто другие данные. Если нужна проверка, а может ли пользователь иметь доступ к данным, то просто надо дополнительно проверить уровень доступа и в IF вписать через && условие, а может ли он иметь к данным доступ. Вставка данных? Да так-же. Если нужно число, вставляем (int)$_POST['chislo'], всё остальное вставляем пропустив через mysql_escape_string() и в " " кавычки в запросе. Если надо, проверили важные данные, а валидны ли они. Хотя конечно это просто надо на опыте понять. Мне намного проще работать напрямую. Это даёт максимальную гибкость, я не упираюсь в ограничения самописных функций по проверке данных. Делаю так, как удобнее в конкретном случае и могу проверить что угодно. От просто заквотить данные, до мега проверки по половине базы данных, а можно ли вставить такие данные этому юзеру вот в такое поле, проверить верны ли ID'ки которые он прислал. И.т.д. Стараюсь держаться принципа KISS, писать просто но удобно и без лишнего кода. PHP всё же скриптовый язык и кол-во и сложность кода на скорость влияют гораздо сильнее, чем на любой компилируемый язык. Зачем мучаться, писать мега универсальные функции проверок, с кучей конфигов и.т.д., если я могу просто сделать PHP: <?php if (is_numeric($param1) && is_array($param2)){ // do something }else{ // Error, invalid data. Print form again with filled fields } Быстро, просто, понятно!
после этого можно было бы и не продолжать, ибо жудкая весч 1. http://php.net/debug_backtrace 2. что функция логирования забыла в классе работы с БД? 3. почему чтобы начать работать с БД нужно написать преварительно 3 строчки кода? 4. почему нельзя использовать апостроф в запросе? 5. как выбрать всю таблицу ввиде одного массива?
Ребята я только учусь, и благодаря этому обсуждению обучение проходит гораздо быстрее. Спасибо вам за это! Psih по поводу проверок. Сам посмотрел на свой код и понял что слишком много лишнего и нагружающего. Просто учусь на разборе чих-то проектов типа форумов CMS и т.д. Смотрел как они делают проверку и подумал что такие опытные люди как они не могут так просто ошибиться (видно что могут). Для себя окончательно решил делать проверку до класса (причем сам), а ваши слова только подтверждают мою правоту. dark-demon полностью упрощать запрос я не хочу и не буду т.к. Я решил упростить его до такой формы: PHP: <?php $DB->Query($query, __FILE__, __LINE__); FILE и LINE я решил оставить по тому что потом будет легче находить откуда пошла ошибка, да и поставить __FILE__ __LINE__ не большая проблема.
Читал! Но мне такой принцип не очень. Мой способ просто мне нравится больше. Да и что проблема вставить два слова? 440Hz что боты все-таки нравится начали? Где капача?