Instantiated object scope and life time in PHP OOP - php

I want to know when an object in PHP will be destruct (destroy) by default. For example if we instantiate a class in a function, does it destruct at the end of function or still will be alive ?

It will eventually be destroyed when all variables that point to the object cease to exist. Variables cease to exist when they go out of scope or when they are unset. Variables go out of scope when the scope/function they were declared in exits.

Yes, it will. The object will live for the duration that it's instance is in scope. You may wish to browse the PHP Garbage Collection documentation. It's also worth noting that you can try these things out for yourself by implementing a __destruct magic method.

Related

Magic Functions in PHP and their use?

i have been reading about magic functions lately, and I'm really confused about their implementations. Some Magic functions such as __contruct() and __destruct() are very useful. Magic functions like __construct() could be used to initialize variables with default values.
However I'm really confused with the implementation of other magic functions such as __isset(), __call(), __toString(), etc. What is the actual purpose of implementing the Magic Functions.
Yes, I do understand they are invoked behind the scenes and do not require a function call, but then what is their main advantage in real world, in terms of security-sql injection-scope. The main difference between isset() and __isset() (or any other Magic Function) and the situations in which I should use them?
You shouldn't use magic methods in PHP unless you want some documented magic functionality.
They allow you to react to certain events when using these particular objects. This means when certain things happen to your object, you can define how it should react in that instance.
Each of these methods are triggered automatically and you are just defining what should happen under these circumstances.
Probably you won't ever need to use any of them besides __construct() and __destruct() when dealing with objects.
__construct() - Is called when an object is first created. You can inject parameters and dependencies to set your object up.
__destruct() - Is called when an object is destroyed. You can write some cleanup code here. Closing any open datastreams, database connections... whatever.
__get() - Listens for get requests of the properties.
__set() - Listens for set requests of the properties.
__isset() - Triggered by calling isset() or empty() on the object's properties.
__unset() - Triggered by calling unset() on the object's properties.
__toString() - Allows you to define how an object will behave when it's treated like a string.
__sleep() - Code defined here will run before you use serialize(). So you can define which properties of the object should be serialised.
__wakeup() - This is used to reinitialize any tasks that may have been put to stop during the serialization.
__invoke() - Defines how your class should behave if you "invoke" it and use it like a function.
__clone() - Triggered when cloning an object is finished. (If you copy your objects they are still linked to their original as they are still referencing it. Cloning can get you a clean copy.)
__debugInfo - Triggered when using var_dump() on the object. You can use it to control what kind of info should show up in the dump. If the method isn't defined on an object, then all public, protected and private properties will be shown.

Static variable in php without objects

I want to define a php variable that can be accessed in all the scripts and is initialized only one time per runtime. This is, like a static variable but with no object. I thought of using $GLOBALS but noticed the variables do not stick between script executions and I would have to instantiate the variable everytime. So how exactly can I accomplish this? Would I need to create an abstract class only to static the variable?
how about using $_SESSION? see http://www.w3schools.com/php/php_sessions.asp

When (at which moment) is __destruct called?

Is there some assurance when __destruct is called, when considering simple objects without reference cycles? I know from java, that it is not defined when and if the function finalize is called, it depends on the garbage collector.
For example if you have a function like:
1 function test(){
2 $x = new SomeObject();
3 $y = new SomeObject();
4 $x = null;
5 }
Where SomeObject has no reference cycles.
Can you assume $x->__destruct is called at line 4 and $y->__destruct is called at line 5?
Testing the following script seems to indicate that this is true:
https://gist.github.com/KAYLukas/0b1d65e57b52862f8da5
Furthermore, SplFileObject seems to work on this predicate: it is impossible to close the file, instead you just need to set the variable to null. If this would not call __destruct directly it would be impossible to open the file reliable after it has been opened with SplFileObject.
I have found that there is an assurance that the __destruct will be called eventually, just not when.
Yes, you can assume that.
__destruct is always called at the moment where the last reference to the object disappears: when you can't access that object anymore in any way from the outside.
If there exist circular references, you need to wait until it circular garbage collector comes in, where it isn't defined at what point that happens.
If you have stored the object somewhere else too, you need to first remove it from there before the destructor is called.
For further information: Internal objects don't always destruct their resources upon __destruct (as the user might call it directly), but only when the object really is destroyed. (technical measure to prevent segfaults)
Also during shutdown, first variables and arrays are removed in the reverse order they were defined and where the last reference to an object disappears the object is destroyed. Then circular garbage collector comes in and removes the other objects and calls __destruct there.
The only thing which is undefined here, is the order in which the circular garbage collector removes objects and calls their __destruct function.

PHP and access to a global object from everywhere

I have a global object, a "registry", it is a container with other important objects:
Input object.
Output object.
DB object with connection.
Logging object.
Session object.
I need to have this global object in every place (object), where I process my request.
Like in my JBoss environment, where I have one Stateful Session Bean as a front controller, which directs the processing to a special Stateless Session Bean, I have one entry point, "facade.php".
In this facade.php, I create the global object and place the other objects (input object, ...) into it.
Then there is a large switch statement, where I redirect the request to special processing objects.
Is there a method, mechanism, to have access to this general object from the processing objects without handing it over as a parameter?
To have a variable available everywhere you can use a $_SESSION variable like so:
session_start();
$_SESSION['registry'] = // Your data
Make sure to use the session_start() function whenever you want access to the session variables.
What you can do:
put the Object into the Session. http://php.net/manual/en/book.session.php (but this will survive "requests")
Make the Object a singleton. http://en.wikipedia.org/wiki/Singleton_pattern (i recommend this, if its suitable for the situation. don't just use singletons to avoid passing parameters to classes/functions.)
Mark the Object with the global keyword. http://php.net/manual/en/language.variables.scope.php

Deconstructor in PHP

After taking a look at some old code:
//Nothing like a destructor!!
function destroy() {
settype(&$this, 'null');
}
And called by
$Cache->destroy();
However in PHP 5.3 I get
Deprecated: Call-time pass-by-reference has been deprecated in /blah/-cache-.php on line 154
How should I do this?
Your immediate problem can be met by removing the & in $this, but the whole construction doesn't make sense to me. If it's not plain invalid to destroy $this from within the object's context, it's definitely not good practice.
To destroy an object, a simple
unset($Cache);
will do.
If one wants to execute stuff when the object is destroyed, one should define a destructor in the class. (The comment in your destroy() code says that this is not the point here, though. :)
Just destroy the object like normal.
unset($Cache);
I don't know why they would do that nasty looking mess above. Keep in mind that if the object has pointers in different places you will need to unset all of them - not just that one line. (singletons are an example)
The error you're getting is not related to having a destructor. The error is simply because you've tried to pass $this by reference in a function call.
PHP used to allow this, but in current versions of PHP, if you want to pass something by reference, you should specify it in the function declaration.
Therefore, your function call should look like this:
settype($this, 'null');
(ie without the &). (btw -- the word 'null' in a string??? is that what you meant?)
And if you want to pass by ref, your function should look like this:
function settype(&$object, $secondparameter) {
...whatever the function does...
}
ie with the & in the function parameter.
This rule applies in all cases in PHP. As I said, it has nothing to do with your destructor method, or with it being an object; that's just how you pass by reference in modern PHP.
Now onto the other part of your question: A destructor method.
PHP does allow for an automatic destructor function, written within your class like this:
function __destruct() {
print "Destroying " . $this->name . "\n";
}
If you write this code, the __destruct() method will be called when the object is destroyed. This may or may not be what you want -- depends on how you want it to work. The object will be destroyed when all references to it are unset or come out of scope. If you're passing the object handle around by reference, this may not happen when you expect it to -- ie the object may persist in memory even when you say unset($myobject);. In this case, it may only actually get destroyed when the PHP program finishes running. If this is the case, and you need it to be called sooner than that, you may be fine continuing with the destroy() method you have already, and calling it explicity.
Hope that answers your question.

Categories