Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:104452 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 66452 invoked from network); 17 Feb 2019 18:40:05 -0000 Received: from unknown (HELO mail-vs1-f48.google.com) (209.85.217.48) by pb1.pair.com with SMTP; 17 Feb 2019 18:40:05 -0000 Received: by mail-vs1-f48.google.com with SMTP id u64so8212451vsc.12 for ; Sun, 17 Feb 2019 07:24:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=0U+kMj/kqminuS4ResLSbLIw+LtyrOqsIDk0R2K+160=; b=dLruciydCb6gjIOWj1SDaQ3AUJJPveAloq00wdFm9rA3LPq6Jml+wDeKvknG/WgQ5X slJEfBQepkrRwg/faFsCgJAv37x5XvgT7g3ZeWBG0gNTJK8bO51bnZd/P/lgmCAu2qXX xWWMWaIwlvumD+UcxTtUZry23Fc9a2ADwsC0i7ooHiGYeSixInnsMcrblQqkQls//LPI /arTAeaAs/px/S4mHd+Dt9GUXgD/bXtdbhjwN9+Qcwx/qMRFVplKGHhP38r3rwzeb/Ym ItoWiUlnGKYN8GabRRVeVCiNoPXN4TwfeP5rNVzcgqkPGpe2Dpp8UrrCe2qTlRvPFxeK RSfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=0U+kMj/kqminuS4ResLSbLIw+LtyrOqsIDk0R2K+160=; b=ZvtS+K4W5QylthO4gsxCDMWr0gOhZoCKq1sC7N5pltdmAX5j3Mce4gqwfXQnYIyH7K MVhIFMYeI9yPa7upqp7jDkGutHaijNIo+6wEYB7Ss1nB7XeD10GdfLFEnnUHv8J3WGmr keOfE81/oRta3GsTPwyAaxNcCyH3seQXa4UNhz0kkzpMCJ8vxwTpM1hTBdj5436/XyqJ 2h7YAIuhofnoHrRRTgJ6xAhpQE5o7aP7EvHmxvA0HUyVT4OyfiHJ5uUD7FPStWDwVFcI b6V7eGKA9rCHu/2fc0XmM8H6CcsD6Ye775tboHos+lcKEkwij7JcKBl4PuUntxNa+8bq Eb4A== X-Gm-Message-State: AHQUAuZ9j5ndfg/jyx+hBzrZxAUYFklivfzHfjoZu6JBxw5p+ZttJZC5 e2tFa+iqmEkFOqRdQufUAevqSNvEH70rfWPs2w9pQg== X-Google-Smtp-Source: AHgI3IYkFt/38181//uotquozb/bXZaIyqmKh0CYDiARbGhYvlJJU3PFDPnu6HM9SF0hQZwy4RLr4XrlkujgeqFFjbc= X-Received: by 2002:a67:874e:: with SMTP id j75mr7282529vsd.12.1550417054667; Sun, 17 Feb 2019 07:24:14 -0800 (PST) MIME-Version: 1.0 Date: Sun, 17 Feb 2019 16:24:05 +0100 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="000000000000cc16fc05821899da" Subject: [PHP-DEV] Allows arrays to be type-hinted with interfaces mimicking Array behaviour From: george.banyard@gmail.com (Girgias) --000000000000cc16fc05821899da Content-Type: text/plain; charset="UTF-8" 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 --000000000000cc16fc05821899da--