php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68541 namespace fallback for functions unexpected when defined after usage in class.
Submitted: 2014-12-03 12:17 UTC Modified: 2016-05-31 20:22 UTC
Votes:2
Avg. Score:3.5 ± 0.5
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: markus at malkusch dot de Assigned: cmb
Status: Duplicate Package: Class/Object related
PHP Version: 5.5.19 OS: Linux
Private report: No CVE-ID:
 [2014-12-03 12:17 UTC] markus at malkusch dot de
Description:
------------
PHP's namespace fallback policy for functions is a great feature for mocking built-in functions like time() for unit tests. I'm using this in my mocking library php-mock: https://github.com/malkusch/php-mock

I experienced a suprising behaviour when an unqualified call in a class happened before the definition of the namespaced function. E.g. when calling in foo\Foo time() and defining afterwards foo\time(). I would expect that after that definition time() in foo\Foo would resolve to foo\time(). Instead it resolves to whatever was resolvable during the first call.

In the example you see two cases. In the rand() case I call foo\Foo::rand() first after the definition of foo\rand(). Those assertions are fine and rand() resolves to foo\rand().

In the time case() I call foo\Foo::time() first before the definition of foo\time(). The call after defining foo\time() still resolves to \time(). I would expect here a resolution to foo\time(). If this is intentional the documentation might be more clear about this.

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

namespace foo;

class Foo
{
    
    public static function time()
    {
        return time();
    }
    
    public static function rand()
    {
        return rand();
    }
}

Foo::time(); // If you remove this line all assertions are true.

// It doesn't matter if you eval the namespaced function or include it.
eval("
    namespace foo {
        function time() {
            return 1234;
        }
        
        function rand() {
            return 5678;
        }
    }
");

assert (5678 == rand());
assert (5678 == Foo::rand());

assert (1234 == time());
assert (1234 == Foo::time());

Expected result:
----------------
All assertions are true and time() resolves in the last call to foo\time().

Actual result:
--------------
The last assertion fails, because time() resolves in foo\Foo to \time() even though foo\time() exists.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-01-29 10:32 UTC] gen dot work at gmail dot com
This is probably a duplicate of bug #64346.
 [2016-05-31 20:22 UTC] cmb@php.net
-Status: Open +Status: Duplicate -Assigned To: +Assigned To: cmb
 [2016-05-31 20:22 UTC] cmb@php.net
> This is probably a duplicate of bug #64346.

Indeed. Thanks.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Mon Jun 26 20:01:38 2017 UTC