php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78407 Contravariant Parameters bug
Submitted: 2019-08-12 18:55 UTC Modified: 2019-08-12 19:01 UTC
From: damian dot jozwiak dot lodz at gmail dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.4.0beta2 OS: Ubuntu 18.04
Private report: No CVE-ID: None
 [2019-08-12 18:55 UTC] damian dot jozwiak dot lodz at gmail dot com
Description:
------------
When class implement an interface it is not possible to override function parameter.
The code works fine if base function is in class

Test script:
---------------
interface Test{
    public function f1($param);
}
class inherited implements Test {
    public function f1(string $param):\DOMElement{
        return new \DOMElement($param);
    }
}
$data = new inherited();
$node = $data->f1("node");
var_dump($node->nodeName);

Expected result:
----------------
string(4) "node" 

Actual result:
--------------
Fatal error: Declaration of inherited::f1(string $param): DOMElement must be compatible with Test::f1($param) 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-08-12 19:01 UTC] nikic@php.net
-Status: Open +Status: Not a bug -Package: PHP Language Specification +Package: Scripting Engine problem
 [2019-08-12 19:01 UTC] nikic@php.net
This is intentionally not allowed, because it is unsound. You can drop a parameter type, but you can't add one.
 [2019-08-12 19:20 UTC] phpbugreports at gmail dot com
> You can drop a parameter type, but you can't add one

but taht is nonsense, when the parent don#t care about types at all a typehint is a subset of "don't care" and compatible no matter what
 [2019-08-12 21:52 UTC] rowan dot collins at gmail dot com
It's easy to get in a muddle about co- and contravariance, but this error is indeed correct. The promise of the interface is not "I don't care about the type", it's "you can safely pass me any type"; so adding a type constraint ("I only accept string") violates the interface's promise. In technical terms, you are attempting covariance where only contravariance is safe.

You might (or might not) find my attempt to demonstrate the concepts with ASCII art interesting: https://github.com/IMSoP/variance-pipes/
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun May 26 20:01:31 2024 UTC