Невозможно связать строку, содержащую @ char, с помощью mysqli_stmt_bind_param - PullRequest
2 голосов
/ 29 мая 2010

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

$types = "ss" and $parameters = array("email@domain.com", "testtest")

Я получаю ошибку:

Предупреждение: параметр 3 к mysqli_stmt_bind_param () ожидается быть ссылкой, значение, указанное в ... db / Database.class.php в строке 63

Вот метод:

private function bindAndExecutePreparedStatement(&$statement, $parameters, $types) {
    if(!empty($parameters)) {
        call_user_func_array('mysqli_stmt_bind_param', array_merge(array($statement, $types), &$parameters));
        /*foreach($parameters as $key => $value) {
            mysqli_stmt_bind_param($statement, 's', $value);
        }*/
    }

    $result = array();

    $statement->execute() or debugLog("Database error: ".$statement->error);

    $rows = array();

    if($this->stmt_bind_assoc($statement, $row)) {
        while($statement->fetch()) {
            $copied_row = array();
            foreach($row as $key => $value) {
                if($value !== null && mb_substr($value, 0, 1, "UTF-8") == NESTED) { // If value has a nested result inside
                    $value = mb_substr($value, 1, mb_strlen($value, "UTF-8") - 1, "UTF-8");
                    $value = $this->parse_nested_result_value($value);
                }
                $copied_row[$ke<y] = $value;
            }
            $rows[] = $copied_row;
        }
    }

    // Generate result
    $result['rows'] = $rows;
    $result['insert_id'] = $statement->insert_id;
    $result['affected_rows'] = $statement->affected_rows;
    $result['error'] = $statement->error;

    return $result;
}

Я получил одно предположение, что:

array_merge является параметром приведения в строку слияния изменить его на & $ параметры, так что он остается ссылкой

Итак, я попробовал это (3-я строка метода), но это ничего не изменило.

Как мне быть? Есть ли лучший способ сделать это без call_user_func_array?


обновление: Я нашел менее симпатичный способ решения этой проблемы. Я создал новый ссылочный массив с циклом и использовал его вместо этого.

private function bindAndExecutePreparedStatement($statement, $parameters, $types)
{
    if(!empty($parameters)) {
        $parameters_references = array();
        foreach($parameters as $key => $parameter) {
            $parameters_references[] = &$parameters[$key]; 
        }
        call_user_func_array('mysqli_stmt_bind_param', 
            array_merge(array($statement, $types), $parameters_references)); 
    } 
    .... 

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

1 Ответ

1 голос
/ 29 мая 2010

Я написал код привязки параметров в адаптере MySQLi Zend Framework. Я считаю, что API привязки параметров для MySQLi трудно использовать. Ссылка должна быть не на массив, а на каждый элемент массива.

Вы можете увидеть код, который я написал в методе _execute() в этом классе: http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Db/Statement/Mysqli.php

Я рекомендую вам проверить PDO. Это гораздо проще в использовании. Вы можете связать параметры, но еще проще просто передать массив значений параметров в виде массива в метод execute() PDOStatement.

...