2013-06-26 3 views
1

Я пишу webapp, который должен использоваться внутри для множества задач. Он использует базу данных MySQL, которая регулярно запрашивается для данных.Неправильно ли использовать обычную функцию для запроса базы данных?

Я знаю подготовленные заявления и что они являются лучшими практиками, но учитывая большое количество таблиц и объединений, мне было проще всего написать общую функцию, которая берет запрос, запускает его и возвращает результат.

Я понимаю, что это может быть уязвимым для SQL-инъекции, если оно находится на реальном сайте, но есть ли что-то по своей сути плохое в использовании этого метода? Я относительно новичок в интерфейсе между php и MySQL и был бы заинтересован узнать лучшие практики для повторяющегося метода запуска операторов в webapp.

Вот пример функции, которую я бы использовал для SELECT запросов.

function getSQLResultsPDO($query){ 
    $mydb = new PDO('mysql:host=localhost;dbname=mydatabase;charset=utf8', 'user', 'password'); 
    $sth = $mydb->prepare($query); 
if (!$sth) { 
    echo "\n<pre>PDO::errorInfo():</pre>\n"; 
    echo "<pre>"; 
    print_r($conn->errorInfo()); 
    echo "</pre>"; 
} 
    $sth->execute(); 

    $result = $sth->fetchAll(PDO::FETCH_CLASS); 
    if (empty($result)){ 
    $result = false; 
    } 

    return $result; 

} 
+1

Это не о инъекции SQL, речь идет о синтаксической правильности! [Великий эскапизм (или: что вам нужно знать для работы с текстом в тексте)] (http://kunststube.net/escapism/) – deceze

+3

Вы действительно создаете новое соединение для каждого запроса youdo? – lonesomeday

+0

SQL-инъекции - это не риск, если вы не используете пользовательский ввод в свои запросы. Пока данные ваших запросов/условий поступают от ввода конечного пользователя (например, веб-форма). Подготовленные заявления более безопасны, хотя внутреннее приложение менее подвержено взлому ... –

ответ

0

Это может быть хорошая практика. Если вы посмотрите на фреймворки, они реализуют нечто похожее, за исключением того, что оно более сложное, и они позволяют создавать ваш запрос с использованием разных методов. Дело в том, чтобы централизовать запрос, если все запросы проходят один и тот же путь, проще изменить что-то, что касается всех запросов. Например, если вы хотите изменить свою базу данных из MySQL на что-то другое. Кроме того, вы можете защитить от инъекций в этой центральной точке.

Итак, ваша идея хорошая, но есть вещи, которые можно было бы улучшить, конечно. Вы можете создать одно соединение при открытии приложения и использовать его для каждого запроса, который вы запускаете позже. Если ваш метод запроса находится в классе, соединение может быть атрибутом класса, например, который инициализируется в конструкторе.

Мое предложение - посмотреть, как это делают другие люди, и получить вдохновение оттуда. Посмотрите, как, например, обращаются к инфраструктуре.

Кроме того, есть хороший MVC учебник, который также говорит об этом материале, здесь:

http://johnsquibb.com/tutorials

5

Я могу только согласиться с замечанием @jay Харриса: «все о том, что сценарий плохая практика»

Хотя идея использования такой функции, чтобы иметь дело с базой данных единственный разумный выбор, реализация все неправильно.

Прежде всего, почему вы считаете, что такая функция противоречит подготовленным заявлениям? Почему бы не добавить только один дополнительный параметр - массив с данными - и у вас есть функция и безопасность?

Далее, как вам уже сказали, не подключайтесь для каждого запроса, кроме после за приложение.

, наконец, ваш способ обработки ошибок неправильный.

function getSQLResultsPDO($query, $params = array(), type = PDO::FETCH_CLASS){ 
    global $mydb; 
    $sth = $mydb->prepare($query); 
    $sth->execute($params); 
    return $sth->fetchAll($type); 
} 

Это не очень удобно, но по крайней мере безопасно и безопасно на 95%.

После использования этой функции вы обнаружите, что довольно неудобно иметь только один.И в итоге вы обнаружите, что вам нужен набор функций. Один для запуска DML-запросов, который не возвращает строк, а некоторые функции возвращают разные результаты.

Сравните эти 2 кода:

$data = getSQLResultsPDO("SELECT name FROM users WHERE id=?", array($id)); 
if (isset($data[0]->name)) { 
    $name = $data[0]->name; 
} 
//and 
$name = getSQLscalar("SELECT name FROM users WHERE id=?", array($id)); 
+0

Спасибо за ваш ответ. Я сейчас немного более подробно разбираюсь в этом вопросе. Я действительно сделал шаг вперед и начал писать свой собственный класс, который использует PDO, который содержит материал соединения в методе '__construct()', и я могу просто вызвать через него различные методы запросов. – harryg

Смежные вопросы