Greetings internals, I would like to have your opinion on being able to type hint arrays and objects which implement array-like interfaces (notably ArrayAccess, Countable, and Iterator) as currently if a function /method only needs one specific feature of an array and is willing to accept array-like objects. There are some rather repetitive boilerplate and the impossibility of using type hints.
An example of such a function, (where $arrayLike could be custom session object) : /** ArrayAccess|array $arrayLike */ public function checkCSRF($session) { if (!is_array($session) && !($session instanceof ArrayAccess)) { throw new Exception(); } // Check token if (!isset($session['CSRF']) { throw new Exception(); } // Do some more stuff ... } As it can be seen this function/method doesn't need any of the other properties of an array such as Countability or Traversability to do its job. However, in the current state of PHP, it is impossible to accept array-like objects without writing the initial if statement. PHP does have the pseudo-type iterable which allows passing Traversable objects as well as arrays. Moreover, the count function accepts objects which implement the Countable interface. This is achieved with specials checks within the function [1]. My knowledge in C is extremely limited and basic but I see three possible implementations: First one, which seems rather impractical/impossible, is to make arrays "implement" these interfaces by possibly paving the way to object-like arrays. However, this would probably mean a major rewrite in most parts of the engine and impact performance as arrays won't be a basic data structure anymore. (Or maybe only some changes to these magic interfaces in zend_interfaces.c are needed? [2]) The second one, adding new pseudo-types like iterable. [3] This is probably one of the simplest solutions however I don't know how ArrayAccess would be named. Moreover, it seems the least "scalable" in case PHP adds a new interface where arrays can be used (something like Comparable or Sortable comes to mind) Thirdly, adding a special check during type hinting against these interfaces that allows arrays. I am not sure where this should be implemented; possibly in Zend/zend_inheritance.c [4] or within the lexer. However, as I don't know if other parts of the engine would need to be updated I've made a list of possible impacted areas of the engine which comes with this proposal, namely: - Argument type hints - Return types - Typed properties - Covariance and Contravariance Possible disadvantages: - Performance impact as every object type hint now needs to go through the special check - This could/should be implemented with object-like arrays I can't see any other disadvantages so if someone sees some if they could raise them this would be greatly appreciated. Future scope: Possibly changing signatures of some array_* functions? However, they would probably sill need to have separate code paths like count. [1] Best regards George P. Banyard [1] Count function https://github.com/php/php-src/blob/master/ext/standard/array.c#L772 [2] "Magic" interfaces https://github.com/php/php-src/blob/master/Zend/zend_interfaces.c#L579 [3] Fake engine types https://github.com/php/php-src/blob/master/Zend/zend_types.h#L435 [4] Type hint check https://github.com/php/php-src/blob/master/Zend/zend_inheritance.c#L180