PHP: обрабатывать переменную как функцию? - PullRequest
0 голосов
/ 13 марта 2011

Я бы хотел использовать переменную типа $ GET [name], которая всегда выводит безопасную для MySQL версию $ _GET [name], даже если значение $ GET [name] изменяется где-то в скрипте.

Итак:

$_GET[name] = "Timmy O'Toole";
echo $GET[name]; // Timmy O\'Toole
$_GET[name] = "Tommy O'Toole"; 
echo $GET[name]; // Tommy O\'Toole

Это выполнимо?Если нет, можете ли вы придумать какой-нибудь другой способ, который может работать, который не включает фактический вызов функции?(Я хотел бы иметь возможность использовать переменные внутри строк и автоматически оценивать их, а не выполнять много конкатенации.)

Обновление:

Я использовал версию решения Марио, и она, кажется, работает:

// Assume $_REQUEST['name'] = "Timmy O'Toole";

class request_safe_vars IMPLEMENTS ArrayAccess {
    var $array = array();
    function offsetGet($varname) {
        return mysql_real_escape_string($_REQUEST[$varname]);        
    }
    function offsetSet($name, $value) { }  
    function offsetUnset($name) { }
    function offsetExists($name) { }
}  

$REQUEST = new request_safe_vars();

$_REQUEST['name'] = $_REQUEST['name'].' MODIFIED';

$query = "SELECT id FROM user WHERE name = '{$REQUEST['name']}'";  

// Query output:
// SELECT id FROM user WHERE name = 'Timmy O\'Toole MODIFIED'

Ответы [ 3 ]

3 голосов
/ 13 марта 2011

Вы не хотите этого делать.

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

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

$statement = $pdo->prepare('SELECT id FROM users WHERE name = ?');
$statement->execute(array( $_GET['name'] ));
if($statement->rowCount() > 0) {
    echo "I found you!";
} else {
    echo "You don't exist. :(";
}

Подготовленные операторы с заполнителями и связыванием являются наиболее разумным и безопасным способом обеспечения защиты SQL от атак.

1 голос
/ 13 марта 2011

Это выполнимо с объектом, который реализует ArrayAccess. Превратив $ GET в объект, вы можете использовать магический метод offsetSet и offsetGet, который может выполнить это.

class safe_vars IMPLEMENTS ArrayAccess {
    var $array = array();

    function offsetGet($varname) {
        return mysql_real_escape_string($this->array[$varname]);
    }

    function offsetSet($name, $value) {  
        $this->array[$name] = $value;
    } 

    function offsetUnset($name) {  }
    function offsetExists($name) {  }
}  

Вот как вы бы это использовали:

$GET = new safe_vars();
$GET["name"] = "Timmy O'Toole";
echo $GET["name"]; // Timmy O\'Toole    

На самом деле у меня есть нечто подобное (но никогда не реализовывало часть set), которое специально работает на $_GET (как указано в вашем вопросе). http://sourceforge.net/p/php7framework/svn/60/tree/trunk/php7/input.php?force=True - Например, можно настроить применение фильтра sql по умолчанию. Хотя этот подход немного напоминает magic_quotes, даже если он использует правильную экранирующую функцию.

0 голосов
/ 13 марта 2011

Во-первых, ставьте кавычки вокруг имени, если вы намеренно не определяете его как константу.

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

function get($key) {
   return isset($_GET[$key]) : mysql_real_escape_string($_GET[$key]) : null;
}

Проблема с определением класса (если вы используете его только статически) состоит в том, что это лишает $_GET его суперглобального статуса, и вы вынуждены использовать либо глобальные (зло), либо передавать все аргументы get локальным замыканиям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...