Как создать ошибку сообщения о неоднозначных именах столбцов? - PullRequest
2 голосов
/ 05 ноября 2011

В последнее время я часто использую CodeIgniter с методами массива для запроса данных: обычно result_array() или row_array() методы БД.Я заметил ошибку, которая иногда происходит без уведомлений об ошибках (старый код - не мой - я просто исправляю ошибку).Это типичная проблема с неоднозначными именами столбцов, которая много раз размещалась здесь в StackOverflow.

Например: PHP & MYSQL: Как разрешить неоднозначные имена столбцов в операции JOIN?

С CodeIgniter, нет сообщения об ошибке неоднозначного поля.Массив заполняется как обычно именами полей;двусмысленно или нет.Есть ли способ предотвратить это изнутри CodeIgnitier, отображая или регистрируя сообщение об ошибке?

У кого-нибудь есть идеи о том, как записать сообщение об ошибке (возможно, с использованием CI log_message()) в PHP при возникновении неоднозначных полей?

1 Ответ

2 голосов
/ 10 ноября 2011

Это возможно. Причина, по которой CI не выдает ошибки SQL в связи с неоднозначными именами столбцов, заключается в том, что при его выборе добавляется имя таблицы, например

SELECT `table`.`name`, `table2`.`name` FROM `table`, `table2` ...

Причина, по которой вы не видите эти столбцы, заключается в том, что ключ массива, сгенерированный mysqli_fetch_assoc() или драйвером, который вы используете, равен name для обоих и, очевидно, перезаписывается. Следующий ответ подходит для тех, кто использует CI2.x.

Расширить класс результата драйвера базы данных аналогично тому, как это было в моем ответе на CodeIgniter: SQL-аудит всех вызовов метода $ this-> db-> query ()? . После расширения класса результата драйвера базы данных у вас есть два варианта. Вы можете выдать ошибку, как вы просили, следующим образом:

/**
 * Result - associative array
 *
 * Returns the result set as an array
 *
 * @access  private
 * @return  array
 */
function _fetch_assoc()
{
    if (!($row = mysql_fetch_array($this->result_id)))
    {
        return null;
    }

    $return = array();
    $row_count = mysql_num_fields($this->result_id);

    for($i = 0; $i < $row_count; $i++)
    {
        $field = mysql_field_name($this->result_id, $i);

        if( array_key_exists( $field, $return ) ) {
            log_message('Error message about ambiguous columns here');
        } else {
            $return[$field] = $row[$i];
        }
    }

    return $return;

    //Standard CI implementation
    //return mysql_fetch_assoc($this->result_id);
}

Или, в качестве альтернативы, вы можете дополнительно манипулировать выводом функции для имитации поведения запроса, добавляя tablename_ к имени столбца, в результате чего получается массив, подобный

SELECT * FROM `users` LEFT JOIN `companies` ON `users`.`id` = `companies`.`id`
Array (
    [users_id] => 1
    [users_name] => User1
    [companies_id] => 1
    [companies_name] => basdasd
    [companies_share_price] => 10.00
)

Для этого вы можете просто изменить цикл for в вышеприведенной функции следующим образом:

for($i = 0; $i < $row_count; $i++)
{
    $table = mysql_field_table($this->result_id, $i);
    $field = mysql_field_name($this->result_id, $i);
    $return["$table_$field"] = $row[$i];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...