Функция для экранирования различных типов переменных в MySQL Query

0

Мне надоело писать запросы на моем PHP как:

"WHERE '" . Database::escape($var) . "'";

Функция escape() просто вызывает mysql_real_escape_string() - но она есть, поэтому я могу позже расширить поддержку других баз данных.

Наличие одиночных строк кавычек в запросе делало мой код более загроможденным. Поэтому моя идея заключалась в создании другой функции в моем классе базы данных для "подготовки" переменной для запроса:

static public function prepare($var)
{

    if (is_object($var) || is_array($var) ) {
        return " '" . Database::escape(serialize($var)) . "' ";

    } else if (is_bool($var)) {
        return ' ' . (int)$var . ' ';

    } else if (is_int($var)) {
        return ' ' . $var . ' ';

    } else if (is_string($var) || is_float($var)) {
        return " '" . Database::escape($var) . "' ";

    } else {
        throw new Exception('Unsupported variable type [' . gettype($var) . ']');
    }
}

Теперь преимущество здесь в том, что мне не нужно беспокоиться о том, какие переменные я передаю в запрос. Однако возникает два вопроса:

  • Я правильно обрабатываю каждый тип переменной?
  • По какой причине (если есть) я не должен этого делать?
  • 0
    почему не используете PDO? У программы в php5?
  • 0
    il.php.net/manual/en/pdo.prepare.php
Показать ещё 1 комментарий
Теги:

4 ответа

1
Лучший ответ

Вы ищете a) pepared statements и b) уровень абстракции базы данных (например, PDO).

То, что вы пытаетесь сделать самостоятельно, уже было решено, вы не должны откатывать свою собственную реализацию.

Если вы спуститесь по этой дороге, вы заметите, что это:

"... WHERE '" . Database::escape($var) . "'"

бессмысленна и опасна. Четкое разделение кода и параметров SQL требует, чтобы вы были более явными и обеспечивали вам безопасную сторону от SQL-инъекции в одно и то же время:

"--- WHERE SomeField = ?"  /* the parameter (?) will be filled elsewhere */

Стоит отметить, что истинная независимость поставщика в области базы данных находится где-то между жестким и невозможным, в зависимости от ваших потребностей и приоритетов. Поэтому попытка написать переносимый SQL может оказаться бесполезной, если вы не готовы пожертвовать много. Для MySQL он запускается даже с помощью предложения LIMIT, которое вы не сможете подключить, скажем, к SQL Server.

  • 1
    pdo - это не уровень абстракции базы данных, а (цитата) «легкий, согласованный интерфейс для доступа к базам данных в PHP». PDO только абстрагирует и эмулирует при необходимости: подготовленные операторы.
  • 0
    Он абстрагирует всю потребность в префиксах «mysql_», «mssql_», «what_», которые вам понадобятся в противном случае. Это не ORM или что-то еще (если вы это имеете в виду). Я думаю, что en.wikipedia.org/wiki/Database_abstraction_layer относится к PDO.
2

Да, просто используйте параметризованные запросы, и он будет просто работать. Это правильное решение, и это не ужасно сложно.

В PHP используйте PDO для этого, его API гораздо более здравомыслящий, чем mysql_ или mysqli_, и, кроме того, он может генерировать исключения из ошибок и делать другие приятные вещи.

2

Вероятно, вы не должны этого делать. Вот почему: mysqli:: подготовить или PDO:: подготовить

Что касается самой функции, что произойдет, если у вас есть что-то, хранящееся в строке (скажем "5"), которую вы хотите сохранить как int? Он все равно будет процитировать его.

  • 0
    База данных имеет предопределенный тип для каждого столбца, поэтому для него не имеет значения, указан он в кавычках или нет. Однако специальные значения, такие как NOW () или CURRENT_TIMESTAMP, не должны заключаться в кавычки.
  • 0
    Что ж, тогда у вас будут проблемы, потому что как вы передаете эти значения? Конечно, не в виде строки, потому что это будет указано ...
0

Вы можете попробовать

$sql = "SELECT * FROM SomeTable WHERE userid = '{Database::prepare($userid}'";

чтобы облегчить проблемы с набором текста. Хотя мое предложение состоит в том, что если вы принимаете входные данные из формы, почему бы не настроить Database:: prepare() для запуска через $_REQUEST или $_POST, чтобы очистить их или выплеснуть копию?

Вот как я это делаю:

$safe_post = InputCleaner::clean($_POST);
$sql = "SELECT * FROM table WHERE userid = {$safe_post['userid']}";

Ещё вопросы

Сообщество Overcoder
Наверх
Меню