【问题标题】:Validate: Controller vs Controller functions验证:控制器与控制器功能
【发布时间】:2013-12-12 12:01:43
【问题描述】:

我想知道验证输入变量的最佳方法在哪里。你可以对每个框架都应用这个问题,但在我的例子中是 Symfony2:控制器是一个类,它处理像单个控制器这样的方法。

例如我有一个控制器类,其中每个操作都是一个方法:

namespace MSD\HomeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use MSD\HomeBundle\Entity\Imagen as Imagen;

class HomeController extends Controller
{   
    public function indexAction()
    {
        if( isset( $_POST['whatever'] ) && $whatever = intval( $_POST['whatever'] ) )
        {
           $iFoo1 = $whatever * 25;
           $iFoo2 = $whatever / 32;

           return $this->render( 'MSDHomeBundle:Home:template.html.twig', array( 'foo'=> array( 'foo1'=>$iFoo1, 'foo2'=>$iFoo2 ) ) );
        }
    }
    //...
}    

$whatever 在控制器操作中得到验证。但是您可以为每种操作创建一个方法。例如

private function multiply( $iNum1, $iNum2 )
{
    return ( $iNum1 * $iNum2 );
}  
private function divide( $iNum1, $iNum2 )
{
    return ( $iNum1 / $iNum2 );
}

你应该验证每个函数的参数:

private function multiply( $iNum1, $iNum2 )
{
    return ( intval( $iNum1 ) * intval( $iNum2 ) );
}  
private function divide( $iNum1, $iNum2 )
{
    return ( intval( $iNum1 ) / intval( $iNum2 ) );
}

并从控制器调用它们:

namespace MSD\HomeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use MSD\HomeBundle\Entity\Imagen as Imagen;

class HomeController extends Controller
{   
    public function indexAction()
    {
        if( isset( $_POST['whatever'] ) && $whatever = intval( $_POST['whatever'] ) )
        {
           $iFoo1 = $this -> multiply( $whatever, 25 );
           $iFoo2 = $this -> divide( $whatever / 32 );

           return $this->render( 'MSDHomeBundle:Home:template.html.twig', array( 'foo'=> array( 'foo1'=>$iFoo1, 'foo2'=>$iFoo2 ) ) );
        }  
    }
    //...
}    

但是你验证$_POST['whatever'] 三次:在if 条件和两个私有函数中。但是,我猜这应该是更安全的验证方式,因为您不能“忘记”验证,因为每个函数都会验证自己的参数。但也意味着重复验证。

我不确定是否有更好的方法。我找不到更好的解决方案,在不重复验证的情况下保持最大安全性。

【问题讨论】:

  • 使用 symfony 你应该使用请求包而不是直接点击 $_POST、$_GET 等参数。

标签: php validation symfony model-view-controller


【解决方案1】:

我不同意“您应该验证每个函数的参数” - 在您的示例中,这些是私有函数,因此它们仅由调用类调用,因此在洁净室中运行:无论调用它们是负责处理干净的数据。因此,您示例中的验证将仅保留在正确的操作中。

也就是说,我相信验证会移动到它自己的类中,并根据需要插入到表单或控制器中。我使用 Zend Framework,因此我将验证器作为服务层的一部分。 Symfony 似乎在执行something similar,看起来您将验证描述为模型 YAML 的一部分,然后在该模型上调用验证器服务。

(顺便说一句:这似乎遵循胖模型,瘦控制器模式,可能是rubbish。在 ZF 中,验证与模型是分开的。必须做更多的工作来连接各个部分,但更少模型膨胀。)

【讨论】:

  • 其实这不是模型,而是控制器。我所写的都是关于控制器的,它在 Symfony 中是一个类。所以当我说一个方法时,我的意思是控制器内部的一个函数。准确地说,我试图避免“胖模型”并在控制器内部编写更多代码。
  • 不管怎样,我警告不要用验证器使控制器变胖,原因有三个:(1) 违背了 Symphony 中验证的方式,(2) 控制器很难测试, (3) 不能在不违反 DRY 的情况下跨多个控制器重用。因此,我建议使用 Symphony 的颗粒,并将验证服务附加到特定的模型类。
  • 好的。我会考虑的。谢谢你的帮助。让我在接受之前看到更多答案。
【解决方案2】:

最合适的方法是为此创建自己的验证器。 我不喜欢这种验证方式——将来你的控制器会被不必要的代码超载:P 最好在 symfony 的教程中尝试这样做

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多