call_user_func_array со ссылками - PullRequest
       11

call_user_func_array со ссылками

1 голос
/ 12 ноября 2011

Я в основном пытаюсь вызвать mysqli :: bind_param через call_user_func_array.

Вот моя функция:

function Insert($table, $values=array(), $flags=0) {
    $field_count = count($values);

    if($field_count > 0) {
        $fields = implode(',',array_keys($values));
        $placeholders = implode(',',array_repeat('?',$field_count));
    } else {
        $fields = '';
        $placeholders = '';
    }

    if($flags > 0) {
        $flag_arr = array();
        if($flags & self::LOW_PRIORITY) $flag_arr[] = 'LOW_PRIORITY';
        if($flags & self::DELAYED) $flag_arr[] = 'DELAYED';
        if($flags & self::HIGH_PRIORITY) $flag_arr[] = 'HIGH_PRIORITY';
        if($flags & self::IGNORE) $flag_arr[] = 'IGNORE';
        $flags_str = implode(' ',$flag_arr);
    } else {
        $flags_str = '';
    }

    $sql = "INSERT $flags_str INTO $table ($fields) VALUES ($placeholders)";
    $stmt = $this->mysqli->prepare($sql);
    if($stmt === false) {
        throw new Exception('Error preparing MySQL statement.<br/>MSG: '.$this->mysqli->error.'<br/>SQL: '.$sql);
    }

    if($field_count > 0) {
        $types = '';
        foreach($values as $val) {
            if(is_int($val)) $types .= 'i';
            elseif(is_float($val)) $types .= 'd';
            elseif(is_string($val)) $types .= 's';
            else $types .= 'b';
        }
        $params = array_merge(array($types),array_values($values));
        call_user_func_array(array($stmt,'bind_param'),$params);
    }

    $stmt->execute();
    return $stmt;
}

Проблема возникает в строке call_user_func_array. Я получаю эту ошибку:

Параметр 2 для mysqli_stmt :: bind_param () должен быть ссылкой, задано значение

Я понимаю проблему, я просто не знаю, как ее обойти.

Например, функция может быть вызвана так:

$db->Insert('pictures',array('views'=>1));

И var_dump($params) даст следующее:

array
  0 => string 'i' (length=1)
  1 => int 1

Итак, есть ли способ вызвать mysqli::bind_param с переменным количеством аргументов или каким-то образом превратить мой массив в ссылки?

1 Ответ

5 голосов
/ 12 ноября 2011

Второе примечание на странице руководства для mysqli_stmt :: bind_param () сообщает:

Необходимо соблюдать осторожность при использовании mysqli_stmt_bind_param () в сочетании с call_user_func_array (). Обратите внимание, что mysqli_stmt_bind_param () требует, чтобы параметры передавались по ссылке, тогда как call_user_func_array () может принимать в качестве параметра список переменных, которые могут представлять ссылки или значения.

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

Редактировать: Оказывается, есть пара SO вопросов по этому вопросу.

...