Php 处理菜单未找到异常的最佳方法?

Php 处理菜单未找到异常的最佳方法?,php,exception-handling,Php,Exception Handling,我目前正在重构PHP CMS中的menu类,并且正在尝试找出处理以下问题的最佳方法:有人试图创建菜单(通过传递菜单的标题(我们有main、footer、utility等菜单),但该菜单不在数据库中 如果他们尝试创建一个菜单对象,其中包含一个可以找到的菜单,那么没有问题,我可以按请求返回该对象。如果他们尝试创建一个找不到的菜单对象,我当前正在抛出一个异常(导致发送电子邮件),然后创建一个空白菜单对象并返回该对象。然后,调用输出菜单时不会出错,但不会输出任何内容 (我已经通过设置它来完成上述工作,因

我目前正在重构PHP CMS中的menu类,并且正在尝试找出处理以下问题的最佳方法:有人试图创建菜单(通过传递菜单的标题(我们有main、footer、utility等菜单),但该菜单不在数据库中

如果他们尝试创建一个菜单对象,其中包含一个可以找到的菜单,那么没有问题,我可以按请求返回该对象。如果他们尝试创建一个找不到的菜单对象,我当前正在抛出一个异常(导致发送电子邮件),然后创建一个空白菜单对象并返回该对象。然后,调用输出菜单时不会出错,但不会输出任何内容

(我已经通过设置它来完成上述工作,因此调用menu类的静态方法来创建一个menu对象,该对象可以在必要时处理抛出异常并返回请求的menu对象或空白对象)

希望所有这些都有意义!这是最好的方法吗?还是有更优雅的解决方案

克里斯

编辑:

以下是创建菜单时调用的静态函数:

static function makeMenu($id,$breakDepth=1){
    // try to create Menu
    try {
        $menu = new Menu($id, $breakDepth);
    }
    catch (no_menu_found_exception $e) {
        // if we failed to find it, an email should have been sent, and create a blank menu so rest of site works without error
        $menu = new Menu("");
    }

    return $menu;
}
这是构造器:

function __construct($id,$breakDepth=1){
    $this->treeObject = Doctrine_Core::getTable('CmsMenuItemNew')->getTree();
    if ($id == "") {
        // if ID supplied is empty, return an empty menu object 
        $this->rootNode = null;
        $this->name = $id;
        return;
    } 
    if (is_numeric($id)) {
        // check it exists?
        $this->rootNode = $id;
        $node = Doctrine_Core::getTable('CmsMenuItemNew')->findByDQL("menuid = '".$id."'")->getFirst();
        $this->name = $node->menutitle;
        if ($this->name == "") $this->rootNode = null;
        return;
    } else {
        $this->name = $id;
        // find the menu ID for the supplied name  
        $table = Doctrine_Core::getTable('CmsMenuItemNew');
        $table->setOption("orderBy", "level");
        $this->rootNode = $table->findByDQL("menutitle = '$id'")->getFirst()->menuid;

        // rootNode with supplied name not found, so look for a branch in the main menu
        $this->breakDepth = $breakDepth;    
        if ($this->rootNode === null) {
            throw new no_menu_found_exception("Menu not found: ".$id);
        }
    }           

}

如前所述-它仍在开发中,因此尚未完全完成。

构建空白对象是一件好事。正确的设计模式称为SpecialObjects。要完成,您的代码应返回与MenuObject具有相同接口的MenuNotFound对象。 然后,此MenuNotFound对象对接口入口点的反应方式取决于您。 这样可以避免检查返回的对象类型,并允许链接


对于异常,我个人更喜欢只存在实际问题的异常。但是在你的情况下,如果你想获得一封邮件,异常不是一个坏主意,也许这个异常或邮件处理可以在MenuNotFound init中完成。

抛出一个异常并通过发送邮件来处理,听起来已经很优雅了。可能会发布一些代码nippets?SpecialObjects设计模式也称为空对象模式?我想这听起来像是我在寻找的。因此,在我的静态方法中,在catch段中,我会调用“new MenuNotFound()”?这意味着我不需要混乱的“if($id==”)构造函数中的{部分,我认为这是我认为必须有一个更简洁的解决方案的部分原因。我认为这就是我一直在寻找的。我也同意,这对于引发异常来说似乎有点弱-我想我可能可以在静态方法中检查它,所以我不必向sh抛出异常是的,空对象,我总是提醒我特殊的对象,但据我所知,空对象似乎是相同的模式。一个区别可能是空对象在他的方法中不包含任何内容,他不应该做任何事情。