自定义验证逻辑是否属于Doctrine模型(CodeIgniter上下文)?

时间:2012-12-21 19:19:29

标签: php codeigniter validation doctrine models

我是Doctrine的忠实粉丝,但过去主要使用它来更简单,更OO地访问我的数据库。最近虽然我发现自己想用模型做更多,但是为了使我的代码更具语义或逻辑性,并且易于使用。

举个例子,让我们使用Stack Overflow问题和相应的答案。一个问题可以包含一个或多个答案。在过去,我可能会做这样的事情(以下所有内容都是sudo代码btw):

/*
*   METHOD ONE: Note that this is IMO not that semantic or OO
*/
Class QuestionController{       

    //.......

    public function addAnswer($whichQuestionId, $answerTitle, $answerCopy, $answerAuthorId)
    {                       
        //Look, I'm validating stuff here in my controller action           
        if(!strlen($answerTitle) || !strlen($answerCopy) || !strlen($answerAuthorId))
            throw new \Exception('Invalid answer stuff!!');

        //Notice here I'm actually doing some DB quering with 
        $author = $entityManager->find('\StackOverflow\User', $answerAuthorId);
        if($author->getIsBanned())
            throw new \Exception('This is user can not post answer, they are banned!');         

        //OK, things are valid, now we're going to load then question and create a new answer           
        $question = $entityManager->find('\StackOverflow\Question', $whichQuestionId)       

        $answer = new \StackOverflow\Answer;
        $answer->setAuthor($author);
        $answer->setTitle($answerTitle);
        $answer->setContent($answerCopy);

        $question->addAnswer($answer);

        //Let's pretend we persisted everything correctly...
        //Done!

    }

    //.......       
}

Class \StackOverflow\Answer{
    //Normal auto generated stuff here
}

Class \StackOverflow\Qusetion{
    //Normal auto generated stuff here
}

好的,所以请注意我在控制器动作中进行了所有的验证,这很好,但是如果我想在一个不同的控制器中添加一个问题的答案,那么这不是很干。我可以把这个验证逻辑放在某种“助手”中,但这似乎也不是特别好的OO。

我会做这样的事情(不过完全不好,但希望你能得到这个想法)

/*
 *  METHOD TWO: Hopefully a bit more OO...
 */ 

Class QuestionController{   

    public function addAnswer($whichQuestionId, $answerTitle, $answerCopy, $answerAuthorId)
    {
        $result = new \stdObject();

        try{

            $question = $entityManager->find('\StackOverflow\Question', $whichQuestionId);
            $answer = new \StackOverflow\Answer;
            $answer->setAuthor($author);
            $answer->setTitle($answerTitle);
            $answer->setContent($answerCopy);

            //THIS IS NEW!
            $answer->validate();

            //note that perhaps to take this a step futher, in the \StackOverflow\Question class 
            //I might actually call the validate function, so it's a bit more transaparent
            $question->addAnswer($answer);

            //Let's pretend we persisted everything correctly...
            //Done!

            $result->success = true;
            $result->message = 'New answer added!';

        }
        catch(Exception $e)
        {
            $result->success = false;
            $result->message = $e->getMessage();
        }

        return json_encode($result);

    }

}

Class \StackOverflow\Answer{

    //ALL NORMAL AUTO GENERATED GETTERS/SETTERS/ETC HERE

    //CUSTOM FUNCTION - perhaps called by one of the LifeCycle callback things that Doctrine has?
    public function validate()
    {
        //Look, I'm validating stuff here in my controller action           
        if(!strlen($this->getTitle()) || !strlen($this->getContent()) || !strlen($this->getAuthor()))
            throw new \Exception('Invalid answer stuff!!');

        //Notice here I'm actually doing some DB quering INSIDE of another model
        $author = $entityManager->find('\StackOverflow\User', $answerAuthorId);
        if($author->getIsBanned())
            throw new \Exception('This is user can not post answer, they are banned!');         

    }

}

Class \StackOverflow\Question{
    //Normal auto generated stuff here
}

所以我想这可能有点好,这是用Doctrine做事的正确方法吗?可以在现有模型中调用其他模型,还是以这种方式使用Doctrine Entity Manager?有没有更简洁的方法呢?

这个具体的例子非常简单,但在现实生活中我有类似的关系,但“答案”有更复杂和丑陋的验证,需要查找其他表,获取有关“问题”的信息以进行验证它也可能更新我们示例中的“用户”,例如添加新问题的答案可能会更新用户的“QuestionsAnswered”值。我宁愿这种情况透明地发生,而不必知道它真的发生了。我想简单地添加问题的答案,并且所有验证和级联更改都会在幕后自动发生。

1 个答案:

答案 0 :(得分:1)

对此没有正确或错误的答案。最终您可以选择模型与控制器相比的重量。

我的建议是选择一种方法来做到这一点,并保持一致。

我会注意到验证应该与您正在使用的对象相关。检查用户是否在答案验证范围内被禁止可能不是最佳选择。相反,您应该检查与答案相关的数据是否有效。