Consider the following PHP code
namespace foo\bar;
class MyClass {}
namespace xyz;
use foo\bar\MyClass;
class OtherClass {}
$a = new MyClass();
$b = new OtherClass();
$a is an instance of \foo\bar\MyClass, while $b is an instance of \xyz\OtherClass. These fully qualified class names, I can get by calling get_class($a) and get_class($b). But is there a way to get the fully qualified names without instantiating the objects? Is there something like a magic function fully_qualified_class_name such that fully_qualified_class_name('MyClass') would return \foo\bar\MyClass, and fully_qualified_class_name('OtherClass') would return \xyz\OtherClass? Or do I just have to write the fully qualified name myself?
From php 5.5 you can use the class name resolution via ::class
namespace foo\bar {
class MyClass {}
}
namespace xyz {
use foo\bar\MyClass;
class OtherClass {}
echo 'OtherClass namespace: ', OtherClass::class, "\n"; // print "OtherClass namespace: xyz\OtherClass"
echo 'MyClass namespace: ', MyClass::class, "\n"; // print "MyClass namespace: foo\bar\MyClass"
}
Related
Why do I receive an error without using a fully qualified name for Bar?
Foo.php
<?php
namespace Bla\Bla;
require '../../vendor/autoload.php';
class Foo
{
public function getBar()
{
$className="Bar";
$fullClassName='\Bla\Bla\\'.$className;
$obj1=new Bar(); //Works
$obj2=new $fullClassName(); //Works
$obj3=new $className(); //ERROR. Class Bar not found
}
}
$foo=new Foo();
$foo->getBar();
Bar.php
<?php
namespace Bla\Bla;
class Bar {}
$obj1=new Bar();
The statement will work because Bar is defined in namespace Bla\Bla that you are already in.
$obj2=new $fullClassName();
This will work because you are referring to the class from the global namespace.
$obj3=new $className();
This will not work because you try to initiate class Bar from a string, in which the current namespace Bla\Bla is not prepended to the class name.
It would work if you define a class Bar inside the global namespace.
#Bar.php
<?php
namespace Bla\Bla{
class Bar {}
}
namespace {
class Bar {
public function __construct(){ echo 'Hi from global ns!';}
}
}
You have to use the full namespace of the class. Try this: (not tested)
$className="Bla\\Bla\\Bar";
In case the namespace is Bla\Bla.
I have two classes, Class1 and Class2 which are under namespace myNameSpace.
I want to create an instance of Class2 in classand I am getting an error in implementing fileClass 'myNameSpace\Class2' not found in.. `. Code given below:
Class1.php
namespace myNameSpace {
use myNameSpace\Class2;
class Class1
{
public function myMethod()
{
$obj = new Class2();
}
}
call.php
namespace myNameSpace {
include 'Class1.php';
error_reporting(E_ALL);
ini_set('display_errors',1);
use myNameSpace\Class1;
$o = new Class1();
$o->myMethod();
}
If they're both in the same namespace you should not have to use a "use" statement. Seems more likely that you're not simply includeing both files.
Maybe what you're looking for is autoloading? http://php.net/manual/en/language.oop5.autoload.php
namespace foo;
class foo{
}
$foo = new foo();
If I removed the namespace, the class works just fine, if the namespace is there, I get class foo unfound error. What is the reason for this?
If your class is namespaced, then you need to reference that namespace when instantiating (assuming you're in the global namespace when you instantiate).
$foo = new foo\foo();
That's the whole point. You can have multiple foo classes in different namespaces.
namespace foo;
class foo {}
And then...
namespace bar;
class foo {}
And now...
$foo1 = new foo\foo();
$foo2 = new bar\foo();
Read up on how namespaces work: http://it2.php.net/namespaces
Is it possible to use namespace without a class?
For example:
namespace Foo;
// rest of the procedural code and functions
Asking because I have notion that namespace are only used where there are classes.
Thanks for your help.
Yes, you can use namespace without a class, like:
//demo.php file
namespace FooDemo;
function first() { return "First"; }
function second() { return "Second"; }
function third() { return "Third"; }
//test.php file
require_once 'demo.php';
foreach (array("first","second","third") as $funcs) {
echo call_user_func('FooDemo\\'.$funcs);
}
Did you mean something like this
Yes, it is. See the documentation.
Extract:
<?php
namespace Foo\Bar;
include 'file1.php';
const FOO = 2;
function foo() {}
class foo
{
static function staticmethod() {}
}
/* Unqualified name */
foo(); // resolves to function Foo\Bar\foo
foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // resolves to constant Foo\Bar\FOO
/* Qualified name */
subnamespace\foo(); // resolves to function Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // resolves to class Foo\Bar\subnamespace\foo,
// method staticmethod
echo subnamespace\FOO; // resolves to constant Foo\Bar\subnamespace\FOO
/* Fully qualified name */
\Foo\Bar\foo(); // resolves to function Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod
echo \Foo\Bar\FOO; // resolves to constant Foo\Bar\FOO
?>
I namespaced a class to make use of aliases to provide shorthands for some long class names:
namespace some_namespace;
use \VeryLongClassnameWhichIUseOften as Short;
class MyClass {
public static method do_stuff() {
Short::do_something(Short::do_other_stuff());
}
}
Now there is some third party code that expects MyClass in the global namespace.
Can I somehow export MyClass to the global namespace?
I tried
class \MyClass {
...
}
but apparently that is no allowed (unexpected T_NS_SEPARATOR, expecting T_STRING).
I also tried this:
namespace some_namespace {
use \VeryLongClassnameWhichIUseOften as Short;
class MyClass {
...
}
}
namespace {
use \some_namespace\MyClass as MyClass;
}
which doesn't throw any additional error but MyClass still isn't available in the global namespace (Class 'MyClass' not found). I don't quite understand why.
Put this in your global namespace:
use \some_namespace\MyClass as MyClass;
I believe it should work.
Edit: It does not. This should work:
class_alias('\some_namespace\MyClass', 'MyClass');