When do PHP objects die? - php

I'm getting started with objects in PHP and I was wondering when they get deleted. Is it when the PHP file gets finished loading or when it's finished with the function I'm calling? is there anyway to keep the object alive so it can be called in another instance when the file is loaded.

There's a distinction to be made between objects dying and objects being out of scope.
If you are concerned with the logistics of memory management and garbage collection in PHP then as T.J. Crowder pointed out you could read the manual on garbage collection in PHP.
If on the other hand you are more concerned with variable scope, then the answer is that the scope of variables is typically bounded to the block they are declared in. But you can also create global variables, and access them using the global keyword inside of functions - although global variables are generally a bad idea. See the manual for details.
And as far as persisting variables beyond a script, this can only be accomplished via some sort of storage mechanism. In the context of web applications, that is usually accomplished using session state but be careful that the nuances of persisting objects from one session to the next (i.e. one invocation of a script to the next) may be different depending on whether the session state is stored in-process, or out of process. In case it's the latter then the objects will be serialized and deserialzed which makes things a little more complicated.

PHP memory vars is garbage collected, usually they are being removed (decrease ref) when request ends, function out of scope .. etc.
you still can go with singleton pattern, and load only not loaded objects
note that this only works for each single request, if you want to keep the object in memory for more than one request, that's wont work for php,
/**
* Singleton class
*
*/
final class UserFactory
{
/**
* Call this method to get singleton
*
* #return UserFactory
*/
public static function Instance()
{
static $inst = null;
if ($inst === null) {
$inst = new UserFactory();
}
return $inst;
}
/**
* Private ctor so nobody else can instance it
*
*/
private function __construct()
{
}
}
To use:
$fact = UserFactory::Instance();
$fact2 = UserFactory::Instance();
$fact == $fact2;
code example taken from https://stackoverflow.com/a/203359/1291995

Related

Static property of PHP class to keep value until next usage?

I just stumbled over a PHP class and wonder if there was a valid reason for the way one of it's methods is written.
LogUtility::getLogger() is called as a static method in various other PHP classes of the PHP application. Does the used if statement make sense or is $logManager always null when getLogger() is called?
class LogUtility
{
/**
* #var LogManager
*/
protected static $logManager;
/**
* #return Logger
*/
public static function getLogger($name)
{
if (!self::$logManager) {
self::$logManager = GeneralUtility::makeInstance(LogManager::class);
}
return self::$logManager->getLogger($name);
}
}
You could quickly whip up a test, like below, and test / prove it yourself:
class someClass {
protected static $stored;
public static function test() {
echo '<br>Stored state:' . self::$stored;
if ( ! self::$stored) {
self::$stored = "set";
}
}
}
someClass::test();
someClass::test();
Output is:
Stored state:
Stored state:set
So, based on this simple test, the answer is Yes, the if statement makes sense. The static variable is set and maintained.
$logManager is set to a property of the class, so for now, its pretty much an empty class, just returning with a getter, the instance. This just sets the code to just reuse the object. So a bit of recycling code there.
In the class you are now able to play with this object freely. So if you run this LogUtility from another piece of code by setting it to a var, you have already instantiated it. e.g. $util = new LogUtility();now if someone comes along and tries to instantiate it again, $anotherUtil=new LogUtility(); this recycles the class, passing back the already instantiated instance, instead of instantiating a new one.
Therefore, yes, it kept it. Although, the var doesn't contain the "same value" per say, it contains a reference to the "same" class that was instantiated with he other variable, so it ends up a copy of the same instance there.
It will be null for only the first call in a lifecycle. This implements a design pattern called Singleton.
Check out https://sourcemaking.com/design_patterns/singleton/php/1

Scope of Static Members in PHP and Concurrency

