이 SO 질문을 읽으면 사용자 입력 유효성 검사에 대한 예외 예외가 발생하는 것으로 보입니다.
그러나 누가이 데이터를 검증해야합니까? 내 응용 프로그램에서 모든 유효성 검사는 비즈니스 계층에서 수행됩니다. 클래스 자체만으로 각 속성마다 유효한 값을 알고 있기 때문입니다. 속성 유효성 검사 규칙을 컨트롤러에 복사하는 경우 유효성 검사 규칙이 변경 될 수 있으며 이제 수정해야 할 두 곳이 있습니다.
비즈니스 계층에서 유효성 검사를 수행해야한다는 전제입니까?
내가하는 일
따라서 내 코드는 일반적으로 다음과 같이 끝납니다.
<?php
class Person
{
private $name;
private $age;
public function setName($n) {
$n = trim($n);
if (mb_strlen($n) == 0) {
throw new ValidationException("Name cannot be empty");
}
$this->name = $n;
}
public function setAge($a) {
if (!is_int($a)) {
if (!ctype_digit(trim($a))) {
throw new ValidationException("Age $a is not valid");
}
$a = (int)$a;
}
if ($a < 0 || $a > 150) {
throw new ValidationException("Age $a is out of bounds");
}
$this->age = $a;
}
// other getters, setters and methods
}
컨트롤러에서 입력 데이터를 모델에 전달하고 예외를 포착하여 사용자에게 오류를 표시합니다.
<?php
$person = new Person();
$errors = array();
// global try for all exceptions other than ValidationException
try {
// validation and process (if everything ok)
try {
$person->setAge($_POST['age']);
} catch (ValidationException $e) {
$errors['age'] = $e->getMessage();
}
try {
$person->setName($_POST['name']);
} catch (ValidationException $e) {
$errors['name'] = $e->getMessage();
}
...
} catch (Exception $e) {
// log the error, send 500 internal server error to the client
// and finish the request
}
if (count($errors) == 0) {
// process
} else {
showErrorsToUser($errors);
}
이것이 나쁜 방법론입니까?
다른 방법
어쩌면 isValidAge($a)
반환 true / false에 대한 메소드를 작성 하고 컨트롤러에서 호출해야합니까?
<?php
class Person
{
private $name;
private $age;
public function setName($n) {
$n = trim($n);
if ($this->isValidName($n)) {
$this->name = $n;
} else {
throw new Exception("Invalid name");
}
}
public function setAge($a) {
if ($this->isValidAge($a)) {
$this->age = $a;
} else {
throw new Exception("Invalid age");
}
}
public function isValidName($n) {
$n = trim($n);
if (mb_strlen($n) == 0) {
return false;
}
return true;
}
public function isValidAge($a) {
if (!is_int($a)) {
if (!ctype_digit(trim($a))) {
return false;
}
$a = (int)$a;
}
if ($a < 0 || $a > 150) {
return false;
}
return true;
}
// other getters, setters and methods
}
그리고 컨트롤러는 기본적으로 동일하지만 try / catch 대신 if / else가 있습니다.
<?php
$person = new Person();
$errors = array();
if ($person->isValidAge($age)) {
$person->setAge($age);
} catch (Exception $e) {
$errors['age'] = "Invalid age";
}
if ($person->isValidName($name)) {
$person->setName($name);
} catch (Exception $e) {
$errors['name'] = "Invalid name";
}
...
if (count($errors) == 0) {
// process
} else {
showErrorsToUser($errors);
}
그래서 내가 무엇을해야하니?
나는 원래의 방법에 매우 만족하며, 일반적으로 내가 보여준 동료들은 그것을 좋아했습니다. 그럼에도 불구하고 대체 방법으로 변경해야합니까? 아니면이 잘못하고 다른 방법을 찾아야합니까?
IValidateResults
.
ValidationException
하고 다른 예외를 수정했습니다