Структура массива необработанных результатов SQL-запроса в CakePHP 3.8 / CakePHP 4 против CakePHP 2

После выпуска CakePHP 4.0 мы рассматриваем возможность переноса нашего приложения CakePHP 2.x на версии 3.8 или 4.0. В настоящее время мы застряли с этой проблемой:

Наше приложение использует необработанные операторы SQL, иногда используя Model::query() метод.


Например, этот код CakePHP 2:

$sql = "SELECT u.id, u.firstname FROM users u, contacts c WHERE u.id = 2 and c.id = u.contact_id";
$u = $this->User->query($sql);  // Or on any other model...
$this->log($u);

возвращается

Array
(
    [0] => Array
        (
            [u] => Array
                (
                    [id] => 2
                    [firstname] => MyFirstName
                )
            [c] => Array
                (
                    [zip] => 12345
                )

        )
)

Когда мы пытаемся сделать то же самое с CakePHP 3.8

$connection = ConnectionManager::get('default');
$sql = "SELECT u.id, u.firstname FROM users u, contacts c WHERE u.id = 1 and c.id = u.contact_id";
$u = $connection->execute($sql)->fetchAll();
$this->log($u);

результат

Array
(
    [0] => Array
        (
            [0] => 2
            [1] => MyFirstName
            [2] => 12345
        )
)

Для безопасной миграции: есть ли способ заставить CakePHP 3.8/4 возвращать результаты запроса, используя ту же структуру массива, что и в CakePHP 2?

Переписывать операторы для использования ORM не вариант. Приведенный выше пример не является реальным кодом — настоящие запросы более сложны.


person anweibel    schedule 20.12.2019    source источник


Ответы (1)


Согласно документации, вы должны использовать ->fetchAll('assoc'). Вывод не совсем идентичен тому, что был в Cake 2, но, по крайней мере, имена полей присутствуют.

person Greg Schmidt    schedule 21.12.2019
comment
Формат 2.x действительно уродлив. Если необходимо выполнить пошаговую миграцию, можно реализовать нечто подобное в 3.x/4.x, см. реализации DboSource::resultSet() и DboSource::fetchResult() в драйверы базы данных 2.x. - person ndm; 21.12.2019
comment
Точно. Как я уже сказал, это не идентично, но имена полей есть. Переход с версии 2.x на версию 3.x является серьезной задачей. - person Greg Schmidt; 08.01.2020
comment
Спасибо @greg-schmidt. Когда я использую ->fetchAll('assoc'), hard, результат выглядит следующим образом: Array ( [0] => Array ( [id] => 2 [firstname] => MyFirstName [zip] => 12345 ) ) Это содержит имена полей, но по-прежнему пропускает псевдонимы таблиц... @ndm Кажется слишком громоздким переписывать драйверы базы данных 4.x, чтобы сделать это Работа. Возможно, мы просто побудем с 2.x немного дольше. Уродство, как и красота, в глазах смотрящего... :-) - person anweibel; 08.01.2020
comment
Жаль, что вы не можете использовать новую ORM так, как она предназначена. Это действительно вещь красоты. - person Greg Schmidt; 08.01.2020
comment
@GregSchmidt У меня сложилось впечатление, что нам нужно будет переписать все наше приложение, чтобы адаптироваться к новому ORM. Поскольку структура объекта данных изменилась, это будет применяться не только к моделям, но также к контроллерам и представлениям... - person anweibel; 08.01.2020
comment
Я согласен с @GregSchmidt, ORM действительно хорош. Также для будущих обновлений, отладки и т. д. Я бы рекомендовал рассмотреть возможность использования ORM. - person LinkinTED; 10.01.2020