Repository navigation
Version 5.2.0
Готовность к PHP 8.6
PHP 8.6 объявляет устаревшими SplFileObject::fgetcsv(), fputcsv(),
setCsvControl() и getCsvControl(). Csv — единственное, ради чего orm вообще
открывал файл, поэтому SplFileObject из пакета убран целиком.
На его месте MotorORM\CsvFile — SeekableIterator поверх обычного
дескриптора. Разбор csv остался за движком: процедурные fgetcsv() и
fputcsv() депрекейт не затрагивает.
Читает быстрее
Строки таблицы отдаёт генератор поверх fgetcsv, а не SplFileObject,
завёрнутый в LimitIterator и CallbackFilterIterator. Строка стоит одно
возобновление генератора вместо вызова каждого метода трёх итераторов.
На 50 000 строк, против того же кода на голом php:
| операция | было | стало |
|---|---|---|
| выбрать строки по условию | ×1.24 | ×1.07 |
| обойти всю таблицу | ×1.38 | ×1.23 |
| десять последних с сортировкой | ×0.80 | ×0.73 |
На 500 000 строк: cursor() 890 → 785 мс, count() 633 → 551 мс,
paginate(10) 638 → 556 мс.
Ломающие изменения
Model::file(), Model::createFile() и Table::file() возвращают CsvFile.
Csv-контроль теперь в конструкторе, а не в сеттере.
// 5.1
$file = $model->file(); // SplFileObject
// 5.2
$file = $model->file(); // MotorORM\CsvFile
$file->fputcsv(['id', 'title']); // вызов тот же
foreach ($file->rows(1) as $line => $row) {} // без заголовка, номер строки => строка
Table::rewrite() отдаёт замыканию номер строки, а не читаемый файл.
// 5.1
$table->rewrite(function (array &$current, SplFileObject $target, SplFileObject $source) {
if ($source->key() === 0) { /* заголовок */ }
});
// 5.2
$table->rewrite(function (array &$current, CsvFile $target, int $line) {
if ($line === 0) { /* заголовок */ }
});
paginate() и simplePaginate() больше не принимают страницу. Страницу
называет page() или берёт из ?page= запроса.
// 5.1
Article::query()->paginate(10, (int) ($_GET['page'] ?? 1));
// 5.2
Article::query()->paginate(10); // страница из запроса
Article::query()->page(3)->paginate(10); // страница названа явно
setPageName() стал статическим и ничего не возвращает. Имя параметра
нужно знать до того, как появится страница строк, поэтому оно не может
принадлежать этой странице.
// 5.1
$articles->setPageName('p')->links();
// 5.2
Pagination::setPageName('p');
Добавлено
- Query::page() — страница пагинации, названная явно.
- PagedCollection::resolvePageUsing() — откуда берётся текущая страница.
Замыканию передаётся имя параметра, null возвращает чтение из query string.
- PagedCollection::resolveCurrentPage() — запрошенная страница, никогда
ниже первой.
- PagedCollection::pageName() — имя параметра страницы.
- with() принимает замыкание на связь. Связь, названная ключом замыкания,
сужается для одного этого чтения — как constrain() сужает каждое. Если есть
оба, условия складываются, объявленное первым.
Story::query()
->with([
'user',
'comments' => static fn (Query $query) => $query->where('approved', 1),
])
->get();
Обновление
composer require visavi/motor-orm:^5.2
Требуется PHP 8.5+. Формат файлов таблиц не менялся — миграция данных не нужна.