I have a class that is declared in my application that has a private static member like so:
class SomeClass{
private static myMember = array();
public static getterFunction(){}
public static setterFunction(){}
}
My question / concern is that multiple requests (i'm thinking like a thread in Java) would be able to modify this static member. My understanding of php scope and static members is that they are in the request scope and a new variable is created for each new request and subsequently destroyed after the request has been fulfilled. That said, this would be a difficult thing to test (at least i can't think of an easy way) so i'd rather be safe than sorry.
Is my assessment correct? The PHP docs i've read are pretty crappy in terms of detail so I haven't been able to authoritatively answer yet...
No data, none, is persistent or shared across different instances of PHP scripts unless you explicitly make it so (for example using sessions, databases, files, shared memory). Each PHP instance is its own thing, and each new request causes the webserver to start a separate instance.
So yes, you are correct.
You don't have shared memory by default in PHP. Every single request is being processed in separate process, so they do not know about each other.
I hope I understood your question correctly.
For example:
You have a simple script.php file that sets private field in a class when GET parameter passed:
<?
class A {
private $x = 1;
public function setX($x) {$this->x = $x;}
public function getX() {return $this->x;}
}
$a = new A();
if (!empty($_GET['x'])) {
$a->setX($_GET['x']);
sleep(3);
}
echo $a->getX();
?>
You do two requests at once:
GET /script.php?x=5
GET /script.php
Second request will print you "1". Yes, you are correct!

Is a singleton class linked to the session in PHP?

I have a singleton class that I am using as part of a CAPTCHA system to generate the code and image etc.
I have one script included on the html form that loads the class singleton, generates the code and image, and outputs it to the browser. I then have another script to validate and process the form. This loads the class singleton to retrieve the instance that was created previously, and calls the function to validate the code.
The problem I'm having is that when I'm validating the form the code that was generated on the form has changed or is completely absent when I come to validate it!
I haven't started or stored anything in the php session, but a session is created on the page the form is loaded in. Is the instance of the singleton somehow linked to that session? If it's a named session or something?
OR...have I completely misunderstood how singleton classes work? In which case can anyone tell me how I can retrieve the instance of the class that is created on the html form page to use again to validate the code in the form processing script? - And maybe tell me how I should be using singletons!
Many thanks.
Singletons exist for the duration of the request, not the duration of the session.
The idea of a singleton is to provide access to the same object across all included scripts, without having to use any explicit initialisation logic.
So, the first call to $foo = MyObject::singleton() creates a new MyObject, but the second call will simply return that object instead of creating a new one. This is incredibly useful for classes that access external resources such as databases and files.
OR...have I completely misunderstood how singleton classes work?
Partially. Since PHP has no ASP.NET alike application variables, objects in PHP live as long as the request does, unless serialized (for example in a session).
As a solution to your problem: save the captcha code (or the captcha class, which is a bit of overkill imho) in a session variable, like $_SESSION['captcha'].
No, it's not.
You'd have to serialize your singleton object and store it to the session when your code execution ends. When the next page is displayed, you can unserialize the object from your session.
PHP serializes/unserializes objects automatically when you assign them to a session.
This only works correctly under the precondition that your singleton does not use link identifiers to external resources.
Here is an example implementation taken from the comments in PHP docs
class SessionSingleton {
/**
* Returns an instance of the singleton class.
* #return object The singleton instance
*/
public static function _instance()
{
// Start a session if not already started
Session::start();
if ( false == isset( $_SESSION[ self::$_singleton_class ] ) )
{
$class = self::$_singleton_class;
$_SESSION[ self::$_singleton_class ] = new $class;
}
return $_SESSION[ self::$_singleton_class ];
}
/**
* Destroy the singleton object. Deleting the session variable in the
* destructor does not make sense since the destructor is called every
* time the script ends.
*/
public static function _destroy()
{
$_SESSION[ self::$_singleton_class ] = null;
}
/**
* Initialize the singleton object. Use instead of constructor.
*/
public function _initialize( $name )
{
// Something...
}
/**
* Prevent cloning of singleton.
*/
private function __clone()
{
trigger_error( "Cloning a singleton object is not allowed.", E_USER_ERROR );
}
private static $_singleton_class = __CLASS__;
}

Why are private variables in an object "visible" from the outside world?

