Witajcie. Dzisiaj po raz kolejny zmierzymy się z frameworkiem symfony, a konkretnie z jego “wewnętrznym frameworkiem” obsługującym formularze. Jak już zdążyliście się dowiedzieć z kilku wcześniejszych wpisów, jest on bardzo wygodnym narzędziem, jednak jeśli się o pewnych rzeczach po prostu nie wie, to niestety potrafi być także złośliwy i ogłupia programistę niezrozumiałymi komunikatami. Tak też właśnie jest z walidatorem pola , walidator zawsze zwróci komunikat “Invalid.” - oczywiście może być to dowolna inna, ustawiona przez nas wiadomość, co nie zmienia faktu, że formularz nie ma szans przejść walidacji.

Wydawałoby się, że jeśli sam framework nie prostestuje w kwestii otrzymanej konfiguracji, to wszystko powinno bez problemu się uruchomić i zadziałać według naszych oczekiwań. Nic bardziej błędnego - okazuje się, że dane przekazywane do walidatora są nieco inne niż te, których oczekuje pole formularza. Walidator oczekuje samych “kluczy” z tablicy opcji przekazanych do pola. Należy zatem potraktować rzeczoną tablicę funkcją array_keys() i problem zostaje magicznie rozwiązany:

$this->setValidators(array(
	// (...)
	'option' => new sfValidatorChoice(
		array(
			'choices' => array_keys($options),
			),
		),
	// (...)
	));

Podsumowanie.

Z jednej strony twórcy frameworka podjęli dobrą decyzję o takiej, a nie innej implementacji tego walidatora. W końcu nie musi on mieć informacji na temat tego, co się będzie wyświetlało - jego interesują tylko i wyłącznie dane wynikowe przekazane do skryptu obsługującego formularz.

Z drugiej strony jednak uważam, że jest to pewna niekonsekwencja, ponieważ przekazanie tych samych danych do pola formularza i walidatora ma sens “logiczny” - jednemu bytowi mówimy: “idź, wyświetl mi ten zbiór danych”, a drugiemu: “słuchaj, sprawdź, czy ten zbiór danych jest poprawny”. Poza tym, w przypadku programisty, który pierwszy raz styka się z tym problemem jest to o wiele bardziej zrozumiałe i przewidywalne, a więc jeden potencjalny problem mniej. Inną sprawą jest to, że posiadając gotową tablicę, możemy ją po prostu wykorzystać w innym miejscu, a wywołanie array_keys() to zawsze trochę czasu i pamięci “do tyłu”. Oczywiście nie namawiam nikogo do tego typu mikrooptymalizacji, aczkolwiek strata kilku mikrosekund bez wyraźnego celu nie będzie nigdy zbyt szczęśliwym rozwiązaniem.

Dziękuję za wspólnie spędzony czas i zapraszam do dyskusji w komentarzach.