0

私はこの CakePHP アプリ (バージョン 1.2) を持っています。これは、特定のページをロードするときに内部サーバー エラーを生成する奇妙な動作を開始しました。

次に、ローカルの Mamp 環境に xDebug をインストールしたところ、このページにアクセスするとアプリがループすることがわかりました。残念ながら、これを解釈する方法がわかりません。おそらく、私を助けて方向性を示すことができます (ここでコードを公開する前に)。

どうもありがとう!

写真: 無限ループ

編集 - 写真の 14 行目は、次の要求を含むファイル mmenu.ctp を参照しています。

$menus = $this->requestAction('/menus/reto');

MenusController には、次のアクションが含まれます。

クラス

 MenusController extends AppController {
            var $name = 'Menus';
            var $helpers = array('Html', 'Form');
            function reto(){
                $this->Menu->recursive = 2;
                return $this->Menu->find('all', array('conditions' => array("parent_id" => 0), 'order' => 'Menu.order asc'));
            }
     ...
    }

それが役立つことを願っています。

編集 2: わかりました、さらにテストを行いました。ロードされるページには、3 つの requestActions があります。1. データベースからナビゲーションをロードします。2. と 3. は GalleryController を呼び出します。どちらの場合も同じコントローラー関数ですが、引数が異なります。

1 つまたは 2 つのギャラリー リクエストを削除すると、サイトは問題なく読み込まれます。

requestAction がメモリを使いすぎているのではないでしょうか? しかし、cakephp が無限ループを開始する理由は、私にはまだ奇妙です。

firebug の net タブには、使用可能な情報が表示されませんでした。私が読み込もうとしている特定のサイトへのリクエストが記載されているだけです。

編集3:

ナンサーさん、お返事ありがとうございます!beforeRender 関数内の app_controler ファイルにメニュー関数を追加しました。

$this->loadModel('Menu');

            if (!isset($this->viewVars['mainMenu'])) 
            {
              $this->set(
                    'mainMenu', $this->Menu->find('all', 
                        array('conditions' => array("parent_id" => 0), 'recursive' => '2', 'order' => 'Menu.order asc')
                        )
                    );

            }

ただし、recursive=2 は削除しませんでした。メニュー テーブルから、たとえば URL などの追加情報が保存されているコンテンツ テーブルに結合する必要があるためです。結果の配列は次のようになります。

[0] => Array
        (
            [Menu] => Array
                (
                    ...

                )
            [Content] => Array
                (

                    [url] => urlhere
                  ...

                )
                [Child] => Array
                (
                    [0] => Array
                        (
                            [Content] => Array
                                (
                                    [url] => url here...
                                )

                        )

                   ...
                )

        )

recursive=-1 でこれを取得する方法がわかりません。Containableを調べましたが、うまくいきませんでした。

とにかく、もっと興味深いのは 2. と 3. の requestAction です。

echo $this->requestAction('/galleries/sidegal');

<?php
    class GalleriesController extends AppController {
        var $name = 'Galleries';
        var $helpers = array('Html', 'Form');

        function sidegal() {
        return 'testString';
        }
            }
?>

私はループを取得します。これに関するアイデアはありますか?

編集 4: すっごく長い時間の後、GalleryModel を試し始めました。最初は次のようになりました。

var $hasMany = array(
        'Gimage' => array(
            'className' => 'Gimage',
            'foreignKey' => 'gallery_id',
            'dependent' => true,
            'conditions' => '',
            'fields' => '',
            'order' => 'Gimage.order asc',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => '' ),
            'Child' => array('className' => 'Gallery',
            'foreignKey' => 'parent_id',
            'order' => 'Child.order asc'
            ),
            );

そのとき、「子」配列が問題を引き起こすことに気付きました。そこで、Child という単語を Children に変更すると、突然機能しました。解決策は次のとおりです。

var $hasMany = array(
            'Gimage' => array(
                'className' => 'Gimage',
                'foreignKey' => 'gallery_id',
                'dependent' => true,
                'conditions' => '',
                'fields' => '',
                'order' => 'Gimage.order asc',
                'limit' => '',
                'offset' => '',
                'exclusive' => '',
                'finderQuery' => '',
                'counterQuery' => '' ),
                'Children' => array('className' => 'Gallery',
                'foreignKey' => 'parent_id',
                'order' => 'Children.order asc'
                ),
                );

今はそれが機能することを嬉しく思います。Nunser のサポートに感謝します。

4

1 に答える 1

0

うーん、再帰アラートがあります。

したがって、サブメニューを持つメニューがあり、 のメニューを取得しようとしていますがparent_id = 0、 を使用すると$recursive = 2

Menu where parent_id = 0
    Submenus of this menu where parent_id = menu_id
        Parent menu of this submenu where parent_id = 0
            ...forever and ever

そこに再帰がありますか?これは、再帰を 2 に設定したために発生します。 docsを参照してください。必要のない情報をたくさん手に入れてしまいます。原則として、再帰を -1 に設定し、Containable Behaviorでデータを取得するようにしてください。クエリを作成するのが少し面倒かもしれませんが、取得するデータは、協会。私は、containable と recursion を正しく使用する前に、cake でメモリの問題に遭遇しました。

まあ、とにかく、ポイントに。のメニューのみreto()が必要な場合は、次のようにしますparent_id = 0

$this->Menu->recursive = -1;
return $this->Menu->find('all', array('conditions' => array("parent_id" => 0), 'order' => 'Menu.order asc'));

そしてループは消滅します。

メニューと最初のティアサブメニューが必要な場合は、試してください

 $this->Menu->recursive = -1;
 return $this->Menu->find('all', array('conditions' => array("parent_id" => 0),
                                       'recursive' => -1, //just to be sure
                                       'contain' => 'Menu',
                                       'order' => 'Menu.order asc'));

またはそのようなもの(私は1.2で作業していないため、構文が少し異なる場合があります)。

ああ、あなたの最後の編集に関する補足として: requestAction は多くの遅延を引き起こし、MVC フレームワーク内では眉をひそめています。削除してみてください。それがループの問題を引き起こしているとは思いませんが、オプションを調べてください。ナビゲーションに使用する場合は、AppController の beforeRender にここに表示されているのと同じメニュー機能を追加し、配列をビュー変数に設定して、毎回 requestAction を実行する代わりに表示するだけにしてみませんか?

于 2013-05-29T15:08:37.853 に答える