Static (Class Definition) attributes on PHP 5

Static attributes (or methods) can be considered class definition attributes (or methods). They are not accessed from a Class instance but directly from the definition of the class itself, as such they can be accessed directly using the Class_Name::$attribute_name syntax or within the class by the Self::$attribute_name syntax.

The following are a couple of tests of this.

We create a simple class with an Static Attribute


class Static_Test {
	public static $counter = 0;
	function show_counter() {
		echo self::$counter;
	}
	function increase_counter() {
		self::$counter++;
	}
}

Accessing the static attribute from the class definition


echo Static_Test::$counter;

Results: 0

Accessing the static attribute within a method from an instance of the Class


$obj1 = new Static_Test;
$obj1->show_counter();

Results: 0

Modifying the attribute value


Static_Test::$counter++;
$obj1->show_counter(); //1

Results: 1


// $obj1->counter++; //Does Nothing.

Results: nothing. Static Attributes can not be accessed directly, even when declared as public.


$obj1->increase_counter();
$obj1->show_counter(); //2

Results: 2. They can be accessed within methods if the syntax used in the method is appropiate.

Accessing the static attribute within a method from another instance of the Class


$obj2 = new Static_Test;
$obj2->increase_counter();

$obj1->show_counter(); //3

Results: 3. Changes done to a static attribute on an instance are reflected across all instances of the class.

A graphical representation of what we’ve done

Class Definition Attributes Graph

Accessing Static Attributes from a Child Class


class Static_Child_Test extends Static_Test {
	function increase_parent_counter() {
		parent::$counter++ ;
	}
}
$obj3 = new Static_Child_Test;
$obj3->increase_parent_counter();

$obj2->show_counter(); //4

Results: 4.

Accessing Static Methods

The same holds true for static methods. An example:


class Static_Test2 {
	public static function static_method() {
		echo 'This is an static Function. Called directly from the Class Definition and not from an Instance of the Class.';
	}
}

Static_Test2::static_method();

Notes on Attribute Visibility on PHP 5

A couple of years ago when I was studying PHP 5 OOP, I did a couple of scripts to test the different aspects of PHP’s particular object implementation. Since I’m currently migrating a whole bunch of PHP 4 scripts to PHP 5, I’ve decided to consult my notes, which I’m presenting here, plus some explanations for extra clarity.

This are my notes on Attributes and Method visibility within Objects.

First we create a simple class with an attribute (variable) of each type of visibility:


class MyClass {
	public $public = 'public';
	protected $protected = 'protected';
	private $private = 'private';
	function printHello() {
		echo $this->public; echo ', ';
		echo $this->protected; echo ', ';
		echo $this->private;
	}
}

Accessing Attributes Directly


$obj = new MyClass;
echo $obj->public; //Works
//echo $obj->protected; //Fatal Error
//echo $obj->private; //Fatal Error

$obj->printHello(); //Prints Everything.

Access Conclusions

Public attributes can be accessed directly.

Protected and Private can not.

Accesibility in Child classes


class MyClass2 extends MyClass {
	function testPublic() {
		echo $this->public; //Prints "Public".
	}
	function testProtected() {
		echo $this->protected; //Prints "Protected".
	}
	function testPrivate() {
		echo $this->private; //Prints nothing.
	}
}
$obj2 = new MyClass2;
$obj2->printHello(); //Prints everything.
$obj2->testProtected(); //Prints "Protected".
$obj2->testPrivate(); //Prints nothing.

Conclusions

Public and Protected attributes can be accessed in child objects.

Private can not.

Redeclaring (or Overriding ) attributes in Child classes


class myClass3 extends myClass {
	public $public = 'new public value';
	protected $protected = 'new protected value';
	private $private = 'new private value';
}
$obj3 = new MyClass3;
$obj3->printHello(); //Prints "new public value, new protected value, private"

Conclusions

Public and Protected attributes can be redeclared in child objects.

Private can not. If redeclared, the redeclaration will not take effect.

Final Conclusions

Note: The same holds true for object methods.

Encapsulation is the reason behind the separation of methods and attributes by levels of visibility. When refactoring an object, Private methods and attributes can be modified freely since they are only accesible within the object and never directly in the scripts or by inheritance in another objects. Protected makes things a little more complex since even though they can not be accessed directly, they can be accessed, redeclared or overriden by child classes. Lots of care needs to be taken when refactoring Public methods or attributes.

Notes on Object Assignment under PHP 5

This is an extended explanation of the examples on Object Assignment (example 19-5) from OOP5 Basics on the PHP Manual.

The full script can be accessed here

First we create the simple class from the example.


class SimpleClass {
	//member declaration
	public $var = 'default value';
	//method declaration
	public function displayVar() {
		echo $this->var;
	}
}

Creating a New Instance


$instance = new SimpleClass();

What exactly does this do?. It Allocates an space in memory for this new object and then references the variable $instance to this space in memory (representing the instance of the object).

Instance equals new object Graph

Assigning a Variable to an already created object


$assigned = $instance;

References the variable $assigned to the object in memory referenced by $instance.

Assigned equals instance Graph

Referencing a Variable to a variable that references an object


$reference &= $instance;

References the variable $reference not to the object in memory referenced by $instance but to the variable $instance itself.

Reference references instance Graph

Cloning an object


$cloned = clone $instance

Allocate in memory space for a new instance of the Object. Copy all the values from the instance referenced by $instance. References the variable $cloned to this new instance of the object in memory.

Cloned clones instance Graph

Full Picture up to now

If we dump with var_dump all of this (see script). We get the following:

Instance: object(SimpleClass)#1 (1) { ["var"]=>  string(13) “default value” }
Assigned: object(SimpleClass)#1 (1) { ["var"]=> string(13) “default value” }
Referenced: object(SimpleClass)#1 (1) { ["var"]=> string(13) “default value” }
Cloned: object(SimpleClass)#2 (1) { ["var"]=> string(13) “default value” }

A good graphical representation of this is:

PHP 5Object Assignment Script State 1

Changing the value of a Member and then Dereferencing $Instance

Now, we’ll do a couple of changes so as to make all of this even clearer.


//Change variable in instance (will be changed in all but cloned)
$instance->var = 'New value';

//Derefence $instance.
$instance = NULL;

What we have just done is change the value of the member var in Obj 1 and then derefencing $instance to obj1.

Instance equals null Graph

Full Final Picture of the script

Let’s see what happens now when we dump all of the variables (see script). Results:

Instance: NULL
Reference: NULL
Assigned: object(SimpleClass)#1 (1) { ["var"]=> string(9) “New value” }
Cloned: object(SimpleClass)#2 (1) { ["var"]=> string(13) “default value” }

A graphical representation of the final state of our script:

PHP 5Object Assignment Script State 2

Post Archive

Post Categories

Search Posts