Creating new object with dynamic variables in PHP - php

I want to create a new object using this
$procedure = new ${$s.'\\'.$p};
It doesn't work. Why isn't this possible?

Why don't you
$name = "$s\\$p";
$procedure = new $name;
?
Also ${$s.'\\'.$p} means a variable, with a variable name that is clearly not good. If you are, and I think you are, trying to get something like an instance of Namespace\Class you should try with the code below.
I think that the {} shortcut only works with this syntax ${} which is clearly referring to a variable. So you cannot use it for instantiating new objects.

Related

Variable class call and namespace in PHP

Using a variable containing the name of a class then creating a new instance of that class, I have a question on the way I call the class in the variable.
My code works:
use AppBundle\Entity\someEntity;
$entityName = "AppBundle\Entity\someEntity";
$instance = new $entityName();
Now, what I would like to do is change the $entityName variable for something more simple like $entityName="someEntity";
Anyone have any idea on how to do that?
I am using PHP5.5
Thanks

What is the scope of constructor injected variables?

Is there a difference between this
$dependency1 = array();
$dependency2 = new SomeObject;
$di = new OtherObject($dependency1, $dependency2);
and this?
$di = new OtherObject(array(), new SomeObject);
In the first example, the $dependency vars are being exposed to the global scope, this is obvious. But what about the second example? Does it create encapsulation?
Is the same true for arguments passed into public methods as well?
I would test it, but I'm not sure how to go about it...
In second case, you won't be seeing those two parameters, unless you know, that OtherObject's constructor assigns them to some public properties.
The first method leaves two references to the parameters in global space. That's about it. Use the first method if there are additional components the need to be injected with the same shared dependencies.

Why can't I place this object into an array?

In PHP, you can normally place an object in an array, like so:
class Car{}
$car = new Car();
// This runs without error
$array['vehicle'] = $car;
I have a custom MVC framework I've built, and I need the controller to get an ORM object from the model, so it can pass that to the view. So, I initialize my user object:
$user = new User(2);
Now, I want to put that user object into a $data array so it can be passed to the view:
($user->data returns an ORM object)
$array['user'] = $user->data;
The problem is, after doing this, I receive the following error:
Object of class ORM could not be converted to string
What am I doing wrong? Is there something I'm missing?
Thanks for any help in advance.
Edit: Here's what $user->data refers to, this is from the constructor of class User:
$this->data = ORM::for_table("users")->find_one($this->user_id);
(I'm using Idiorm as an ORM)
If you get an error message like:
Object of class ORM could not be converted to string
The first question you should ask is, "why does it have to be converted to a string"? An array can take a string just fine, so you can guess that $data is actually a string and PHP thinks you want to modify $data[0].
As you've seen, dynamically typed languages can leave befuddled if you aren't careful.
When your variables show suspect behavior, try to see what's actually in them using var_dump().
It's also a good idea to explicitly initialize arrays (eg: $my_array = array();) before using them.

Stop new object from updating with old object's variables

I'm trying to do something like:
$obj2 = $obj1
where $var1 is an object, the problem is that I want $obj2 to be like a snap shot of $obj1 - exactly how it is at that moment, but as $obj1's variables change, $obj2's change as well. Is this even possible? Or am I going to have to create a new "dummy" class just so I can create a clone?
Simply clone the object, like so:
$obj2 = clone $obj1;
Any modifications to the members of $obj1 after the above statement will not be reflected in $obj2.
Objects are passed by reference in PHP. This means that when you assign an object to new variable, that new variable contains a reference to the same object, NOT a new copy of the object. This rule applies when assigning variables, passing variables into methods, and passing variables into functions.
In your case, both $obj1 and $obj2 reference the same object, so modifying either one will modify the same object.

Create a new copy of object itself with some new properties

Sometimes it's difficult to explain in human language what you want to do in programming, but I will try...
Please explain to me, how can I implement the following logic. Suppose we have a template class:
$obj1=new Tmpl($somevar1, $somevar2, ...);
//we then add a new file to template
//as we don't have any files yet, new object won't created
$obj1->AddTmpl('file1.tmpl');
//we add a second file to template,
//it will be independent template
//but all properties from $obj1 must be available
$obj2=$obj1->AddTmpl('file2.tmpl');
$obj1->printTmplFile(); //should output file1.tmpl
$obj2->printTmplFile(); //should output file2.tmpl
$obj2->printInitialVars();
//will print $somevar1, $somevar2 constructed for $obj1;
//$obj1 of course must have these variables available also
So, the purpose of it is in creating new object for each new file of a template. Each new object should have all set of properties which have been established for old object. So, in this case, for example, we will not call a constructor each time with the same arguments. Also only $obj1 can create a copy of itself. And if it is first call to method AddTmpl, then we don't create new copy.
(Here I assume that the AddTmpl function does not return a copy of the object itself.)
The following line is wrong. You are saving the result of the AddTmpl function into $obj2, this does not return a copy of $obj1.
$obj2=$obj1->AddTmpl('file2.tmpl');
You have to use cloning like this:
$obj2 = clone $obj1;
$obj2->AddTmpl('file2.tmpl');
Note that after the cloning, $obj2 and $obj1 are totally independant and any changes made to one will not be reflected to the other. This is the intended purpose!
More information about cloning: http://php.net/manual/en/language.oop5.cloning.php
Edit: fixed typo in code
I'm not sure if it's what you're trying to do, but have a look at php's object cloning.
Possible yes, (with clone in the addTmpl() function)
But thats not adviseable, the API you're showing in the question not directly understandable / selfexplanatory.
Other solutions are:
$tpl = new Tmpl();
$tpl->render('template1.tmpl');
$tpl->render('template2.tmpl');
Or
$tpl = new Tmpl();
$tpl->setTmpl('template1.tmpl');
$tpl2 = clone $tpl;
$tpl2->setTmpl('template2.tmpl');
$tpl1->render();
$tpl2->render();

Categories