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. 从数据库加载一个 Navigation。2. 和 3. 调用 GalleryController。两次都是相同的控制器功能,但具有不同的参数。

现在,当我摆脱 1. 或两个画廊请求时,网站加载没有任何问题。

可能是那个 requestAction 占用了太多内存?但是,为什么 cakephp 启动无限循环对我来说仍然很奇怪。

firebug 的 net 选项卡没有显示任何可用信息。它只是向我尝试加载的特定站点说明了请求。

编辑 3:

感谢您的回复Nunser!我确实在 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. 对 GalleriesController 的 requestAction:即使我有一个非常基本的控制器,在调用时也只返回一个字符串

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

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

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

我得到一个循环。对此有什么想法吗?

编辑 4:Soooo,经过很长时间后,我开始尝试使用我的 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' 数组会导致问题。所以我把孩子这个词改成了孩子,它突然起作用了。解决方案如下:

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

呃,那里有递归警报。

因此,您有一个包含子菜单的菜单,并且您正在尝试获取菜单 where 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。请参阅文档。你得到了很多你甚至不需要的信息。作为一般规则,尝试将递归设置为 -1 并使用Containable Behavior检索数据,相信我,即使查询可能更麻烦,您检索的数据也会大大减少,具体取决于您的协会。在正确使用可包含和递归之前,我遇到了蛋糕的内存问题。

好吧,无论如何,说到点子上了。如果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 回答