Я работаю с чужой связью с PHP, которая работает отлично, пока я передаю ей как минимум три аргумента. Если я передам ему два аргумента, тогда в протоколе apache говорится:
mysql_real_escape_string() expects parameter 2 to be resource, null given
Мне нужна функция для выполнения SQL-запроса:
$sql = DatabaseManager::prepare("SELECT * FROM sometable WHERE somevar = %d", $var);
и подготовьте его для безопасного выполнения. Может ли кто-нибудь помочь ему принять два аргумента?
public static function prepare($query = null) { // ( $query, *$args )
$args = func_get_args();
array_shift($args);
// If args were passed as an array (as in vsprintf), move them up
if ( isset($args[0]) && is_array($args[0]) ){
$args = $args[0];
}
$query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
$query = str_replace('"%s"', '%s', $query); // doublequote unquoting
$query = str_replace('%s', "'%s'", $query); // quote the strings
for($i=0; $i<count($args); $i++){
$args[$i] = mysql_real_escape_string($args[$i], self::$currentCon);
}
//array_walk($args, array(&$this, 'mysql_real_escape_string'));
return @vsprintf($query, $args);
}
Спасибо, тонна!
ИЗМЕНИТЬ
Как отмечается в deceze, это примерно self::$currentCon)
и означает, что соединение с базой данных возвращается null
Я пробовал это несколько раз. Все еще интересно, почему это работает:
$sql = DatabaseManager::prepare("SELECT * FROM sometable WHERE id = ".$somevar);
но это не удается:
$sql = DatabaseManager::prepare("SELECT * FROM sometable WHERE somevar = %d", $var);
Как это повлияет на self::$currentCon)
?
mysql_real_escape_string() ожидает, что параметр 2 будет ресурсом, null задан
Это совершенно другая проблема, чем количество аргументов, которые принимает функция. Прочтите еще раз:
mysql_real_escape_string()
ожидает, что параметр 2 будет ресурсом,null
указан
Он ссылается на эту строку:
mysql_real_escape_string($args[$i], self::$currentCon);
Второй параметр для mysql_real_escape_string
, т.е. self::$currentCon
, должен быть ссылкой (ресурсом) на открытое соединение MySQL. В этом случае, хотя это было null
.
Это означает, что есть некоторая проблема с self::$currentCon
. Либо возникает проблема в коде, который устанавливает self::$currentCon
, либо данные конфигурации вашей базы данных (имя пользователя, пароль, сокет и т.д.) Неправильны и невозможно установить соединение с базой данных, следовательно self::$currentCon
есть null
.
Эта проблема должна была быть поймана намного раньше, в то время, когда должно было быть установлено соединение с базой данных, но автор, похоже, является фанатом подавления ошибок, поэтому проблема проявляется здесь.
Мораль истории:
:)
$args
, цикл for (...) { ... }
вообще не будет запущен, поэтому mysql_real_escape_string
никогда не вызывается. Этот цикл запускается столько раз, сколько есть (лишних) аргументов.
Возможно, это только я, я бы написал функцию, подобную этой
public static function prepare($query = null,$args = array()) {
$query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
$query = str_replace('"%s"', '%s', $query); // doublequote unquoting
$query = str_replace('%s', "'%s'", $query); // quote the strings
foreach($args as $key=>$arg){
$args[$key] = mysql_real_escape_string($arg, self::$currentCon);
}
//array_walk($args, array(&$this, 'mysql_real_escape_string'));
return @vsprintf($query, $args);
}
Я не тестировал его. Я не понимаю, почему функция использует func_get_args()
и array_shift()
, а затем проверяет, был или нет второй аргумент. Это кажется слишком сложным, по крайней мере для меня
Вам нужно 1 параметр ($ query);
DatabaseManager::prepare("SELECT * FROM sometable WHERE somevar = %d", $var);