Symfony

PropelのページネーションとCriteriaを使ったSQLの演算子の使用例

この記事は約9分で読めます。
スポンサーリンク

PHPフレームワークのSymfonyのバージョンはこの記事を執筆した時点で7.1.4がリリースされています。composerでのパッケージ管理により便利な機能が簡単に実装できる利便性の高さは評価できますが、開発したアプリケーションに対して各パッケージの詳細まで把握する事は滅多にありませんが運用上、「把握していない」、「知らない」はあってはならない事からパッケージ管理ツールが出回る以前の古いバージョンも今なお一定の人気があります。

ここではSymgony1.0.17をベースにデータベースを参照したページネーション機能とデータベースへの参照問合せで頻繁に使用する演算子の使用例について紹介します。

スポンサーリンク

ページネーション

アクションクラスへメソッドの追加

アクションクラスへ次のメソッドを追加します。

  // 省略  

  public function executeList()
  {
    $c = new Criteria();
    $c->add(ProductPeer::<カラム名>, <値>, <演算子(クラスメゾット)>);
    $c->addDescendingOrderByColumn(ProductPeer::NAME);

    $pager = new sfPropelPager('Product', <表示させる件数>);
    $pager->setCriteria($c);
    $pager->setPage($this->getRequestParameter('page', 0));
    $pager->init();

    $this->pager = $pager;
  }

改ページリンクの作成

次にページャーリンクの関数を用意します。

アプリケーションディレクトリ内のlibディレクトリ内にhelperディレクトリを作成し次のファイルを作成します。

作成ファイル:PagerHelper.php

<?php

function pager_navigation($pager, $uri, $num = 8, $attach= '')
{
  $navigation = '';

  if ($pager->haveToPaginate())
  {
    $uri .= (preg_match('/\?/', $uri) ? '&' : '?');
    $uri .= 'page=';

    if($num + 1 < $pager->getPage()){
      $navigation .= '<li>'.link_to('<<', $uri.'1').'</li>';
    }
    if ($pager->getPage() > 1){
      $navigation .= '<li>'.link_to('<', $uri.$pager->getPreviousPage()).'</li>';
    }

    $stcnt = ($pager->getPage() <= $num) ? 1 : $pager->getPage() - $num;
    $encnt = ($pager->getPage() > ($pager->getLastPage() - 3)) ? $pager->getLastPage() : $pager->getPage() + $num;
    if($encnt > $pager->getLastPage()){
      $encnt = $pager->getLastPage();
    }

    for($i = $stcnt; $i <= $encnt; $i++)
    {
      if ($i == $pager->getPage()) {
        // if ($page == $pager->getPage()) {
        $navigation .= '<li class="active"><a href="#">'.$i.'</a></li>';
      }else {
        $navigation .= '<li>'.link_to($i, $uri.$i).'</li>';
      }
    }


    if($pager->getPage() <  $pager->getLastPage()){
      $navigation .= '<li>'.link_to('>', $uri.$pager->getNextPage()).'</li>';
    }
    if($pager->getPage() + $num <  $pager->getLastPage()){
      $navigation .= '<li>'.link_to('>>', $uri.$pager->getLastPage()).'</li>';
    }
  }

  return '<ul class="pagination '.$attach.'">'.$navigation.'</ul>';
}

ページ情報(プロパティ)の作成

先程作成したPageHelper.phpに表示しているページが全何件中、何処から何処まで表示しているか表示する機能を追加します。

function pager_infomation($pager, $format = '{total}件中 ({from}~{to}件表示)', $emp = 'Not found.')
{
  $infomation = '';
  if ($pager->getNbResults() > 0 ) {
    $total = $pager->getNbResults();
    if ($total > 0) {
      $from = $pager->getMaxPerPage() * ($pager->getPage()  - 1) + 1;
    }else {
      $from = $pager->getMaxPerPage() * ($pager->getPage()  - 1);
    }
    $to = $pager->getMaxPerPage() * ($pager->getPage()  - 1) + count($pager->getResults());
    $infomation = str_replace('{total}', $total, $format);
    $infomation = str_replace('{from}', $from, $infomation);
    $infomation = str_replace('{to}', $to, $infomation);
  }else {
    $infomation = $emp;
  }
  return $infomation;
}

ビュー(テンプレート)の作成

次はビューファイル(listSuccess.php)の内容です。

<?php use_helper('Pager') ?>
<table>
  <caption><?php echo pager_infomation($pager) ?></caption>
  <thead>
    <th>品名</th>
    <th>状態</th>
    <th>金額</th>
    <th>製造番号</th>
  </thead>
  <tbody>
    <?php foreach($pager->getResults() as $product): ?>
      <tr>
        <th><?php echo $product->getName() ?></th>
        <th><?php echo $product->getStatus() ?></th>
        <th><?php echo $product->getPrice() ?></th>
        <th><?php echo $product->getSerial() ?></th>
      </tr>
    <?php endforeach; ?>
  </tbody>
</table>
<?php echo pager_navigation($pager, '<アクションクラス名>/list') ?>

Propelのページネーションの例は以上です。

SQLの演算子の使用例

次の表に演算子の使用例を紹介します。

SQL文指定方法
WHERE product.STATUS = ‘enable’$c->add(ProductPeer::STATUS, ‘enable’, Criteria::EQUAL);
WHERE product.PRICE > 500$c->add(ProductPeer::Price, 500, Criteria::GREATER_THAN);
WHERE product.PRICE < 500$c->add(ProductPeer::Price, 500, Criteria::LESS_THAN);
WHERE product.PRICE >= 500$c->add(ProductPeer::Price, 500, Criteria::GREATER_EQUAL);
WHERE product.PRICE <= 500$c->add(ProductPeer::Price, 500, Criteria::LESS_EQUAL);
WHERE product.SERIAL LIKE ‘123%’$c->add(ProductPeer::SERIAL, ‘123%’, Criteria::LIKE);
WHERE product.STATUS IN(‘close’, ‘disable’)$c->add(ProductPeer::STATUS. array(‘close’, ‘disable’), Criteria::IN);
WHERE product.STATUS NOT IN(‘close’, ‘disable’)$c->add(ProductPeer::STATUS. array(‘close’, ‘disable’), Criteria::NOT_IN);
OFFSET 25$c->setOffset(25);
LIMIT 25$c->setLimit(25);
ORDER BY product.NAME ASC$c->addAscendingOrderByColumn(ProductPeer::NAME);
ORDER BY product.NAME DESC$c->addDescendingOrderByColumn(ProductPeer::NAME);
WHERE product.MESSAGE IS NULL$c->add(ProductPeer::MESSAGE, null, Criteria::ISNULL);
WHERE product.MESSAGE IS NOT NULL$c->add(ProductPeer::MESSAGE, null, Criteria::ISNOTNULL);
WHERE product.SERIAL REGEXP ‘.+456[0-9]{3}’$c->add(ProductPeer::SERIAL, ” REGEXP ‘.+456[0-9]{3}'”, Criteria::CUSTOM);

スポンサーリンク
Symfony
スポンサーリンク

コメント

タイトルとURLをコピーしました