ffm*_*ngh 5 php oop validation
我正在使用面向对象的方法开发一个新的应用程序,其中涉及一些REST,我没有使用任何框架.
我的问题是在下面的setter中验证用户输入的最佳位置:
public function setSalary($salary)
{
if (Validator::money($salary))
$this->salary = $salary;
else
return 'Error that is an invalid number';
}
Run Code Online (Sandbox Code Playgroud)
还是在控制器中?
public function updateSalary()
{
$errors = array();
if (Validator::money($_POST['salary']))
$salary = $_POST['salary'];
else
$errors ['salary'] = 'Error that is an invalid number';
if(count($errors))
return $errors;
$employee = new Employee($_POST['e_Id']);
$employee->setSalary($salary);
$employee->save();
}
Run Code Online (Sandbox Code Playgroud)
如果我要放入setter我的控制器应该如何看,并返回验证错误?
我已经看到大多数人在控制器中进行验证,但是我认为应该是验证的模型,因为它将使用数据,我们可以重用该模型而不重复自己.但是,有时候验证规则可能需要在某些特殊情况下有所不同,例如对不同视图的不同验证或对晚餐管理员的不同验证.
你会说哪一个符合最佳做法?
首先,既然你似乎渴望实现类似MVC的结构,那么让我们从一些与验证直接无关的一般错误开始.
只有部分代码(包含PHP超级全局)应该是引导阶段.在你的代码中撒满了超级全局,这使得测试变得非常困难.而且您的代码也会通过<input>名称与HTML紧密结合.
控制器不应该有任何逻辑,也不应该处理数据保存.阅读这篇文章,也许它清除了一些东西.
好的..现在回到原来的主题.
一般来说,有两种思想流派:
您在域实体中进行验证
您的域实体(在您的情况下Employee)包含与其相关的所有业务角色.如果它处于有效状态,它可以使用这些规则进行评估.
代码将是这样的:
$employee = new Entity\Employee;
$employee->setID($id);
$employee->setSalary($money);
if ($employee->isValid()) {
$mapper = new Mapper\Employee($dbConn);
$mapper->store($emplyee);
}
Run Code Online (Sandbox Code Playgroud)您永远不会创建无效的域实体
这种方法来自DDD,其中您的域实体由其他类创建,并且它只能从一个有效状态更改为另一个有效状态.基本上,如果你想探索这种方法,你将不得不阅读这本书(可能好几次).
此外,还有另一个验证表单,前两个说明涵盖了注释:数据完整性检查.这是验证的类型,实际上是我的RDBMS.例如,UNIQUE约束.
当遇到ans完整性违规时,通常会抛出异常,即在服务层中处理.
每次将数据写入数据库时都必须调用验证。所以在这种情况下来自控制器。实际验证发生在模型中。模型是对象,它知道它的字段遵循哪些规则,并且可以检查数据是否有效。此外,模型是世界其他部分和数据库之间的边界。所以,我会做这样的事情:
public function updateSalary()
{
$employee = new Employee($_POST['e_Id']);
$employee->setSalary($_POST['salary']));
if ($employee->validate()) {
$employee->save();
} else {
return $employee->getErrors();
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我以这种方式向您提供: