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.
Related
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.
I'm reading few books about PHP and getting stared to grab the basics. I came across “instantiated” and “initialised” words. I can not find an example which explains them.
What is the difference between “instantiated” and “initialised” in PHP ? What do they mean ? How to use them ? What's the purpose of using them ?
Provide an example if possible.
You instantiate an object from a class. I.e. you create an instance (hence the name). In code:
$obj = new SomeClass();
You initialise a variable, which means "giving it its initial (hence the name) value".
$var = "someValue";
In fact, when you instantiate, you also often initialise it (in the constructor). For example:
// this instantiates an object of class 'SomeClass' and
// initialises it with "somevalue"
$obj = new SomeClass("someValue");
Instantiation is a object-oriented programming term. Initialisation is used in all languages. Both terms are certainly not limited to PHP.
Instances are where you have allocated memory for the variable but may or may not have placed a value in there.
Initialized is where you have allocated memory as well as stored an intial value to it as well.
Just adding after reading Barts Answer that object oriented programming usually refers to instances in terms of objects being allocated memory while variables are said to be initialised which means allocated memory and assigned a value as well.
So for example
int $intarray=new Array(); // Instance created
while
int $intarray= new Array({1,2,3}); // instance created and initialised
When you define a class in any object oriented programming language, you create a blue print of an object but the object does not exist. But when you create a copy of that object based on the class or blue print defined, you actually instantiate a class. For example:
//Define a Class called Foo
class Foo {
public $aMemberVar = 'aMemberVar Member Variable';
public $aFuncName = 'aMemberFunc';
function aMemberFunc() {
print 'Inside `aMemberFunc()`';
}
}
// Create an object of type Foo * Instantiate Foo
$foo = new Foo;
Now for Initialised, consider any variable. When you declare a variable, it is there but does not hold any meaningful value. So, the process of assigning a value for the first time to a variable is known as intialisation. Initialisation may happen at the time you declare a variable or may be later programmatically.
Just declare a variable:
var $newVariable;
Intialise the above variable:
$newVariable = "This is intialisation";
Declare and intialise a variable:
var $intialisedVar = "This var is declared and intialised";
Just to add another point in intialisation, see the variables in the class above. These variables will be intialised automatically as soon as you instantiated an object.
Hope this helps.
I was looking for the __destroy() method in ArrayObject but found no implementation.
If I set the variable containing an ArrayObject to NULL, will it correctly destroy all the objects stored in it and free memory? Or should I iterate the ArrayObject to destroy each of the objects before unsetting it?
When you unset or null the ArrayObject only the ArrayObject instance is destroyed. If the ArrayObject contains other objects, those will only be destroyed as long as there is no reference to them from somewhere else, e.g.
$foo = new StdClass;
$ao = new ArrayObject;
$ao[] = $foo;
$ao[] = new StdClass;
$ao = null; // will destroy the ArrayObject and the second stdClass
var_dump($foo); // but not the stdClass assigned to $foo
Also see http://www.php.net/manual/en/features.gc.refcounting-basics.php
In PHP you never really have to worry about memory usage beyond your own scope. unset($obj) will work fine, in your case. Alternatively you could simply leave the function you're in:
function f() {
$obj = new ArrayObject();
// do something
}
And the data will be cleaned up just fine.
PHPs internal memory management is rather simply: a reference count is kept for each piece of data and if that's 0 then it gets released. If only the ArrayObject holds the object, then it has a refcount of 1. Once the ArrayObject is gone, the refcount is 0 and the object will be gone.
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.
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();