Given this example:
class Database
{
private $host,
$database,
$username,
$password,
$type;
public $active_connection;
//Some methods
}
class Page
{
private $db;
public function __construct($id)
{
// Some code
$this->db = new Database($id);
}
//Some Methods
}
$page = new Page(0);
var_dump($page);
This will output the private variables of Database Object, even though they are marked as private (and so, as I understand it, unusable by the outside world).
My questions are:
Is this a security risk?
Is there a way to effectively hide those variables marked as private?
thanks in advance
EDIT:
In this project, the admin section will provide the ability to create custom PHP scripts to incorporate in the site, as sections. Since this is being developed to a third party entity, my concern is that, for some reason, the costumer inadvertently dumps the $page object (which is, in our code, the main modifiable object) in order to "explore" it.
Encapsulation is an architectural mechanism, not a security measure, and can't be used as such.
How exactly would an attacker exploit this security risk? It's only accessible from inside the source code, so he can as well read the source code for your protected class, or any other source code in the project.
Besides, even in C++ you could get access to private members by preparing a pointer with the right offset into the object.
var_dump() shows them, because it's special. You can also dig around in private/protected properties using the Reflection API.
echo $object->_somePrivateVar;
On the other hand, will not expose _somePrivateVar.
1) Is it a security issue? Not at all. If you don't trust the code you're executing, you're pretty much boned.
2) Hide them from what? They're already hidden according to the data-visibility rules of the class system. But the language is dynamic, and provides some other ways to peek inside. As Leonid just said in his answer, this in an architectural mechanism, not a security feature.
New Magic method __debugInfo() was introduced in PHP 5.6 that will allow you to modify the default behaviour of var_dump() when dumping your objects.
Have a look at the documentation.
Example:
<?php
class C {
private $prop;
public function __construct($val) {
$this->prop = $val;
}
public function __debugInfo() {
return [
'propSquared' => $this->prop ** 2,
];
}
}
var_dump(new C(42));
?>
Returns:
object(C)#1 (1) {
["propSquared"]=>
int(1764)
}
Although this question is 3 years old, I'm sure someone will find this useful in the future.
var_dump is intended for the developer to track and debug the code. From the documentation:
In PHP 5 all public, private and protected properties of objects will be returned in the output.
This is documented behaviour for var_dump (as well as with print_r and var_export). This is intended as a way to gain visibility into your running code; for example, while debugging it you would want to know value of the private variables.
You can trap the output using output control functions, or use var_export if you need to use the private variable's contents in another class. This would be an unusual situation: you would most likely be using a public variable in that case anyway. If you were developing some kind of test suite that needed to verify the contents of private variables, this would be your answer.
I know this is an old question, but I'd like to point out a (fairly) effective means of masking a variable;
You can create a function inside of the class which houses static variables; If you have a variable you really feel needs to be hidden from the system itself, save it into the functions' static variable. As long as that function is private to the class, it becomes very difficult to peek inside. This is O.K. if for some reason your server is dumping values out to userland and you can't control it.
But like TimDev said: if you don't trust the code you're executing, it's a sign that you have some larger security issues. Even if you have a plugin-based project with potential malicious pluin authors, you're simply not going to be able to protect yourself in that environment. It would be up to the administrator who installs those plugins to ensure security.
Check out __debugInfo() magic method in PHP manual how to hide sensitive data from stack traces (added in PHP 5.6.0). Here is an example:
class PDO_Database
{
private $db_user = 'my_user';
private $db_password = 'my_password';
/**
* The purpose of this method is to hide sensitive data from stack traces.
*
* #return array
*/
public function __debugInfo()
{
$properties = get_object_vars($this);
$hidden = [
'db_user' => '***',
'db_password' => '***',
];
return $hidden + $properties;
}
}

Lifetime of a static variable

I'm going through a Joomla book, and I came across the following piece of code in the chapter of MVC pattern:
class QuizController extends JController
{
static function &getInstance(/* some PHP code... */)
{
// use a static array to store controller instances
static $instances;
if (!$instances)
{
$instances = array();
}
/* some PHP code... */
// return a reference to the controller
return $instances[$class];
}
}
What is the lifetime of $instances? When is it destroyed?
If it is alive during the lifetime of the request, then declaring $instances static doesn't make sense, because this code will be run once.
If it is alive during user session, how does PHP engine knows this?
If it is alive during the lifetime of the request, then declaring
$instances static doesn't make sense, because this code will be run
once.
Yes, the static variable only exists for the duration of the request. It's a common design pattern to store an object in a static variable if it's expensive to create, or if having multiple copies will cause problems.
It's not necessarily the case that this function only be called once - it will likely be called multiple times, at least on certain pages / for certain modules.
By the looks of the code, the variable lasts until the script is finished being executed.
Because you can't access the variable from outside that function, and there is no unset() call to that variable, it doesn't get destroyed until the end of script execution.

Categories