Using Namespaces but not for default classes - php

Since yesterday I am going to use namespaces in php and I have a little problem there:
namespace NamespaceName;
use StdClass;
$s = new StdClass;
$s->meow = "Hello World";
echo $s->meow;
Is there any way that I must not include the "use StdClass"?

You just have to put a backspace in your declaration, so that you use StdClass from the global namespace:
$s = new \StdClass;
//^ See here

Related

Namespace not working when used as variable?

<?php
namespace Vendor\Package;
$test1 = new Foo\Bar(); // works as usual
$test2 = 'Foo\Bar';
$test2 = new $test2(); // does not work
$test3 = 'Vendor\Package\Foo\Bar';
$test3 = new $test3(); // but this works
I was looking to use $test2 but it doesn't work even though it looks like it should as it's pretty much the same as $test3 which worked.
Is this expected or is there some syntax I need to use for test2 to work?
When you use a dynamic class name, it has to be fully qualified. The documentation says:
One must use the fully qualified name (class name with namespace prefix). Note that because there is no difference between a qualified and a fully qualified Name inside a dynamic class name, function name, or constant name, the leading backslash is not necessary.
Foo\Bar is not fully qualified, it's relative to Vendor\Package that you selected with the earlier namespace statement.
You can prefix your strign with __NAMESPACE__
Vendor\Package\Foo\Bar::__construct
Vendor\Package\Foo\Bar::__construct
Vendor\Package\Foo\Bar::__construct
Repl.it : https://repl.it/repls/BuzzingFairSuperuser
namespace Vendor\Package\Foo;
class Bar
{
function __construct()
{
echo __METHOD__,"\n";
}
}
namespace Vendor\Package;
$test1 = new Foo\Bar(); // works
$test2 = __NAMESPACE__.'\Foo\Bar';
$test2 = new $test2(); // works
$test3 = 'Vendor\Package\Foo\Bar';
$test3 = new $test3(); // works
So I'll see if I can explain this simply. In your first instance "$test1 = new Foo\Bar();", the path to the model is mapped during compile/load time. In the case where "$test2 = 'Foo\Bar'; $test2 = new $test2();", you're trying to call this model during runtime... Unfortunately, at runtime, the linking has already been done, and is not revisited. What this means it that "$test2 = '\Vendor\Package\Foo\Bar'" should work, but a shortened version of the name can't work, as the linking step is not revisited during runtime.

initiate an instance from variable name and namespace in one line

$map_class_name = __NAMESPACE__.'\\'.$map_class_name;
$map = new $map_class_name;
Is it possible to do this in one line like this?
$map = new (__NAMESPACE__.'\\'.$map_class_name);
The above gives
syntax error, unexpected '('
The answer is no, you can't use new with string or expression.
But you can use
$map = new $map_class_name;
Since you use class from current namespace(__NAMESPACE__) you don't have to prefix classname, namespace will be implied.
Alternative solutions
You might use Reflection
$map = (new \ReflectionClass(__NAMESPACE__."\\$map_class_name"))->newInstance();
Another way is to not break line, but I guess this misses the point.
$map_class_name = __NAMESPACE__.'\\'.$map_class_name; $map = new $map_class_name;
IIFE is also possible
$map = (function($n){return new $n;})(__NAMESPACE__."\\$map_class_name");

Use keyword and dynamic class names

use my\Project\FooClass;
$obj = new FooClass(); // ok
$name = 'FooClass';
$obj2 = new $name(); // throws an error that the class wasn't found
Well, I believe the title and the example were pretty enough explanation of my question, so just - why does this throws an error, and how should I deal with this?
Sadly, this is not possible due to the way PHP imports/aliases from namespaces. This can be remedied by using literal namespace definitions, though it no doubt sucks.
As follows:
$r = "my\\Project\\FooClass";
$k = new $r();
There is a patch in the works, or at the very least, it was on PHP's bug report a couple of months back. They will hopefully do something about it.
If it bothers you, you can use class_alias() to remedy it, by the way.
try:
$obj2 = new $name;
Remove the parenthesis
Alternatively:
$obj2 = new {$name}();
Can't explain why this doesn't work. But for how to deal with it:
$name = 'FooClass';
$name = "my\\Project\\FooClass\\" . $name; // prepend namespace
$obj2 = new $name();

PHP, new variable class in namespace

I'm experimenting with PHP 5.3's namespacing functionality and I just can't figure out how to instantiate a new class with namespace prefixing.
This currently works fine:
<?php
new $className($args);
?>
But how I can prepend my namespace in front of a variable classname? The following example doesn't work.
<?php
new My\Namespace\$className($args);
?>
This example yields: Parse error: syntax error, unexpected T_VARIABLE
Try this:
$class = "My\Namespace\\$className";
new $class();
There must be two backslashes \\ before the variable $className to escape it
Here's how I did it:
$classPath = sprintf('My\Namespace\%s', $className);
$class = new $classPath;
Note the single quotes instead of double.

Can I dynamically set new object name

I want to create objects dynamically. Right now I'm creating them manually like this
$obj1 = new Prefix_Myobj();
$obj2 = new Prefix_Other();
$obj3 = new Prefix_Another();
How can I set the part after Prefix_ dynamically? I tried this but it didn't work
$name = 'Myobj';
$obj1 = new Prefix_{$name}();
You need to create a string that specifies the entire class name.
$name = 'Myobj';
$classname = 'Prefix_'.$name;
$obj1 = new $classname();
However, it might be better design to build a class registry of sorts rather than generating class names on the fly like this.
Why do you need this? Maybe there is a better solution for your problem; multiton or dependency injection etc...
It is important to say that if your class is in a specific namespace, you need to inform the full path. Example:
namespace my\path\app;
class MyClass {
$name = 'Myobj';
$classname = 'my\path\app\Prefix_' . $name;
$obj1 = new $classname();
}

Categories