php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79440 Object typehint sometimes seems to be misunderstood
Submitted: 2020-03-31 22:18 UTC Modified: 2020-03-31 22:33 UTC
From: lmprogg at gmail dot com Assigned: daverandom (profile)
Status: Closed Package: Class/Object related
PHP Version: 7.3.16 OS: Ubuntu
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: lmprogg at gmail dot com
New email:
PHP Version: OS:

 

 [2020-03-31 22:18 UTC] lmprogg at gmail dot com
Description:
------------
It is difficult for me to make this reproducible.
Short notice on the setup:
A local vm with vagrant and php 7.3.16:

PHP 7.3.16-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Mar 20 2020 13:51:21) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.16, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.16-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

That one does *not* have the problem.

Then there is an aws instance that is running the following version:

PHP 7.3.16-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Mar 20 2020 13:51:46) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.16, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.16-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

This one *has* the problem.

The following happens (I also included a little code snippet, although it may be hard to reproduce).

Whenever a typehint "object" is encountered (in my failing case, it is PHPUnit, but it happens on any typehint "object", even in other functions):

 [TypeError] Argument 5 passed to PHPUnit\Framework\MockObject\Invocation::__construct() must be an instance of PHPUnit\Framework\MockObject\object, instance of Mock_MyClient_070b46a8 given, called in /project/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php(42) : eval()'d code on line 47  

This is the line that does not pass the typecheck: (PHPUnit 9.0.2)

public function __construct(string $className, string $methodName, array $parameters, string $returnType, object $object, bool $cloneObjects = false, bool $proxiedCall = false)

The 5th parameter seems to be misunderstood to be an "object" of the same namespace, instead of the reserved "object" keyword. (which should be passed by the mock passed in)
I first had this in 7.3.9, and then upgraded to the latest 7.3.16, but the problem still persisted on the AWS instance.

I am not sure if this is a bug or just a configuration issue, but it seems that some versions (I am not sure how they differ) are unable to understand this relatively new typehint which was introduced in php 7.2. I included a little snippet that *might* reproduce it. If you need more info, please tell me, it is just a little hard to get it from the aws instance (which is why I did not go haywire and collected everything beforehand).

The code in the snippet should actually just produce a failure because of different contents that are compared, but throws this on the aws instance:

[TypeError] Argument 1 passed to Test\Namespace1\MyTest::getMyResult() must be an instance of Test\Namespace1\object, instance of stdClass given, called in /project/tests/Test/Namespace1/MyTest.php on line 14

(The line number might differ)  

I hope someone might have an idea how this can fit together and guide me in the right direction. Happy to assist with further input. Good night!



Test script:
---------------
<?php

namespace Test\Namespace1;

use Codeception\TestCase\Test;
use stdClass;

class MyTest extends Test
{
    public function testObjectAnnotation()
    {
        $a = new stdClass();
        $a->c = "1";
        $this->assertEquals('anything', $this->getMyResult($a));
    }

    private function getMyResult(object $anything): string
    {
        return $anything->c;
    }
}


Expected result:
----------------
 MyTest: Object annotation
 Test  tests/Test/Namespace1/MyTest.php:testObjectAnnotation
Failed asserting that two strings are equal.
- Expected | + Actual
@@ @@
-'anything'
+'1'
#1  /project/tests/Test/Namespace1/MyTest.php:14


Actual result:
--------------
[TypeError] Argument 1 passed to Test\Namespace1\MyTest::getMyResult() must be an instance of Test\Namespace1\object, instance of stdClass given, called in /project/tests/Test/Namespace1/MyTest.php on line 14


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-03-31 22:24 UTC] lmprogg at gmail dot com
I am sorry, seems that the tests are run with a different version. Could have saved the effort creating this. Late hour. If I double checked that is indeed not only outputting 7.3.16 for the version but actually using it, I'll report back ... :/
 [2020-03-31 22:26 UTC] daverandom@php.net
Just for the sake of sanity, can you double-triple-super check that PHPUnit is executing under the PHP version you think it is? A simple `var_dump(\PHP_VERSION);` in the offending test will suffice.

Also, can you sanity check that there is no `use` statement which affects the name "object" in the file?

Just in the interests of eliminating PEBCAK before going any further :-)
 [2020-03-31 22:27 UTC] daverandom@php.net
Ha, no problem. I'm going to close this bug, if you need to re-report it then open a new one :-)
 [2020-03-31 22:27 UTC] daverandom@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: daverandom
 [2020-03-31 22:33 UTC] lmprogg at gmail dot com
Just a heads up for future reference, I found the problem. No bug in php or anything. It was just tricky to begin with. The aws instance set up a docker image with 7.3.16 that was happily cloning all the dependencies with php >= 7.2, but then delegating the work of executing the tests to another container that ran 7.1. That went unnoticed until now, and I only randomly discovered it due to that error. An easy pitfall to fall into, as the version difference is not really obvious at first sight.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 02:01:28 2024 UTC