Why changes on a class affects on other class? - php

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.

Related

Get methods on a standard class?

Is there a way to get all the methods of an instantiated standard class object? I'm talking about an object that has some methods and properties on it, not a fresh stdClass object. ReflectionClass seems to work only on classes.
Try get_class_methods(), sounds like what you're describing, if I understand you correctly.
You can use get_object_vars to get a list of all of the properties, and then iterate over them (or array_filter them) and determine which of them is_callable:
$myClass = new StdClass;
$myClass->someFunc = function($a) {
return $a - 1;
};
$myClass->someProperty = 42;
$properties = get_object_vars($myClass);
$methods = array_filter($properties, 'is_callable');
I'm not sure if it's my 5.4.39 version of PHP or not, but using the above example and instead doing var_dump(get_class_methods($myClass)); as #Mike suggested returns an empty array.

Using defined constants to create objects

Arbitrary PHP question, more/less out of curiosity. I apologize if this is a silly question.
$class = 'ClassName';
$object = new $class();
or
$object = $class::functionName();
This obviously works.
define(CLASS, 'ClassName');
$object = new CLASS();
or
$object = CLASS::functionName();
This does not work.
Just wondering if it is at all possible to use defined constants to create new objects. If not, I definitely understand why.
Well, you can do this:
define(MYCLASS, 'ClassName');
$class = MYCLASS;
$object = new $class();
...but as far as I know, you can't use the constant directly as in new MYCLASS(), because it will of course look for the class named MYCLASS.
Side note: You can't have constants with names that conflict with reserved words, like class or function, even if they are uppercased.
You could do something silly like this if for some reason you're doing this a lot:
function newClass($str, $args = NULL) {
return new $str($args);
}
$class = newClass(MYCLASS);
...but I don't really recommend it. I'd also guess that you probably don't need so many constants, or there's a more elegant way to do what you're doing that doesn't involve constants at all.

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.

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