2015-06-24 12 views
8

diesen Eingang Gegeben:Wie überprüft man, ob ein Element eines Arrays selbst ein Array ist?

[ 
    'key' => 'value', 
] 

Wie das überprüfen, um sicherzustellen, dass:

  1. key Attribut vorhanden
  2. Sein Wert ist ein Array (mit einer beliebigen Anzahl von Elementen)

Ich erwartete diese Bedingung zu arbeiten

$constraint = new Collection([ 
     'key' => new Required([ 
      new Type('array'), 
      new Collection([ 
       'value' => new Required([ 
        new NotBlank(), 
       ]), 
      ]), 
     ]), 
    ]); 

aber es löst eine Ausnahme:

Symfony\Component\Validator\Exception\UnexpectedTypeException: Expected argument of type "array or Traversable and ArrayAccess", "string" given 

Was bin ich?

PS: es ist symfony v2.7.1

PPS: nur zu klären: Ich weiß, dass man einen Rückruf verwenden können. Wenn ich die Validierung manuell von Grund auf neu implementieren wollte, hätte ich symfony nicht von Anfang an verwendet. Die Frage ist also vor allem über Kombination die bestehenden Zwänge und nicht über ein Callback-Constraint mit ..

+0

etwas wie 'if ((is_array ($ a)) oder ($ a instanceof Traversable))' – Umair

+0

@Umair die Frage ist besonders über die Verwendung von Symfony2 Validator – zerkms

Antwort

4

ich die vor genau das gleiche Problem zwei Nächte hatte.

Die Schlussfolgerung am Ende war, dass Symfony2 Validierung keine "Fast-Fail" Validierung hat. Das heißt, auch wenn Ihre -Einschränkung fehlschlagen würde, würde sie mit anderen Einschränkungen fortfahren und daher mit der Ausnahme UnexpectedTypeException fehlschlagen.

aber ich war in der Lage, einen Weg zu finden, dass in Angriff zu nehmen:

$constraint = new Collection([ 
    'key' => new Required([ 
     new Type(['type' => 'array']), 
     new Collection([ 
      // Need to wrap fields into this 
      // in order to provide "groups" 
      'fields' => [ 
       'value' => new Required([ 
        new NotBlank(), 
       ]), 
      ], 
      'groups' => 'phase2' // <-- THIS IS CRITICAL 
     ]), 
    ]), 
]); 

// In your controller, service, etc... 
$V = $this->get('validator'); 

// Checks everything by `Collection` marked with special group 
$violations = $V->validate($data, $constraint); 

if ($violations->count()){ 
    // Do something 
} 

// Checks *only* "phase2" group constraints 
$violations = $V->validate($data, $constraint, 'phase2'); 

if ($violations->count()){ 
    // Do something 
} 

Hoffnung, dass dies hilft ein wenig. Persönlich finde ich es ärgerlich, dass wir das tun müssen. Eine Art "Fast-Fail" -Flag innerhalb validator Service wäre sehr hilfreich.

+1

Das ist endlich etwas, was wie eine Antwort aussieht, danke :-) Noch 3 Tage, bis die Bounty ausläuft, diese ist der einzige Kandidat. – zerkms

1

Verwenden Callback Einschränkung (docs), wo Sie Ihre benutzerdefinierte Validierungslogik implementieren können.

Die andere Möglichkeit besteht darin, benutzerdefinierte Constraint- und Validator-Klassen zu erstellen. (docs)

+1

Was genau schlagen Sie vor? Um alle Symfony2-Einschränkungen neu zu implementieren? Was nützt es, einen Symfony Validator überhaupt zu benutzen? – zerkms

2

Sie sagen, dass die Collection Einschränkung nur statt Auslösen einer Ausnahme fehlschlagen sollte, weil 'value' ein string und kein array.

Es ist ein kürzlich angemeldet Symfony Fehler für diese: https://github.com/symfony/symfony/issues/14943

+0

Constraints haben ein Konzept von sogenannten "Default-Optionen", die im Falle einer 'Type'-Einschränkung' type' sind. Das bedeutet, dass 'new Type (['type' => 'array'])' identisch mit 'new Type ('array')' ist. Siehe https://github.com/symfony/symfony/blob/2.8/src/Symfony/Komponente/Validator/Constraints/Type.php # L32 und https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Validator/Constraint.php#L144 – zerkms

+0

Doing Typ Validierung ist immer "Spaß", weil auf welcher Ebene der tatsächliche Typ Fehler selten klar ist. Tut mir leid, versuche diese neue Antwort. –

+0

"Ihre Eingabe hat die Zeichenfolge 'value' als Wert des Index 'key', der kein Array ist, also wird hier die Ausnahme ausgelöst" --- Ich weiß, warum sie ausgelöst wurde. Die Frage war: Wie schreibe ich eine Einschränkung, die ** ANY INPUT ** akzeptieren würde. Wenn ich garantieren könnte, dass Eingaben immer gültig sind, würde ich keine Validatoren verwenden. "Wenn Sie Ihre Eingabe in" --- ändern würden, würden Sie es buchstäblich auf Ihre Seite stellen: Bitte, liebe Hacker, übergib uns nicht, was wir nicht, außer es stürzt unsere Anwendung ab? – zerkms

Verwandte Themen