2013-04-17 9 views
13

मैं सिम्फनी सत्यापन का उपयोग कर सरणी कुंजियों को कैसे सत्यापित कर सकता हूं?सिम्फनी सत्यापन का उपयोग करके सरणी कुंजियों को मैं कैसे सत्यापित कर सकता हूं?

कहें कि मेरे पास निम्न है, और emails सरणी की प्रत्येक कुंजी एक आईडी है। मैं कॉलबैक, या किसी अन्य बाधा का उपयोग करके उन्हें कैसे सत्यापित कर सकता हूं (उदाहरण के लिए कॉलबैक की बजाय रेगेक्स बाधा कहें)?

$input = [ 
    'emails' => [ 
     7 => '[email protected]', 
     12 => '[email protected]', 
    ], 
    'user' => 'bob', 
    'amount' => 7, 
]; 

use Symfony\Component\Validator\Validation; 
use Symfony\Component\Validator\Constraints; 
$validator = Validation::createValidator(); 
$constraint = new Constraints\Collection(array(
    'emails' => new Constraints\All(array(
     new Constraints\Email(), 
    )), 
    'user' => new Constraints\Regex('/[a-z]/i'), 
    'amount' => new Constraints\Range(['min' => 5, 'max' => 10]), 
)); 

$violations = $validator->validateValue($input, $constraint); 
echo $violations; 

(नवीनतम डेवलपर मास्टर सिम्फोनी का उपयोग कर)

उत्तर

6

मैं एक कस्टम सत्यापन बाधा उत्पन्न करूंगा जो सरणी में प्रत्येक कुंजी-मूल्य जोड़ी (या केवल तभी कुंजी) पर बाधा लागू करता है। All बाधा के समान, लेकिन कुंजी-मूल्य जोड़ी पर सत्यापन किया जाता है, केवल मूल्य नहीं।

namespace GLS\DemoBundle\Validator\Constraints; 
use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Validator\Exception\ConstraintDefinitionException; 

class AssocAll extends Constraint 
{ 
    public $constraints = array(); 

    public function __construct($options = null) 
    { 
     parent::__construct($options); 

     if (! is_array($this->constraints)) { 
      $this->constraints = array($this->constraints); 
     } 

     foreach ($this->constraints as $constraint) { 
      if (!$constraint instanceof Constraint) { 
       throw new ConstraintDefinitionException('The value ' . $constraint . ' is not an instance of Constraint in constraint ' . __CLASS__); 
      } 
     } 
    } 

    public function getDefaultOption() 
    { 
     return 'constraints'; 
    } 

    public function getRequiredOptions() 
    { 
     return array('constraints'); 
    } 
} 

बाधा सत्यापनकर्ता है, जो प्रत्येक बाधा को कुंजी-मान पेयर के साथ एक सरणी से गुजरता है:

namespace GLS\DemooBundle\Validator\Constraints; 
use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Validator\ConstraintValidator; 
use Symfony\Component\Validator\Exception\UnexpectedTypeException; 


class AssocAllValidator extends ConstraintValidator 
{ 
    public function validate($value, Constraint $constraint) 
    { 
     if (null === $value) { 
      return; 
     } 

     if (!is_array($value) && !$value instanceof \Traversable) { 
      throw new UnexpectedTypeException($value, 'array or Traversable'); 
     } 

     $walker = $this->context->getGraphWalker(); 
     $group = $this->context->getGroup(); 
     $propertyPath = $this->context->getPropertyPath(); 

     foreach ($value as $key => $element) { 
      foreach ($constraint->constraints as $constr) { 
       $walker->walkConstraint($constr, array($key, $element), $group, $propertyPath.'['.$key.']'); 
      } 
     } 
    } 
} 

मुझे लगता है, केवल Callback बाधा समझ में आता है प्रत्येक कुंजी-मान पेयर है, जहां आप पर लागू किए जाने अपना सत्यापन तर्क डालें।

use GLS\DemoBundle\Validator\Constraints\AssocAll; 

$validator = Validation::createValidator(); 
$constraint = new Constraints\Collection(array(
    'emails' => new AssocAll(array(
     new Constraints\Callback(array(
      'methods' => array(function($item, ExecutionContext $context) { 
        $key = $item[0]; 
        $value = $item[1]; 

        //your validation logic goes here 
        //... 
       } 
      ))), 
    )), 
    'user' => new Constraints\Regex('/^[a-z]+$/i'), 
    'amount' => new Constraints\Range(['min' => 5, 'max' => 10]), 
)); 

$violations = $validator->validateValue($input, $constraint); 
var_dump($violations); 
+0

लगता है कि 'getGraphWalker' को हटा दिया गया है और हटा दिया गया है। – Petah

