Функция не примет менее трех аргументов

0

Я работаю с чужой связью с 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)?

  • 0
    Пожалуйста, приведите пример того, как бы вы вызывали эту функцию только с одним аргументом. Кажется, что изменение, которое вы ищете, не соответствует цели функции.
  • 0
    @ Джефф, правда. Много извинений за плохую формулировку. Я имею в виду один дополнительный аргумент для запроса SQL. Я отредактировал свой пост, чтобы уточнить. Но пока это займет всего три аргумента (включая запрос SQL) или более
Показать ещё 2 комментария
Теги:

3 ответа

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

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.

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

Мораль истории:

  • Всегда читайте сообщения об ошибках три раза.
  • Всегда указывайте точное сообщение об ошибке при задании вопроса.
  • Не подавлять ошибки.

:)

  • 0
    спасибо @ deceze! это имеет смысл, и я последую этому примеру ... Однако соединение с базой данных работает, если я ее кормлю: $ sql = DatabaseManager :: prepare ("SELECT * FROM sometable WHERE id =". $ somevar); но терпит неудачу, когда я передаю его $ sql = DatabaseManager :: prepare ("SELECT * FROM sometable WHERE somevar =% d", $ var); Есть причина для этого?
  • 1
    @ Эмиль Да. Если вы не предоставите никаких дополнительных $args , цикл for (...) { ... } вообще не будет запущен, поэтому mysql_real_escape_string никогда не вызывается. Этот цикл запускается столько раз, сколько есть (лишних) аргументов.
Показать ещё 1 комментарий
1

Возможно, это только я, я бы написал функцию, подобную этой

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(), а затем проверяет, был или нет второй аргумент. Это кажется слишком сложным, по крайней мере для меня

  • 0
    Спасибо @pleasedontbelong ... Мои первые шаги в PHP, так что простите меня за незнание, но в моем журнале apache написано "Недопустимый аргумент для foreach ()`, когда я запускаю код, используя вашу функцию. (Хотя вы и избавились от последнего сообщение об ошибке :) Есть идеи?
  • 1
    ну .. читая другие ответы и журнал apache, я думаю, что это не проблема, поэтому @deceze может быть прав. Но просто для справки: если вы используете функцию, как я написал здесь, вам придется вызывать функцию по-другому ... что-то вроде этого prepare ("SELECT ...", array ($ var1, $ var2 ,. ..)); ... в любом случае .. используйте свой оригинальный код и проверьте параметры, переданные функции mysql_real_escape_string ()
Показать ещё 1 комментарий
0

Вам нужно 1 параметр ($ query);

DatabaseManager::prepare("SELECT * FROM sometable WHERE somevar = %d", $var);
  • в этом коде вы даете 2 параметра для работы.
  • 0
    очень хороший момент @ Александр ... Спасибо за помощь в разъяснении моего вопроса. Я имею в виду, что это не займет 1 дополнительный параметр. Таким образом, включая SQL-запрос, он не займет ничего, кроме трех параметров. Я отредактировал свой вопрос, чтобы уточнить.

Ещё вопросы

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