php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51126 class_exists + namespaces
Submitted: 2010-02-23 18:41 UTC Modified: 2010-02-23 19:02 UTC
From: richard at rjharrison dot org Assigned:
Status: Not a bug Package: SPL related
PHP Version: 5.3.1 OS: linux
Private report: No CVE-ID:
 [2010-02-23 18:41 UTC] richard at rjharrison dot org
Description:
------------
class_exists() is not calling my spl_autoload_register'ed function with a fully qualified (namespaced) class name.

Because the input to my autoload function is not fully qualified, it cannot load the class and class_exists return false; however, if I try to instantiate the class that "does not exist" then the correct, fully qualified class now passed to the autoloader: it correctly loads the class and my code works.

Reproduce code:
---------------
// register my autoloader

use Foo\Things;

// This fails: my autoload function is called with $class = 'Things\Car'
if(class_exists('Things\Car')){
    echo "class exists!";
}else{
    echo "Weird?";
}


// This works: my autoload function is called with $class = 'Foo\Things\Car'
$x = new Things\Car(); 



Expected result:
----------------
"class exists!"

Actual result:
--------------
"Weird?"

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-02-23 18:46 UTC] johannes@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

When used as a string we need the fully qualified name as we don't know where the parameter is coming from.
 [2010-02-23 19:02 UTC] richard at rjharrison dot org
Hi Johannes,

I double-checked the documentation and found no mention that the string passed to class_exists() must be fully qualified. Perhaps this is a documentation bug.

It is certainly seems inconsistent/counter-intuitive:-

class_exists('Things\Car'); // FALSE, class does not exist
$car = new Things\Car(); // HUH? Class does exist after all

So PHP is able to figure out there is a "use Foo/Things" namespace in effect on one line, but not on the other? Lame.
 [2011-10-10 10:37 UTC] dmittner at llnw dot com
I agree that this behavior is counter-intuitive. I seem to have just run into the same problem, myself, where my autoload works just fine where class_exists() returns false.

In short... class_exists() should really infer the given namespace of the current file, just like it's inferred in all other uses.
 [2012-06-16 06:41 UTC] php dot net at jluis dot com dot ar
I have a very similar problem, not with class exists, but with dynamic instantiation: 

  return ($dynamic? new $className : new SelectMysql);

I can fix it concatenating __NAMESPACE__, but it seems weird that PHP cannot determine this.

Here's a working example:

Select.php
<?php

namespace sql;

abstract class Select {
   abstract function limit($limit, $offset);
   static function factory($dynamic = true) {
       $className = "SelectMysql";
       return ($dynamic? new $className : new SelectMysql);
   }
}
?>

SelectMysql.php
<?php

namespace sql;

class SelectMysql {
   function limit($limit, $offset) {
       return;
   }
}
?>

test.php
<?php

include('Select.php');
include('SelectMysql.php');

// this works
$select = sql\Select::factory(true);

// this does not
$select = sql\Select::factory(true);

?>
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC