इस 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)
उस रिटर्न के सही / गलत होने के तरीके बनाने चाहिए और फिर उन्हें कंट्रोलर से कॉल करना चाहिए?
<?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
}
और नियंत्रक मूल रूप से समान होगा, बस कोशिश / पकड़ने के बजाय अब हैं यदि / नहीं:
<?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
और अन्य अपवादों को संशोधित करने के लिए संशोधित किया है