.ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録

.検索

.メインメニュー

.フォーラムメニュー

.オンライン状況
15 人のユーザが現在オンラインです。 (13 人のユーザが フォーラム を参照しています。)

登録ユーザ: 0
ゲスト: 15

もっと...

.
.リンク集

メイン
   一般的な話題(General)
     条件をつけたpaginateでページ繰りができない
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
macchaka
投稿日時: 2008-6-25 12:35
Baker スタート
登録日: 2008-6-24
居住地:
投稿: 6
条件をつけたpaginateでページ繰りができない
初めてのポストなので、フォーラムカテゴリーが間違っていたらすみません。

PHPすら初心者なのですが、1.2のPaginationで困っています。

第2引数に条件を与えて、表示しようとしているのですが、1ページはきちんと動作するのですが、2ページ目以降に遷移すると、絞り込みが外れて全件が対象になってしまいます。(表示はします)

コードはこんな感じです。

<?php
$where
=array('Dictionary.word_search LIKE'=>$this->data['search_word']);
$this->set('results'$this->paginate('Dictionary',$where));
?>



Dictionaryテーブルのword_searchフィールドの内容を、フォームsearch_wordで得たテキストで検索しています。
第2引数ではなく、paginateのconditionsに引き渡しても同じです。

この指定自体は機能していて、思惑通りの【1ページ目】は表示されます。ただ、他のページを指定して遷移した途端にdata['search_word'](フォームからの値)をロストするためDictionaryテーブルの全件を対象としてしまっているようです。(dataから取らずに条件を決め打ちする分には正常に動作するので)

色々検索して、
http://www.nabble.com/Pagination-td14993402.html
こちらをつたない英語力で解読してみたところ、postした値を使うにはセッションを使えよ、と読めました(笑)

ところが、$this->Session->write(〜)で書き込んでも、遷移した先でread(〜)しても、空っぽになってしまいます。
(書き込みができてると認識したのは、ページ遷移前にセッションからreadしたら取り出せたため)

http://groups.google.com/group/cake-php/browse_thread/thread/c4b30b02adaf4a9f/f71248fa3cb18220
このへんで皆さん、同じ問題にぶつかってるというように読めたのですが、core.phpの設定を変えろと読めたので、セキュリティレベルを下げたり、Session.saveもcakeにしてみましたが変わらず。
同じサーバのCakePHPを使ってない、PHPコードではセッションの保存が使えているので、php.iniの問題でもないだろうなぁとは思っているのですが。

マニュアルを含め、色々なところをググってみたのですが、英語力のなさもあって、答えにたどり着きませんでした。

条件をつけてPaginateするのは普通のことだと思うので、そもそも、セッションを使う云々自体が正しいのかどうかも疑問です。

どうも1.1系と1.2系の情報が混ざって、自分の中で混乱が起きています。

ご存じの方がおられましたら、よろしくお願いいたします。
okage20
投稿日時: 2008-6-26 0:38
Baker スタート
登録日: 2007-2-16
居住地: 群馬県
投稿: 9
Re: 条件をつけたpaginateでページ繰りができない
こんにちは。

PaginatorHelper のメソッドはオプションを配列で受け取れると思うのですが、
"url" というキー名でデータを渡すと、
ページが変わってもそのデータが維持されますので、
そこに絞り込み条件を指定してみてはいかがでしょうか。

名前付きパラメータにするのがおすすめです。

▼コントローラ

<?php
function index()
{
  
$conditions = array();

  if (!empty(
$this->data)) {
    
// 絞り込み条件が変わったときは1ページ目から表示し直す
    
$conditions["Dictionary.title"]    = $this->data["Dictionary"]["title"];
    
$conditions["Dictionary.isbn"]     = $this->data["Dictionary"]["isbn"];
    
$conditions["Dictionary.checkout"] = $this->data["Dictionary"]["checkout"];
  } else if (isset(
$this->params["named"]["filters"])) {
    
// 絞り込み条件が渡ってきたらページングの材料にする
    
$conditions unserialize($this->params["named"]["filters"]);
  }

  
$this->set("results"$this->paginate("Dictionary"$conditions));
  
$this->set("filters", array("url" => "filters:"urlencode(serialize($conditions))));
}
?>



▼ビューテンプレート

<?php
<?php echo $paginator->prev("<< 前へ", array(), nullam($filters, array("class"=>"disabled")));?>
<?php 
echo $paginator->numbers($filters);?>
<?php 
echo $paginator->next("次へ >>", array(), nullam($filters, array("class"=>"disabled")));?>
?>



こんなかんじで。
macchaka
投稿日時: 2008-6-26 14:45
Baker スタート
登録日: 2008-6-24
居住地:
投稿: 6
Re: 条件をつけたpaginateでページ繰りができない
さっそくのご返信ありがとうございます。
試してみたのですが、結果は同じでした。
なんか、configの問題なんでしょうか…。

