php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46373 Type-Hinting with namespaces does not work
Submitted: 2008-10-23 18:50 UTC Modified: 2008-10-24 05:08 UTC
From: phpbugs at sevenlight dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.3CVS-2008-10-23 (snap) OS: OSX 10.5.5
Private report: No CVE-ID: None
 [2008-10-23 18:50 UTC] phpbugs at sevenlight dot com
Description:
------------
Using a type-hint with a namespace does not work.  It allows an object of a different class to be passed, and even allows a bogus namespace to be used.  It will also allow null variables, and will pass through any value, no matter what class type-hinting you use.

Unfortunately, in my simplest test cases I have not been able to reproduce it, it is only in my larger project that it causes this problem.

I really don't know where to start with this, and how to duplicate it.  Needless to say,  have provided the failing code from my project.  The entire project is several thousand lines of code.  And I've really done my best to track down the problem, even using the 5.3-alpha3-dev.

I'll include the code that causes the problem.

I really don't know what's wrong, and why it is doing it.  Any hints as to what I might be able to do to try to reproduce this in a simpler way would be nice, but I really don't know where to go from here.

Reproduce code:
---------------
<?php
namespace MyNamespace;

class MyClass
{
    // execute
    public function execute()
    {
        $this->test(NULL);
        return $this->_execute($this->_mc);
    }
    
    protected function test(MyBogusNamespace::MyBogusClass $m)
    {
        $reflect = new ReflectionClass(get_class($this));
        $method = $reflect->getMethod('test');
        echo $method;
        var_export($m);
        echo "\n\nClass: " . get_class($m) . " == MyBogusNamespace::MyBogusClass\n\n";
    }
}
?>

Expected result:
----------------
Catchable fatal error: Argument 1 passed to MyNamespace::MyClass::test() must be an instance of MyBogusNamespace::MyBogusClass, null given, called in /srv/www/test/ns/new.php on line 9 and defined in /srv/www/test/ns/new.php on line 13


Actual result:
--------------
Method [ <user> protected method test ] {
  @@ /srv/spin/spin4/spinnaker/extender/universal/tablelibrary.php 73 - 80

  - Parameters [1] {
    Parameter #0 [ <required> MyBogusNamespace::MyBogusClass $m ]
  }
}
NULL

 == MyBogusNamespace::MyBogusClass


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-10-23 20:54 UTC] felipe@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 [2008-10-23 21:06 UTC] phpbugs at sevenlight dot com
Can nobody provide any assistance?

I realize I cannot provide a small test-case script, but that is because this exact same script works fine in the smaller test cases.  I am looking for any advice as to how I can help track down the cause of this bug.  If I need to add some debugging code to the PHP source and recompile, or something else, I'm willing to do this, I just need some guidance.  I've covered the extent of what I can come up with to test out inside my PHP code itself, and the bug is at the point where I feel that it would need some modifications to the PHP code for debugging purposes, but I have no experience in debugging the PHP C code.  I can get around debugging C, but not debugging PHP in C.

I know your job is impossible without a test case, but please give me some help in getting you a test case.  The bug is obviously not simple enough that a 10 line test case will trigger it (although maybe it can, but I don't know how to yet).

Thank you,
-Andrew
 [2008-10-23 21:25 UTC] felipe@php.net
Using $x = new myclass; $x->execute();, i got:
Catchable fatal error: Argument 1 passed to MyNamespace::MyClass::test() must be an instance of MyBogusNamespace::MyBogusClass, null given, called ...

If you want accept NULL to be passed, it must be the default value to the parameter.

public function test(MyBogusNamespace::MyBogusClass $m = NULL)

So, we will have...

Method [ <user> public method test ] {
  @@ ... 15 - 22

  - Parameters [1] {
    Parameter #0 [ <optional> MyBogusNamespace::MyBogusClass or NULL $m = NULL ]
  }
}


Thanks.
 [2008-10-23 21:46 UTC] phpbugs at sevenlight dot com
That is not the issue.  The issue is that I DO NOT want NULLs to be accepted, yet they are being accepted (ie. no error be thrown).  The issue is that I want an instance of Class A and if I pass it an instance of Class B, it is still accepted (Class B is not a child of Class A).  The issue is if I pass ANY value of ANY kind if is accepted.  The issue is if I ask for a non-existant class, no error is thrown at all...

In all of these instances, errors should be thrown, but they are not being thrown.  This is why I am seeking advice as to why this might be happening, and how I might be able to debug the actual PHP C code to figure out what is wrong...

-Andrew
 [2008-10-23 22:04 UTC] felipe@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

Well, I can't reproduce it.

namespace MyNamespace;

class foo {
	public function test(bla::foobar $a) {
	}
}

$x = new foo;

#$x->test(new stdclass);
/*
Catchable fatal error: Argument 1 passed to MyNamespace::foo::test() 
must be an instance of bla::foobar, instance of stdClass given ...
*/

#$x->test(NULL);
/*
Catchable fatal error: Argument 1 passed to MyNamespace::foo::test() 
must be an instance of bla::foobar, null given, called in ...
*/

$reflect = new ReflectionClass(__NAMESPACE__ .'::foo');
$y = $reflect->getMethod('test');
#$y->invoke(new foo, 1);
/*
Catchable fatal error: Argument 1 passed to MyNamespace::foo::test() 
must be an instance of bla::foobar, integer given
*/

 [2008-10-24 05:08 UTC] phpbugs at sevenlight dot com
Terribly sorry for wasting your time... set_error_handler() script was hiding the errors...  Again, sorry... :)
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jul 10 06:01:34 2025 UTC