2010-07-15 35 views
6

im đang làm cho một lớp xác nhận php với các lớp học phụ mà mở rộng nó, ví dụ như, điện thoại di động, ngoại ô, CREDIT_CARD, vvlớp php ... xác nhận

như vậy, ý tưởng là bạn có thể gọi

$validation = new Validation('mobile'); 
$valid = $validation->validate($number); 

$validation->type('suburb'); 
$valid2 = $validation->validate($suburb); 

tại ý tưởng của tôi để làm điều này là có

class Validation() { 
    private $v_type = null; 

    function __construct($type) { 
     $this->type($type); 
    } 

    public function type($type) { 
     $this->v_type = new $type(); 
    } 

    public function validate($info) { 
     return $this->v_type->validate($info); 
    } 
} 

như một ví dụ rất cơ bản

nhưng có cách nào tốt hơn để làm điều này?

Trả lời

9

Bạn có thể thực hiện theo cách này nhưng có thể cải thiện. Có các trình duyệt tính hợp lệ thực sự là logic xác nhận hợp lệ của chúng là tốt. Mở rộng chúng từ một lớp cơ sở thì không. Thay vào đó, hãy triển khai một giao diện. Bằng cách này, mọi lớp đều có thể là Trình xác thực.

interface IValidate 
{ 
    public function validate($value); 
} 

xác nhận của bạn sẽ trông như thế này thì:

class IsNumeric implements IValidate 
{ 
    public function validate($value) 
    { 
     return is_numeric($value); 
    } 
} 

class GreaterThan implements IValidate 
{ 
    protected $_value; 
    public function __construct($value) 
    { 
     $this->_value = $value; 
    } 
    public function validate($value) 
    { 
     return $value > $this->_value; 
    } 
} 

Bạn vẫn muốn có một lớp Validator chính. Không giống như trong ví dụ của bạn, Trình xác thực bên dưới chấp nhận nhiều Trình xác thực, cho phép bạn tạo Chuỗi bộ lọc.

class Validator implements IValidate 
{ 
    protected $_validators; 

    public function addValidator(IValidate $validator) 
    { 
     $this->_validators[] = $validator; 
     return $this; 
    } 
    public function validate($value) 
    { 
     foreach($this->_validators as $validator) { 
      if ($validator->validate($value) === FALSE) { 
       return FALSE; 
      } 
     } 
     return TRUE; 
    } 
} 

Và điều này có thể được sử dụng như:

$validator = new Validator; 
$validator->addValidator(new IsNumeric) 
      ->addValidator(new GreaterThan(5)); 

var_dump($validator->validate('ten')); // FALSE 
var_dump($validator->validate('10')); // TRUE 
var_dump($validator->validate('1')); // FALSE 

Trên đây là khá nhiều Command pattern. Và do Validator triển khai IValidate, nó cũng là Composite. Bạn có thể lấy chuỗi Validator từ phía trên và xếp chuỗi đó vào một Chuỗi xác thực khác, ví dụ:

$numericGreaterThanFive = new Validator; 
$numericGreaterThanFive->addValidator(new IsNumeric) 
         ->addValidator(new GreaterThan(5)); 

$otherValidator = new Validator; 
$otherValidator->addValidator(new Foo) 
       ->addValidator(new Bar) 
       ->addValidator($numericGreatherThanFive); 

Để thuận tiện, bạn có thể thêm phương pháp nhà máy tĩnh để tạo Trình xác thực với các đối tượng Lệnh xác thực thực tế (như được hiển thị ở nơi khác).

Trên sidenote: the Zend Framework already has an extensive number of Validators you can build on. Vì ZF là một thư viện thành phần, bạn có thể sử dụng chúng mà không phải di chuyển toàn bộ ứng dụng của mình sang ZF.

2

Thông thường, bạn làm các loại vật bằng cách sử dụng mô hình Nhà máy, một cái gì đó như thế này:

class ValidatorFactory { 
    public static function get($type) { 
     $validator = "Validator_$type"; 
     return new $validator(); 
    } 
} 

$valid = ValidatorFactory::get('mobile')->validate($number); 

Would dĩ nhiên cần một số kiểm tra lỗi và như vậy, nhưng bạn sẽ nhận được các ý tưởng

0
... 
public function type($type) { 
    return new self($type); 
} 
... 

Lưu ý: Điều này mỗi lần trả về một thể hiện mới của lớp Validator của bạn vì vậy sẽ tốt hơn nếu bạn sử dụng mẫu Factory như Dennis đã đề xuất hoặc không gắn Validator mới với phương thức type().