Stop new object from updating with old object's variables - php

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.

Related

How the 'new' keyword is used with the 'object variable' that already contains 'an object identifier' to some already existing 'object' of some class?

Consider below code from the PHP Manual :
<?php
class Test
{
static public function getNew()
{
return new static;
}
}
class Child extends Test
{}
$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);
?>
Output of above code :
bool(true)
As per my understanding, the object variable $obj1 contains an object identifier which allows object accessors to find the actual object of class Test.
Then, how this object variable named $obj1 has been prefixed with the keyword new when it is being assigned to the variable $obj2?
The object variable $obj1 must contain the object identifier to the object of class Test.
What has been achieved here by using a new keyword with the object variable that already contains some object identifier?
What actually gets compared in the var_dump() statement?
Why is the output of the comparison true?
I'm using PHP 7.3.0
new $obj1 will create a new instance of $obj1::class (which is Test).
The comparison within the var_dump() statetment is a strict comparison between two objects. It returns true because that strict comparison is checking that these two instances ($obj1 and $obj2) are not references the same instance of the the same class.
If the comparison were not strict (e.g. $obj1 != $obj2) it would return false, since $obj1 == $obj2 (e.g. the two have the same attributes and values, and are instances of the same class)
Read more about object comparison on this page in the documentation.
That you are using 7.3 is mostly immaterial. You would have gotten the same results from 5.3 onwards

Why changes on a class affects on other class?

Here is my code: Demo
class myclass1 {
public $myvariable;
}
$obj1 = new myclass1;
$obj2 = $obj1;
$obj1->myvariable = 'something';
echo $obj2->myvariable; //=> something
As you see, I've initialized something to the first object, but surprisingly it will be also applied on the second object. Why really? Actually I need to have two different value in $myvariable for both classes, not the same value.
How can I do that?
That's how OOP works. Actually all you need to know is about pass-by-reference. Take a look at this:
In your code, both $obj1 and $obj2 are using same memory point. So any change on $obj1 will be seen also on the $obj2. To separate them from each other you need to use clone:
$obj2 = clone $obj1;
By cloning an object you are actually making a copy of it. So the new object won't refer to the old one.

Creating new object with dynamic variables in 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.

So what really happens when we use 'new' in PHP

So what really happens when someone say 'new' in PHP
I believe in C/Java, when new is called, memory is allocated for each instance variables that are needed for an object? (correct me if i am wrong)
Is this the same with PHP?
When you use $var = new Class
a new object is created (memory allocated and initialized);
its constructor, if any, is called;
the object is put into a list of objects and given a unique id;
a new zval container1 is created, this container stores, inter alia, the id of the object;
the variable $var is associated with this created zval container.
1 Definition of what's a zval container.
The easiest way would be to check it for yourself using memory_get_usage()
echo memory_get_usage();
$obj1 = new obj1;
$obj2 = new obj2;
$obj3 = new obj3;
echo memory_get_usage();
Same is the case with PHP.
When you say new in PHP, PHP assumes you'd like to call a new Class: PHP Classes Basics.

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