Yii 2 began its life long before PHP 7’s scalar type. Since 7.1, I like to declare type on all method parameters in application code. It’s a habit. But when you declare scalar type on an action method, something nasty happens. I’d like to discuss what we want to do about it in Yii 3.
If controller class
Foo has strict type and
public function actionBar(int $id) then request /foo/bar?id=baz returns 500 server error. That’s wrong. What should happen instead?
Perhaps the framework should help. It could reflect on the action method before calling it, check the input string to see if it is an int. If so, convert it, otherwise return a 400 with a suitable error message. This is functionally a validation and it makes me uncomfortable.
Validation belongs business logic but this would be validation implied by the type of params of methods with a name starting with “action” in classes extending
Controller. The implicit validation runs after filters but before the action. If the app wants something different from this validation the framework provides, e.g. a more specific error message, it can:
- catch the exception in its own
bindActionParams()method, which becomes a real mess,
- drop the type declaration,
- not use action param binding.
I think an app should always be explicit in specifying its validation. Using a type declaration to specify a default validation that the framework provides is dangerous. We ask too much of programmers to understand and remember the special meaning of a type declaration in action method params. Such implicit validation is a foot gun for people a habit of declaring type.
I think the best way forwards might be to drop action param binding altogether from web cntrollers in Yii 3. It’s a bit too magical and it encourages sloppy programming. Otoh, it’s real handy in console controllers.