2015-05-16 20 views
5

ile sınırlayın Apigiliteye sahip bir API bağlı API oluşturdum. Şimdilik standart oluşturma taslaklarını kullanıyorum. Benim PostResource içinde fetchAll($params = array()) adlı bir yöntem var. bu sonuçların bir paginatable kümesi döndüren böylece yönteminin kodunu yarattı: Bu ince şimdiye kadar çalışırSonuçları Apigilite

/** @var HydratorInterface $hydrator */ 
$hydrator = new \Zend\Stdlib\Hydrator\ClassMethods(); 

/** @var PostService $postService */ 
$postService = new PostService(); 

$posts = $postService->findAll(/* Limit, default 10 */); 
$apiData = array(); 
foreach ($posts as $post) { 
    $apiData[] = $hydrator->extract($post); 
} 
return new Paginator(new ArrayAdapter($apiData)); 

. API URL'sine gidersem, DB verilerimin sayfalanmış bir json gösterimine sahip olurum. API'm için sayfa boyutunu 5 olarak ayarladıysam 2 sayfa ve 5 sonuç verir. Çok uzak çok iyi. Sorun şu ki, her çağrıda (sayfa 1 veya sayfa 2) tüm 10 sonuç DB'den alınacaktır. Yalnızca bir sayfada 5 döndürür ancak 10 tane hidratlanır.

Bir sınır kullanmanın bir yolu var mı ama aynı zamanda Apigilite veya paginatörün bilmesini sağlayın, toplamda ne kadar sonuç olduğunu ve böylece 5 satır alacağım sayfalama?

+1

Belki bir göz atın 'DbSelect' paginator adaptörü? -> http://framework.zend.com/manual/current/en/modules/zend.paginator.usage.html#the-dbselect-adapter – Crisp

+0

Varsayılan koleksiyonlar 'Zend \ Paginator \ Paginator' öğesini genişletir; Standart taslakları kullanıyorsunuz, tanımladığınız davranış görünmemelidir. Çağrı zinciriniz nasıl görünür? Bunun gibi: FooResource # fetchAll (...) -> FooService # getBar (...) -> FooMapper # findAll (...) '? FooMapper # findAll (...) '' FooCollection'ı döndürüyor mu? 'findAll ($ params = array()) { \t $ select = $ this-> getSelect(); \t $ select-> burada (...); \t $ paginatorAdapter = $ this-> createPaginationAdapter ($ select); \t $ collection = new FooCollection ($ paginatorAdapter); \t iade $ koleksiyonu; } ' – automatix

cevap

4

Tam olarak bilmiyorum, verileri nasıl alıyorsunuz, ancak aşağıdaki yaklaşım şu şekilde çalışıyor: Çağrı zinciri AddressResource#fetchAll(...) -> AddressService#getBar(...) -> AddressMapper#findAll(...) gibi görünüyor ve veri alma yöntemi Collection nesnesini döndürüyor.

AddressResource.php

... 

class AddressResource ... { 

    ... 

    public function fetchAll($params = array()) { 
     $service = $this->getAddressService(); 
     $collection = $service->getAddresses($params->toArray()); 
     return $collection; 
    } 

    ... 

} 

AddressService.php

... 

class AddressService ... { 

    ... 

    public function getAddresses($params = array()) { 
     $collection = $this->getMapper()->findAll($params); 
     return $collection; 
    } 

    ... 

} 

AddressMapper.php

... 

class AddressMapper extends AbstractDbMapper { 

    ... 

    public function findAll($params = array()) { 
     $select = $this->getSelect(); 
     $select->where(
      ... 
     ); 
     $paginatorAdapter = $this->createPaginationAdapter($select); 
     $collection = new AddressCollection($paginatorAdapter); 
     return $collection; 
    } 

    ... 

} 

AddressCollection.php

module.config.php

return array(
    ... 
    'zf-rest' => array(
     ... 
     'AddressBookAPI\\V1\\Rest\\Address\\Controller' => array(
      ... 
      'page_size' => 5, 
      ... 
     ), 
     ... 
    ), 
    ... 
); 

... 

use Zend\Paginator\Paginator; 

class AddressCollection extends Paginator { 
} 

Şimdi bir test: Ben /addresses arama ve MySQL sorgu kaydını gözlemliyorum:

$ tail -f /var/log/mysql_query.log 

... 

3 Connect [email protected] on address-book-api 
3 Query  SET NAMES 'UTF8' 
3 Query  SELECT COUNT(1) AS `C` FROM (SELECT `addresses`.* FROM `addresses`) AS `original_select` 
3 Query  SELECT `addresses`.* FROM `addresses` LIMIT 5 OFFSET 0 
3 Quit 

...