Article
PHP5: Coming Soon to a Webserver Near You
The PHP5 Object Model
First, a warning—from here on, things get more intense. There's a lot of ground to cover and I'll be assuming you have knowledge of OOP, as well as a rough idea of how things are in PHP4 today. If you want more detail, please feel free to add to the discussion at the end of this article. Mostly, I'll be leaving it to the code to speak for itself, so you'll probably need to examine it fairly carefully. Feel free to drop questions into the discussion at the end of this article or the Advanced PHP Forums if anything is unclear.
If you've ever done any work with Java, PHP5's object model will be very familiar to you. That's not to say it's the same as Java; there are significant differences in terms of developer-friendliness, and the fact that PHP is a dynamically typed language.
Here, I'll be taking you on a tour with examples. There are already a number resources online (see the end of this article) which offer more information.
Private, Protected and Public
Addressing what is perhaps the #1 complaint leveled at PHP4, you can now declare member variables and methods in your class as being "off limits" for code that’s external to the class. With PHP4, you could get by through exerting some self-discipline, but for some (perhaps those lacking the requisite discipline!) this wasn't enough. So, with PHP5 you can now protect the internals of objects from the outside world, providing access only via the API (Application Program Interface) you've defined.
Private (and Public)?
Here's and example of a private keyword being use to protect a class variable and a class method;
<?php
class Color {
// Available only from within the class
private $rgb = array();
// Note "public" and "var" are basically the same thing
public $colorname = '';
// This method is only available from within the class
private function setRGB ($rgb) {
$this->rgb=$rgb;
}
// "public" is optional
public function setColor($color) {
$colorMap = array (
'white' => array ('r'=>255,'g'=>255,'b'=>255),
'gray' => array ('r'=>190,'g'=>190,'b'=>190),
'yellow' => array ('r'=>255,'g'=>255,'b'=>0),
'black' => array ('r'=>0,'g'=>0,'b'=>0)
);
// Use private method
$this->setRGB($colorMap[$color]);
$this->colorname = $color;
}
// More public methods
function r() {
return $this->rgb['r'];
}
function g() {
return $this->rgb['g'];
}
function b() {
return $this->rgb['b'];
}
function name() {
return $this->colorname;
}
}
$color = new Color();
# Private property - FATAL Error!
// $color->rgb = array ('r'=>255,'g'=>255,'b'=>0);
# Private method - FATAL Error!
// $color->setRGB(array ('r'=>255,'g'=>255,'b'=>0));
$color->setColor('yellow');
echo ( 'Yellow is made from:<br />' );
echo ( 'Red: '.$color->r().' ' );
echo ( 'Green: '.$color->g().' ' );
echo ( 'Blue: '.$color->b().' ' );
?>
Script: private.php
Note that I've used the keyword "public" in the above example as well, just to show it's possible. Effectively, "public" is optional, as any method or class variable that’s not declared as "private" or "protected" defaults to "public" (allowing for backwards compatibility).
Anything declared as "private" is accessible only from inside the class where it’s declared. That means subclasses are barred from access as well. If you create a subclass, you can declare methods and variables with the same name, but they will be separate entities from those declared in the parent.
Protected
Here's an example with a protected variable;
<?php
class Color {
// Accessible only inside this class and subclasses of this class
protected $rgb = array();
var $colorname = '';
private function setRGB ($rgb) {
$this->rgb=$rgb;
}
function setColor($color) {
$colorMap = array (
'white' => array ('r'=>255,'g'=>255,'b'=>255),
'gray' => array ('r'=>190,'g'=>190,'b'=>190),
'yellow' => array ('r'=>255,'g'=>255,'b'=>0),
'black' => array ('r'=>0,'g'=>0,'b'=>0)
);
// Use private method
$this->setRGB($colorMap[$color]);
$this->colorname = $color;
}
function r() {
return $this->rgb['r'];
}
function g() {
return $this->rgb['g'];
}
function b() {
return $this->rgb['b'];
}
function name() {
return $this->colorname;
}
}
class RedFilter extends Color {
function setColor($color) {
parent::setColor($color);
$this->rgb['r'] = 0;
}
}
$color = new RedFilter;
# Protected property - FATAL Error!
// $color->rgb = array ('r'=>255,'g'=>255,'b'=>0);
$color->setColor('yellow');
echo ( 'Yellow filtered by Red is made from:<br />' );
echo ( 'Red: '.$color->r().' ' );
echo ( 'Green: '.$color->g().' ' );
echo ( 'Blue: '.$color->b().' ' );
?>
Script: protected.php
A protected variable (or method) is available to a subclass.