php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #77518 SeekableIterator::seek() should accept 'int' typehint as documented
Submitted: 2019-01-24 19:11 UTC Modified: 2019-01-25 10:15 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: claude dot pache at gmail dot com Assigned: nikic (profile)
Status: Closed Package: SPL related
PHP Version: 7.3.1 OS:
Private report: No CVE-ID: None
 [2019-01-24 19:11 UTC] claude dot pache at gmail dot com
Description:
------------
This is related to Bug #71051, but since
https://wiki.php.net/rfc/parameter-no-type-variance
has been implemented, it should be fixable in PHP7.2+ without breaking legacy code.

Per documentation, the signature of SeekableIterator::seek() is:

    abstract public SeekableIterator::seek ( int $position ) : void

However, when implementing the interface, providing the typehint ”int” triggers a compile error.


Test script:
---------------
class Foo implements SeekableIterator {
    function current() { }
    function key() { }
    function next() { }
    function rewind() { }
    function valid() { }

    function seek(int $position) { }
}


Expected result:
----------------
No error.


Actual result:
--------------
Fatal error: Declaration of Foo::seek(int $position) must be compatible with SeekableIterator::seek($position)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-01-24 19:49 UTC] fractalesque at gmail dot com
Hello,

unless I am mistaken, the rfc you link has been passed allowing for type hints to be _widened_, that is, that declaring an untyped variable could pass a typed variable, whereas what you are doing is the inverse.

That is, if the interface was typed with int, you could implement it without the int, but not add the int where the interface declares untyped.
 [2019-01-24 20:07 UTC] claude dot pache at gmail dot com
> unless I am mistaken, the rfc you link has been passed allowing for type hints to be _widened_, that is, that declaring an untyped variable could pass a typed variable, whereas what you are doing is the inverse.

As a picture is worth a thousand words, here is an illustration:

Current situation
-----------------

interface SeekableIterator extends Iterator {
    function seek($position);
}

class LegacyFoo implements SeekableIterator {
    // (implementation of Iterator elided)
    function seek($position) { } // ok
}

class FutureFoo implements SeekableIterator {
    // (implementation of Iterator elided)
    function seek(int $position) { } // Error
}


Proposed change
---------------

interface SeekableIterator extends Iterator {
    function seek(int $position);
}

class LegacyFoo implements SeekableIterator {
    // (implementation of Iterator elided)
    function seek($position) { } // ok (since RFC implemented)
}

class FutureFoo implements SeekableIterator {
    // (implementation of Iterator elided)
    function seek(int $position) { } // ok
}
 [2019-01-25 10:13 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=909d0a3d786118e0b1105288f6b88231e6697815
Log: Fixed bug #77518
 [2019-01-25 10:13 UTC] nikic@php.net
-Status: Open +Status: Closed
 [2019-01-25 10:15 UTC] nikic@php.net
-Assigned To: +Assigned To: nikic
 [2019-01-25 10:15 UTC] nikic@php.net
Adding the int type *should* indeed be backwards compatible nowadays. I've added it on master (7.4) only, since I don't trust that "should" enough to change this on stable branches.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Nov 06 20:01:29 2024 UTC