Функция getPaginationCount() не работает в Laravel’s Eloquent ORM

#php #laravel #eloquent

#php #laravel #красноречивый

Вопрос:

Я вытаскиваю модуль Eloquent, чтобы использовать его отдельно, но у меня есть доступ к функциям QueryBuilder. Все они работают, кроме этого.

Когда я запускаю count() и getPaginationCount() , count() возвращает правильное значение, но getPaginationCount() просто возвращает объект IlluminateDatabaseEloquent Builder, как если бы я не командовал запуском запроса. Тем не менее, я вижу 2 запроса в журнале запросов, и, как ни странно, они оба выполняют один и тот же запрос.

 require 'vendor/autoload.php';  

use IlluminateDatabaseCapsuleManager as Capsule;  

$capsule = new Capsule;

$capsule->addConnection(array(
    'driver'    => 'mysql',
    'host'      => TECHDB_HOST,
    'database'  => TECHDB_DBNAME,
    'username'  => TECHDB_USER,
    'password'  => TECHDB_PASS,
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => ''
));

$capsule->bootEloquent();


class Indicator extends IlluminateDatabaseEloquentModel {
    public $timestamps = false;
    public $table = "indicator_performance";
}

$query = Indicator::where('symbol', '=', 'IBM')->forPage(1,2);

var_dump($query->count()); //Correctly prints '13'

var_dump($query->getPaginationCount()); //dumps the 'IlluminateDatabaseEloquentBuilder' object
  

Вот журнал запросов:

 array (size=2)
  0 => 
    array (size=3)
      'query' => string 'select count(*) as aggregate from `indicator_performance` where `symbol` = ? limit 2 offset 0' (length=93)
      'bindings' => 
        array (size=1)
          0 => string 'IBM' (length=3)
      'time' => float 4.85
  1 => 
    array (size=3)
      'query' => string 'select count(*) as aggregate from `indicator_performance` where `symbol` = ? limit 2 offset 0' (length=93)
      'bindings' => 
        array (size=1)
          0 => string 'IBM' (length=3)
      'time' => float 4.24
  

Редактировать:

Кажется, я обнаружил более общую ошибку с count() функцией при использовании после forPage() вызова. Взгляните на эти результаты:

 $query = Indicator::where('symbol', '=', 'IBM');

var_dump($query->count()); //Correctly returns '13'
var_dump($query->forPage(0, 5)->count()); //Correctly returns '13'
var_dump($query->forPage(1, 5)->count()); //Correctly returns '13'
var_dump($query->forPage(2, 5)->count()); //Returns null. Should return '13' or '3', depending on implementation.
  

Комментарии:

1. Что произойдет, если вы не запустите count() , а просто запустите getPaginationCount() ? Я не знаю наверняка, но, возможно count() , каким-то образом изменяет текущее состояние запроса, что сбивает с толку количество страниц.

2. К сожалению, удаление count() не меняет результаты.

Ответ №1:

Есть 2 проблемы с вашим кодом (и Laravel):

  1. getPaginationCount() вызываемый в Eloquent Builder запускает метод (в классе Query Builder), но не возвращает его результат. Вместо этого он возвращает себя как $this .

  2. getPaginationCount() не сбрасывается limit и offset не выполняется запрос для получения количества, что, я полагаю, является ошибкой. Это приводит к возврату null всякий раз, когда смещение установлено на что-либо большее, чем 1. forPage($page) будет делать это для $page > 1 .

При этом я предлагаю вам либо использовать count() вместо getPaginationCount() или:

 // first get the count
$count = $query->getQuery()  // get the base Query Builder directly
    ->getPaginationCount();  // in order to return the count

// then use forPage
$query->forPage(1,5);
  

Комментарии:

1. Возможно, я неправильно интерпретирую назначение getPaginationCount() функции, но я думал, что она должна возвращать количество записей, возвращаемых на странице. Если вы сделаете свой forPage() вызов после getPaginationCount() , он не вернет количество для правильной страницы. Например. если у вас 13 записей и размер страницы 5, количество для 3-й страницы должно быть 3.

2. Кажется, я обнаружил более общую ошибку с count() функцией при использовании после forPage() . Взгляните на мою правку в OP.

3. Да, но это более общее, а не только после forPage . Это касается любой ситуации, когда в запросе задано смещение.