2013-02-16 55 views
13

如何通過Zend Framework 2 ValidatorChain將空值傳遞給我的自定義驗證器?傳遞給Zend framework 2驗證器的空值

這是可能的ZF1通過allowEmpty(false)

在ZF2與空元素值:

  • allowEmpty = false如果,NotEmptyValidator加到ValidatorChain的頂部breakOnFailure = true@see Zend/InputFilter/Input#injectNotEmptyValidator

  • 如果allowEmpty = true,元素被認爲是有效的,@see Zend/InputFilter/BaseInputFilter#isValid

    if ($input->allowEmpty()) { 
        $this->validInputs[$name] = $input; 
        continue; 
    } 
    
+1

http://akrabat.com/zend-framework-2/setting-up-required-fields-that-c​​an-be-empty-with-zendinputfilter/ – Sam 2013-02-16 13:58:36

+0

這不是我需要的,因爲如果allow_empty = true,我的元素值爲空,zf2認爲該元素是有效的,不會調用驗證器。 – deyine 2013-02-16 14:29:03

+0

我想我不明白你的問題。要麼你允許空值,要麼你不允許。如果你不允許空值,那麼所有的驗證器都會運行,否則驗證會失敗,當一個空的輸入被給出時。如果你確實允許,那麼一個空值就不需要進一步確認了o0 – Sam 2013-02-16 15:29:43

回答

14

以下工作爲2.1.1版本ZF2:

的問題(如果我沒有得到它)​​是在例如,對於'fieldName'的空值,不會觸發驗證。這可能是很煩人的,雖然在

$input = new \Zend\InputFilter\Input('fieldName'); 

$input 
    ->setAllowEmpty(true) 
    ->setRequired(false) 
    ->getValidatorChain() 
    ->attach(new \Zend\Validator\Callback(function ($value) { 
     echo 'called validator!'; 

     return true; // valid 
    })); 

$inputFilter = new \Zend\InputFilter\InputFilter(); 
$inputFilter->add($input); 

$inputFilter->setData(array('fieldName' => 'value')); 
var_dump($inputFilter->isValid()); // true, echoes 'called validator!' 

$inputFilter->setData(array('fieldName' => '')); 
var_dump($inputFilter->isValid()); // true, no output 

$inputFilter->setData(array()); 
var_dump($inputFilter->isValid()); // true, no output 

這是當你有特殊的情況下,很煩人如檢查分配給您的CMS一個頁面的URL和避免碰撞(空URL仍然是一個URL!) 。

有一種處理空字符串的方法,它基本上將NotEmpty驗證程序附加在自己的上面,並避免調用setRequiredsetAllowEmpty。這將基本上告訴Zend\InputFilter\Input#injectNotEmptyValidator不utomatically附上了自己的一個NotEmpty驗證:

$input = new \Zend\InputFilter\Input('fieldName'); 

$input 
    ->getValidatorChain() 
    ->attach(new \Zend\Validator\NotEmpty(\Zend\Validator\NotEmpty::NULL)) 
    ->attach(new \Zend\Validator\Callback(function ($value) { 
     echo 'called validator!'; 

     return true; // valid 
    })); 

$inputFilter = new \Zend\InputFilter\InputFilter(); 
$inputFilter->add($input); 

$inputFilter->setData(array('fieldName' => 'value')); 
var_dump($inputFilter->isValid()); // true, echoes 'called validator!' 

$inputFilter->setData(array('fieldName' => '')); 
var_dump($inputFilter->isValid()); // true, echoes 'called validator!' 

$inputFilter->setData(array()); 
var_dump($inputFilter->isValid()); // false (null was passed to the validator) 

如果你也想覈對null,則需要延長Zend\InputFilter\Input如下:

class MyInput extends \Zend\InputFilter\Input 
{ 
    // disabling auto-injection of the `NotEmpty` validator 
    protected function injectNotEmptyValidator() {} 
} 
+0

你已經去了,我想檢查空和空,所以你最後的解決方案確認我的實施。非常感謝。 – deyine 2013-02-16 23:48:07

+5

只要執行'$ input-> setContinueIfEmpty(true);'而不是擴展_Zend \ InputFilter \ Input_,它會產生相同的效果,減少工作量並且簡化操作。 – 2013-11-19 11:21:00

2

如果您喜歡使用單獨的表單驗證類或數組表示驗證,可以這樣做:

$factory  = new Zend\InputFilter\Factory(); 
$inputFilter = new Zend\InputFilter\InputFilter(); 

$inputFilter->add($factory->createInput(array(
    'name' => 'name', 
    'required' => false, 
    'allowEmpty' => true, 
    'filters' => array(
     array('name' => 'StripTags'), 
     array('name' => 'StringTrim'), 
    ), 
    'validators' => array(
     array(
      'name' => 'StringLength', 
      'options' => array(
       'encoding' => 'UTF-8', 
       'min' => '8', 
       'max' => '100', 
      ), 
     ), 
    ), 
))); 

你可以通過一個數組required => falseallowEmpty => true輸入濾波器工廠(因爲我記得你可以直接將它傳遞給輸入濾波器 - 不太確定)。

25

continue_if_empty解決了我的問題。感謝@ dson-horácio-junior。這是我用:

$this->add(array(
    'name' => 'field', 
    'continue_if_empty' => true, 
    'filters' => array(
     array('name' => 'StripTags'), 
     array('name' => 'StringTrim') 
    ), 
    'validators' => array(
     array(
      'name' => 'Application\Form\Validator\Sample' 
     ) 
    ) 
)); 

public function isValid($value, $context = null) 
{ 
    if ($value == '' && $context['otherfield'] == '') { 
     $this->error(self::INVALID_FIELD); 

     return false; 
    } 

    // ... 
} 
+0

完美的答案。謝謝 – Abadis 2015-02-05 07:28:10

+0

最佳答案!值得更多upvotes。如果您將'continue_if_empty'設置爲'true',那麼'InputFilter \ Factory'不會自動添加'NotEmpty'驗證器,因此所有驗證都會轉到用戶定義的驗證器。 – kachar 2015-05-26 10:45:17

+0

很好的答案謝謝你+1 – 2016-04-25 10:27:44

7

這引發了我的Callback驗證的驗證當數值是空字符串:

'required'   => false, 
'allow_empty'  => false, 
'continue_if_empty' => true, 
'validators'  => array(
    array(
     'name' => 'Callback', 
     'options' => array(
      'callback' => function ($value, $context = []) use ($self) { 
       // ... 
      } 
     ) 
    ) 
) 

allow_empty最初無效空字符串和continue_if_empty允許它然後是由後面的驗證器進行評估。

+0

這是工作的解決方案,謝謝本 – 2016-04-15 11:55:57

+0

保存我的一天!謝謝 – 2017-02-23 04:12:59

2

我經常看到在inputFilter配置數組中使用allowEmpty來犯錯誤的人。字符串應該用下劃線分隔,而不是與駱駝大小寫。所以allow_empty將工作:

'fieldName' => array(
    'name'  => 'fieldName', 
    'required' => true, 
    'allow_empty' => true, 
    'filters' => array(
     //... your filters ... 
    ) 
    'validators' => array(
     //... your validators ... 
    ), 
); 

意思與關鍵「字段名」字段必須存在於數據,但其價值被允許爲空。