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: 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: richard at rjharrison dot org
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Sun Nov 24 14:01:32 2024 UTC