前回端折ってしまったのですが、プルダウンの選択で条件を変えているので、そのあたりがちょっと例示の通りにはできませんでした。

初心者で赤面なんですが、コードを晒します


<?php
function word()
    {
        
$conditions = array();

        if (!empty(
$this->data)) {
            switch(
$this->data['search_mode']) {
            case 
'sta'//で始まる
                
$str_start='';
                
$str_end='%';
                break;
            case 
'mat'//に一致する
                
$str_start='';
                
$str_end='';
                break;
            case 
'con'//を含む
                
$str_start='%';
                
$str_end='%';
                break;
            case 
'end'//で終わる
                
$str_start='%';
                
$str_end='';
                break;
            }
            
$conditions["Dictionary.word_search LIKE"]=$str_start.$this->data['search_word'].$str_end;
            
//$conditions=array('Dictionary.word_search LIKE'=>$str_start.$this->data['search_word'].$str_end);

        
} else if (isset($this->params["named"]["filters"])) {
            
// 絞り込み条件が渡ってきたらページングの材料にする
            
$conditions unserialize($this->params["named"]["filters"]);
        }

        
$this->set("results"$this->paginate("Dictionary"$conditions));
        
$this->set("filters", array("url" => "filters:"urlencode(serialize($conditions))));
  
        return;
    }
?>



p.s.このサイトのセッション切れの早さって切ないです。調べたり他のことをしながら書いていると、もう2回も文章をロストしてしまいました。。。
macchaka
投稿日時: 2008-6-26 17:31
Baker スタート
登録日: 2008-6-24
居住地:
投稿: 6
Re: 条件をつけたpaginateでページ繰りができない
見落としていました。

numbersで生成されたページナンバーの方には、URLにきちんとfiltersが出てきて、Prev,Nextの方にはURLの中にfiltersが出てこないという状況でした。

なので、ページナンバーを押せば、希望する動作をします。ビューのところの引数で何かミスしているのでしょうか。
見直してみましたが、コピペで入れたので、そのへんのミスではなさそうなのですが。。。
macchaka
投稿日時: 2008-6-30 14:49
Baker スタート
登録日: 2008-6-24
居住地:
投稿: 6
Re: 条件をつけたpaginateでページ繰りができない
その後の状況です。
未だ動かないのは変わっていないのですが、

ご教示いただいた

<?php
php 
echo $paginator->next("次へ >>", array(), nullam($filters, array("class"=>"disabled")));
?>



の部分を
http://bakery.cakephp.org/articles/view/basic-pagination-overview-3
こちらを参考に

<?php
php 
echo $paginator->next("次へ >>", array('url'=>$this->passedArgs));
?>


