2016-10-11 2 views
0

habe ich die Situation auf OptionsResolver Component basiert folgt:Wie mit OptionsResolver Component zwei verwandten Optionen zu normalisieren

  • Ich habe zwei Möglichkeiten: bar und foo, sowohl null standardmäßig.
  • bar Option akzeptiert B Wert auch.
  • foo Option akzeptiert A, B, C, Werte auch. Jetzt

, wenn diese Optionen aufgelöst werden, wenn foo Option A gleich ist, muss bar Option B geändert werden, aber ich brauche auch: wenn foo Option gleich A oder B ist dies C geändert werden muss .


Ich habe versucht, das umzusetzen, aber das erwartete Ergebnis ist falsch:

use Symfony\Component\OptionsResolver\Options; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

$resolver = new OptionsResolver(); 
$resolver->setDefaults(array(
    'bar' => null, 
    'foo' => null, 
)); 
$resolver->setAllowedValues('bar', array(null, 'B')); 
$resolver->setAllowedValues('foo', array(null, 'A', 'B', 'C', 'D')); 

$resolver->setNormalizer('bar', function (Options $options, $value) { 
    if ('A' === $options['foo']) { 
     return 'B'; 
    } 

    return $value; 
}); 

$resolver->setNormalizer('foo', function (Options $options, $value) { 
    if ('A' === $value || 'B' === $value) { 
     $value = 'C'; 
    } 

    return $value; 
}); 

$options = $resolver->resolve(array('foo' => 'A')); 

var_dump($options); 

dies immer wieder:

array(2) { 
    ["foo"] => string(1) "C" 
    ["bar"] => NULL // wrong normalization, expected `B` value. 
} 

Das Problem ist, dass 'A' === $options['foo'] Anweisung in bar normalizer Anrufe zu foo Normalizer (dh $options->offsetGet('foo')), um die Bedingung zu vervollständigen, so dass für diesen Test immer überprüft 'A' === 'C' und bar Option nicht erfolgreich normalisiert.

Wie funktioniert es?

Antwort

0

Nun, es ist ein schreckliches Problem zu umgehen, aber es ist der Code, den ich endlich umgesetzt:

$resolver = new OptionsResolver(); 
$resolver->setDefaults(array(
    'foo' => null, // <-- move to top to make sure to normalize first that bar 
    'bar' => null, // for internal use 
)); 
$resolver->setAllowedValues('bar', array(null, 'B')); 
$resolver->setAllowedValues('foo', array(null, 'A', 'B', 'C', 'D')); 

$bar = null; 

$resolver->setNormalizer('foo', function (Options $options, $value) use (&$bar) { 
    if ('A' === $value) { 
     $bar = 'B'; 
    } 

    if ('A' === $value || 'B' === $value) { 
     $value = 'C'; 
    } 

    return $value; 
}); 

$resolver->setNormalizer('bar', function (Options $options, $value) use (&$bar) { 
    return $bar; 
}); 

$options = $resolver->resolve(array('foo' => 'A')); 
1

IMO ist es nicht zuverlässig, diesen Ansatz zu verwenden. Sie werden sich immer auf die Reihenfolge der Normalisierung verlassen müssen, und es ist sehr leicht, sich zu verirren.

Ich würde eher dritte Option baz verwenden, die nicht geändert wird und wird wie eine Quelldaten für bar und foo.

$resolver = new OptionsResolver(); 
$resolver->setDefaults(array(
    'bar' => null, 
    'foo' => null, 
    'baz' => null, 
)); 
$resolver->setAllowedValues('bar', array(null, 'B')); 
$resolver->setAllowedValues('foo', array(null, 'A', 'B', 'C', 'D')); 
$resolver->setAllowedValues('baz', array(null, 'A', 'B', 'C', 'D')); 

$resolver->setNormalizer('bar', function (Options $options, $value) { 
    if ('A' === $options['baz']) { 
     return 'B'; 
    } 

    return $value; 
}); 

$resolver->setNormalizer('foo', function (Options $options, $value) { 
    if ('A' === $options['baz'] || 'B' === $options['baz']) { 
     $value = 'C'; 
    } else { 
     return $options['baz']; 
    } 
}); 

$options = $resolver->resolve(array('baz' => 'A')); 
+0

Der zweite normalizer gibt 'null' wenn' $ value = ‚C'' bitte, dass beheben zu akzeptieren die Antwort. Danke @Dmitry. – yceruto

+0

Entschuldigung, ich fand eine andere Lösung, um das zu tun, danke trotzdem;) – yceruto

Verwandte Themen