0

Example in file 1:

namespace A;

class Foo{

}

file 2:

use A\Foo;

do_stuff('A\Foo');  // <- need namespace here :(

Foo::someStaticMethod();  // <- namespace not required :D

Is there any way I can pass class names in function arguments like constants or something, so I don't need to prepend the namespace?

4 Answers 4

2

Update :)

When I know, that I need to pass the classnames of some classes around as string I'm used to create special class constant

namespace Foo\Bar;
class A {
    const __NAMESPACE = __NAMESPACE__;
    const __CLASS = __CLASS__;
}

Now you can reference the classname like

use Foo\Bar\A as Baz;
echo Baz::__CLASS;

With PHP5.5 this will be builtin

echo Baz::class;

Full-Qualified-Names (FQN) for namespaces always starts with a namespace separator

do_stuff('\A\Foo');

except (and thats the only exception) in use-statements, because there can only appear complete namespace identifiers, so for convenience you can omit it there.

However, a string is a string and where you use it as a class name is out of scope of the interpreter, so it lost the reference to the former use A\Foo-aliasing. With PHP5.5 you can write Foo::class, but I think thats not an option right now ;)

Sign up to request clarification or add additional context in comments.

1 Comment

I'll wait for PHP 5.5 :( But the constant solution is good too :)
1

You could instantiate a new object, then call get_class() to get the fully qualified name for the class.

use A\Foo;

$foo = new Foo();

do_stuff(get_class($foo));  // get_class($foo) = '\A\Foo'

This means that the namespace of Foo is only defined by the use statement (ie. less code maintenance).

3 Comments

Covers not even half of useful use-cases: Usually, when you pass a classname as string, you don't want a object here. Additional: Why do you need the classname, when you even have an object?! Also remind, that there may be constructors ;)
This solutions covers the use case in the question, which is all that is important. It there are other use cases, then the question needs to be expanded.
Do you really assume, that Foo is empty? :D
1

Or you can pass class reflection.

ReflectionClass

Comments

1

No, not without tracing the caller, as far as I know. The function you are calling must exists within the same namespace as the object you are trying to pass.

You might want to have a look at the debug_backtrace function if you require the namespace resolution. But this requires the file-paths to be translated into namespace resolutions or similar.

This is however possible: (I see Andrew has answered with the same type of solution.)

function doStuff ($obj)
{
    $name = (is_object($obj))
        ? (new ReflectionClass(get_class($obj)))->getName()
        : $obj;

    // $name will now contain the fully qualified name
}


namespace Common;

class Test
{}

$testObj = new Test();

// This will work, but requires argument to be
// fully quialified or an instance of the object.
\doStuff($testObj);
\doStuff("\Common\Test");

6 Comments

Even with tracing I don't see a way to fetch the aliases of the callers scope.
Of course not all scenarios are possible, but if the class exists within the given namespace and the namespaces follow specific standards/rules this might be possible to implement for strict usage. I.e. autoloaders that use namespaces for directories in file-path resolution, which will allow for "path to namespace" translation.
Don't know exactly, what you are talking about, but when you define a use-statement and then you use the relative classname within a string, it is not resolvable anymore. No standard can help you: The alias-definitions are resolved during compile-time and thus they are not available at runtime anymore, but the string, .. well, it's a string and remain as it is :D
Yeah, you are right. I completely blocket that possibility. I was thinking of the relative namespace from the caller and not in terms of the by "use" defined resolutions. So this is not possible in that case. But my edit should be OK to use, though it requires an actual instance of the passed object.
Depends ;) I prefer a special class constant like for such cases class A { const __NAMESPACE = __NAMESPACE__; const __CLASS = __CLASS__;}. Now you can use use \Bar\Baz\Foo; echo Foo::__CLASS;.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.