としてみたのですが、
メソッド名/filters:a:1:{s:20:"Dictionary…}/page:1
を期待するところ、
メソッド名/page:1/filters:a:1:{s:20:
(ダブルコーテーションで切れる)
となってしまい、

<?php
php 
echo $paginator->next("次へ >>", array('url'=>$filters));
?>


としてみたところ、こちらはいいところまでいっているのですが、
メソッド名/page:1/url:filters:a:1:{s:20:"Dictionary…}
と、「url:」がついてしまうために、動作しません。

原理が分からずに手当たり次第にやっている感じなので、どうにも答えに行き着きません。

Prev,NextやNumbersの引数の説明が書かれているところがあるのでしょうか。マニュアルとして、
http://book.cakephp.org/ja/view/166/pagination-in-views
を参照しているのですが、ここではよく分からず、
http://papuh.s3.zmx.jp/2008/01/21/cakephp%EF%BC%9A%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%B3%E3%82%B0%E3%82%92%E8%A9%A6%E3%81%99%EF%BC%92/
こちらで、ようやく理解はしたのですが、これに該当するものをマニュアルで見つけることができていません。

マニュアルでは「こういうときにはこう書く」ということは比較的見つけられるのですが、このファンクションの引数はこういう意味で、そこに与えることができるものはこれが全て、というようなリファレンス的なものを見つけることができていません。
http://api.cakephp.org/
も、うちからではアクセスできず。。。


php初心者なので、フレームワークでラップされる方がコードのクォリティが上がるかなと思ってCakePHPを初めてみたのですが、ページネーション処理ごときでつまづくということは、フレームワークは使うべきではないのでしょうか…(弱気)
shun
投稿日時: 2008-6-30 18:22
Cake 職人
登録日: 2006-7-14
居住地: 東京、日本
投稿: 1007
Re: 条件をつけたpaginateでページ繰りができない
引用:

php初心者なので、フレームワークでラップされる方がコードのクォリティが上がるかなと思ってCakePHPを初めてみたのですが、ページネーション処理ごときでつまづくということは、フレームワークは使うべきではないのでしょうか…(弱気)


いや、ページネーションは相当、複雑ですよ。
特に、今回はページネーション+絞込み、ということですので、一筋縄ではいかないと思います。

まずは、libs/view/helpers/paginator.php を読んでみることをお勧めします。

フレームワークは、基本的な機能だけしか提供していないかもしれませんので、自分の必要な機能がない場合には、オーバーライドしたり、別クラスを作ったりしたほうがよい場合もあります。

ちなみに、1.1の初期にはページネーションそのものの機能が提供されていなかったので、自分で書きました。

http://cakephp.seesaa.net/article/25243275.html

ただ、絞込み機能を付けて表形式にするだけでよい、というのであれば、これでただ焼けばよいので楽かもしれません。インターフェイスは phpMyEdit を参考にしています。
http://www.phpmyedit.org/

新原さんは、PEAR::Pager を使う方法を「CakePHPガイドブック」で説明されています。PEARのほうが良いように思えるなら、そちらでも良いと思います。

ちなみに、PHPの前はJavaとかPerlとか使われていたのでしょうか。「こういう解決方法があればよいのに」と思うような、別言語での仕様・プロジェクトなどがありますか?
macchaka
投稿日時: 2008-7-3 3:03
Baker スタート
登録日: 2008-6-24
居住地:
投稿: 6
解決しました
やはり、海外のサイトにあったように、セッションを使うという流れのようで、そもそもセッションがキープできないことに諸悪の根源がありました。

セッションが切れてしまった原因は、お恥ずかしながら、ソースの最後に空の改行が2行あったことです。冒頭の改行で動かなくなることは認識していましたし、同じような現象で「最後にBOMが付いていたのが原因だった」というやりとりもどこかで見かけていたのですが、まさか2行の空改行でこんなに苦しめられているとは思い至りませんでした。

こちらのヒントの糸口になったのは、
https://trac.cakephp.org/ticket/4235
こちらで、コントローラに埋め込む形でセッションのダンプを表示するというコードを見かけ、これでは正しく表示することが確認できたので、後はつきあわせて詰めていきました。
(今まではよく分からず、printfとかでガリガリやっていたので、参考になりました。)


で、セッションの方が使えるようになりましたので、コードの方も改めてそれを利用する形で、コントローラは次のようにしました。


<?php
if (!empty($this->data)) {
    
//検索フォームからの流れなので、条件をセット
    //前のポストの通り、LIKEで指定する必要があったのでこの形に。
    
$where=array('Dictionary.word_search LIKE'=>$this->data['search_word']);
    
$this->Session->write('where',$where);

} elseif (
$this->Session->check('where')) {
    
//検索フォームからではないが、条件を覚えている場合、セッションから条件を復元
    
$where=$this->Session->read('where');
}

if (!empty(
$where)){
    
$this->set('results'$this->paginate('Dictionary',$where)); 
}
?>



ビューはシンプルです。

<?php
<?php echo $paginator->prev('<<前へ '); ?>
<?php 
echo $paginator->numbers(); ?>
<?php 
echo $paginator->next(' 次へ>>'); ?>
?>




okage20さんに教えていただいた方法では、Prev,Nextを動かすことができなかったのですが、こちらでは動作しています。
コード的に突っ込み箇所があるのはともかくとして、一応動く形にはできました。

okage20さんに教えていただいた方法ではないのですが、あのときにタイムリーにアドバイスいただいたおかげで、一旦上司からの追求をかわすことができ(笑)、首の皮一枚つながった感じで、助かりました。本当にありがとうございました。

今の技量ではよく分からなかったのですが、改めてあのやり方の方も調べてみたいと思います。
macchaka
投稿日時: 2008-7-3 3:21
Baker スタート
登録日: 2008-6-24
居住地:
投稿: 6
Re: 条件をつけたpaginateでページ繰りができない
shunさん、コメントありがとうございます。

paginator.phpは開いてみましたが、クラクラしましたw

自分で作ってオーバーライドというのも、概念は理解できますが、私の技量では、まだまだ。一通り、Cakeの世界を見渡せたところで、取り組んでみたいと思います。


> ちなみに、PHPの前はJavaとかPerlとか使われていたのでしょうか。「こういう解決方法があればよいのに」と思うような、別言語での仕様・プロジェクトなどがありますか?

ディスカスに必要な話ではないかもしれませんが、アレなコードをアップしてしまったので、実情を書いておきます。

実は、Web系はほぼ初めてで、今まではBASICを書いてきました。
ほとんどEUC的なものが中心ですが、データベースはよく使っていて、VBの他、MacのREALbasicという変わり種も使ってきましたので、SQLやらオブジェクト指向やらというのは、それとなくやってきました。

今まで、Web系はパートナーさんに外注していて、コードのチェックとか、ちょっとした改修をしていたのですが、案件が増えてきたので、そろそろ潮時かなと思い(笑)、取り組むことにしたんです。
今回、検索だけで更新がないので、余裕と思っていたのですが、とんでもなかったです(笑)

フレームワークやMVCの考え方は大好きなので(理解できているかどうかはともかく)、これに懲りずに続けてみることにします。

ありがとうございました。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 


. .