2

एक कॉलबैक बाधा नहीं है। देखें http://symfony.com/doc/master/reference/constraints/Callback.html

अद्यतन:

मैं वर्तमान मूल्य की चाबी पाने के लिए एक क्लीनर रास्ता नहीं मिल सका सत्यापित किया जा रहा। शायद एक बेहतर तरीका है, मैंने इस पर बहुत अधिक समय नहीं लगाया लेकिन यह आपके मामले के लिए काम करता है।

use Symfony\Component\Validator\Constraints; 
    use Symfony\Component\Validator\Context\ExecutionContextInterface; 

    // ... 

    $input = array(
    'emails' => array(
      7 => '[email protected]', 
      12 => '[email protected]', 
    ), 
    'user' => 'bob', 
    'amount' => 7, 
    ); 

    // inside a sf2 controller: $validator = $this->get('validator.builder')->getValidator(); 
    $validator = Validation::createValidator(); 
    $constraint = new Constraints\Collection(array(
     'emails' => new Constraints\All(array(
       new Constraints\Email(), 
       new Constraints\Callback(array('methods' => array(function($value, ExecutionContextInterface $context){ 
        $propertyPath = $context->getPropertyPath(); 
        $valueKey = preg_replace('/[^0-9]/','',$propertyPath); 
        if($valueKey == 7){ 
         $context->addViolationAt('email', sprintf('E-Mail %s Has Has Key 7',$value), array(), null); 
        } 
       }))) 
     )), 
     'user' => new Constraints\Regex('/[a-z]/i'), 
     'amount' => new Constraints\Range(array('min' => 5, 'max' => 10)), 
    )); 

    $violations = $validator->validate($input, $constraint); 
    echo $violations; 
+0

हाँ, लेकिन मैं इसे सरणी ** कुंजी ** नहीं मान पर चलने कैसे करते हैं। – Petah

+0

उत्तर को अपडेट किया गया क्योंकि मुझे डाउनवोट –

+0

समाधान के बजाय हैक की तरह मिला। लेकिन मैं एक कस्टम सत्यापनकर्ता में मोड़ने में सक्षम हो सकता है। आपके परिश्रम के लिए धन्यवाद। – Petah

-1

आप कुंजियों, मानों को उल्टा करने के क्रम में php समारोह array_flip उपयोग करते हैं, और एक सत्यापनकर्ता या एक कस्टम एक का उपयोग कर सकते हैं।

आशा है कि यह सहायक होगा।

सर्वोत्तम सम्मान।

-1

एक छोटी सी थोड़ी देर हो चुकी है, लेकिन ये रहा, मेरे दोस्त:

use Symfony\Component\Validator\Constraints as Assert; 

public function getConstraints() 
{ 
    return [ 
     'employee' => [new Assert\NotBlank(), new Assert\Type("integer")], 
     'terms' => [new Assert\NotBlank(), new Assert\Type("array")], 
     'pivotData' => new Assert\All([ 
      new Assert\Type("array"), 
      new Assert\Collection([ 
       'amount' => new Assert\Optional(new Assert\Type('double')) 
      ]) 
     ]), 
    ]; 
} 

योग्य कुछ बातें यहां सूचना के लिए:

  • उदाहरण में ऊपर दी गई, हम pivotData कुंजी को मान्य कर रहे हैं। pivotData अतिरिक्त डेटा की एक सरणी होनी चाहिए जिसे हम मान्य करना चाहते हैं।

  • हर बार जब हम एक सरणी मान्य करने के लिए चाहते हैं, हम new Assert\All के साथ शुरू, जिसका अर्थ है कि हम बाद में pivotData

  • में सब कुछ मान्य करने के लिए चाहते हैं, हम एक सरणी वास्तव में सामने से पारित कर दिया गया है, तो नया Assert\Type("array") जाँच करने के लिए जोड़ समाप्त।

  • और, सबसे महत्वपूर्ण बात यह है कि हम new Assert\Collection बनाते हैं जहां हम मानक के रूप में एक-एक करके अपनी नई संपत्तियों को परिभाषित करते हैं। उपर्युक्त उदाहरण में, मैंने amount कुंजी जोड़ दी है जो पिवोटडेटा संपत्ति का प्रतिनिधित्व करती है।आप स्वतंत्र रूप से अपने सभी गुण यहां सूचीबद्ध कर सकते हैं, वे मान्य हो जाएगी :)

गुड लक :)

+0

यह सवाल नहीं है ... – Petah

+0

ओह हाँ, क्षमा करें! मुझे और सावधानी से पढ़ना चाहिए था –

संबंधित मुद्दे

 संबंधित मुद्दे