OOP in PHP
It’s been a long time since my last post. Sorry for this to all of you who have been looking forward to my next article (yeah, both of you!).
I do like functions. I even try to use functions instead of classes wherever it’s possible - either it’s just because I got used to it by writing PHP for two years (as coding object oriented scripts in PHP 4 was actually impossible), or I’m too stupid to understand the real power of OOP. And even though PHP’s authors have been trying to implement a nice object structure, it still sucks. However, as I consider PHP to be the nicest programming language, I decided to describe its OOP powers.
Why?
Let’s start with the definition of OOP: by using objects, it allows you to keep your code clean and prepared for further development. I suppose you still don’t know what an object is. Think about this: you create a function, let’s call it omg_am_i_pregnant($user), that will check whether the user is pregnant. It actually can return some data, but it’s very difficult to reuse it afterwards. It would probably look like this:
function omg_am_i_pregnant($user) {
if (user_exists($user) && is_pregnant($user)) {
$p = true;
}
}
By doing the same thing with a class called pregnancy, you can easily store the data and send it to, let’s say, a sperm bank.
class Pregnancy {
function __construct($user) {
if (user_exists($user) && is_pregnant($user)) {
$this->p = true;
}
}
}
Now, you may think “WTF are you talking about, the second piece of code is longer and does the same thing”. Yeah, but now, let’s try to check whether Anne, Isabelle and Lucy are pregnant and store the data simultaneously.
$anne = omg_am_i_pregnant('Anne');
$isabelle = omg_am_i_pregnant('Isabelle');
$lucy = omg_am_i_pregnant('Lucy');
The code above won’t work properly, as the function saves the result to the $p variable. Of course, this could be done many other ways, but what if you had to do it this way, using $p?
$anne = new Pregnancy;
$isabelle = new Pregnancy;
$lucy = new Pregnancy();
echo $anne->p;
echo $isabelle->p;
echo $lucy->p;
As you can see from this simple and greatly useless example, you can use classes to manipulate data in the way that the good ol’ procedural programming wouldn’t let you do so. And yeah, you must be wondering what the fuck __construct means.
What?
Before explaining the usage of classes in PHP, we’ll have to cover some terminology. A class is a template for further object creation - it does all the data-related stuff. An object is an instance of a class - it can use all functions and access all data that is available in the class it’s based on. Notice that there is only one class in the example above (pregnancy), but many objects being instances of that class. All the variables that are related to the object are its members (properties), and its functions are called methods. When defining a class, you can define its members and methods. A child class can inherit methods and members from a parent class. These are the basic terms you’ll need in this article; if you want to learn more about classes, head over to the official manual and read more about OOP in PHP 5.
How?
Explaining the usage of objects before explaining how to define a class sounds really stupid - however, as you’re probably going to read the whole article anyway, I think this might be a great idea.
Objects
To create an object, we’ll have to use a variable - let’s call it $object - and a class - let’s call it class.
$object = new class;
$object = new class('argument1', 'argument2');
$member = $object->member;
$object->method('argument1', 'argument2');
Yay, that’s so easy! However, you must remember that an object is just a reference to the class, not a copy of it. Thus, this code:
$object = new DisplayGreeting;
$object->set_greeting('Hey John!');
$another = $object;
$another->use_greeting('Hey Jack!');
echo $object->greeting;
echo " ";
echo $another->greeting;
would echo Hey Jack! Hey Jack! instead of Hey John! Hey Jack!. To welcome John and Jack at the same time, you’ll have to clone the object.
$object = new DisplayGreeting;
$object->set_greeting('Hey John!');
$another = clone $object;
$another->set_greeting('Hey Jack!');
echo $object->greeting;
echo " ";
echo $another->greeting;
Classes
Now, let’s get to classes. You define a class just like a function, except classes don’t take any arguments, thus you don’t have to put any parenthesis after the class’ name.
class TehName [ extends TehParentClass ] {
[ var $member [ = "value"]; ... ]
[ function TehMethodName ($teh, $arguments) { ... } ... ]
}
You can (and should) use the keywords describing items’ (methods and members) visibility when declaring an item; to do this, you should put either public, private or protected before its name. A public declared item can be accessed everywhere; private means that only the class that has defined the item can use it, and protected limits the access to the item to the defining class and all its parent and child classes. When you don’t use any keywords, the item will become public by default.
class Thanksgiving {
public $turkey;
private $participants;
private function is_aunt_mary_coming($bool) {
if(!$bool) { delete_participant($this->participants, "Aunt Mary"); }
}
}
Defining a method works exactly the same way as defining a function. However, you shouldn’t start the name of your method with a double underline (__), as many of them are used by PHP (some of them are described below). Defining a method inside a class allows you to use a very handy $this pseudo-variable, which can be used to refer to the current class (or object).
class DisplayGreeting {
public $greeting;
public function set_greeting($greeting) {
$this->greeting = $greeting;
}
}
Declaring properties isn’t necessary - just like variables, members don’t need any declaration.
class Foo {
public $foo;
private function bar() {
$this->bar = $this->foo;
}
}
A static item is a type of method or property which is called within the class - not the object. To make an item become static, you have to declare it using the static keyword, for instance static function hello_chuck_norris(). To call it afterwards, you don’t need to create an object; just use the class’ name, then a double colon and the item’s name. To call a static item from within a class the item’s been defined in, use self instead of the class’ name. Usage:
class WelcomeChuck Norris {
static $hello_chuck_norris = "Hello, Chuck!";
static function bye_chuck_norris() {
echo 'Bye, Chuck!';
}
}
echo WelcomeChuckNorris::$hello_chuck_norris;
if ($action == 'goodbye') { WelcomeChuckNorris::bye_chuck_norris(); }
Using the final keyword will make an item unoverwritable by the child classes of the current class.
The powers of __double underline__
As I’ve mentioned before, PHP uses many functions that start with a double underline (__). Now, I’ll describe you the most useful ones - and believe me, writing an efficient object-oriented web application without them is almost impossible.
I’m sure you’ve wondered if there’s a way to make a class take arguments. Using the constructor method will allow you to execute any piece of code whenever a new instance of the class is created. The method has to be called __construct (or have the same name as the class). When creating an object, its arguments will be passed on to the constructor.
class Assassinate {
public $target, $assassin;
function __construct($who, $whom) {
$who->terminate($whom);
}
}
$dubya = new Assassinate($TehGreatestTerminator, "George W. Bush");
Destructors, as you’d suppose, are called whenever an object is destructed, for instance when the script is over.
class OhNoes {
public function __destruct() {
$db->query("UPDATE results SET destruction = '" . $this->result . "'");
}
}
When defining or using a member that hasn’t been declared before, you can use the special methods __get() and __set().
class PrintName {
public function __construct($name) {
$this->name = $name;
}
public function __set($member) {
echo $member;
}
}
$print = new PrintName('Jack'); // prints "Jack"
Cloning objects, as described a few paragraphs above, also has a related method, called __clone(). It is called (on the newly created object) whenever you clone an object.
Inheritance
When a child class extends a parent class, it inherits all its methods and properties (unless they’re set to private).
class User {
protected $name, $email;
}
class Admin extends User {
private $username, $password;
private function __construct() {
$this->username = $this->name;
}
}
The child class will overwrite all methods and properties of the parent class if they have the same name. However, you’ll still be able to access the parent class’ items, by using parent::item notation.
Interfaces
An interface is a framework that can be implemented by classes, forcing them to implement all of its methods. Interfaces can implement other interfaces, provided that none of the methods that are defined in the child interface were previously defined in any of its parent interfaces.
interface UserInterface {
function create();
function delete();
}
class User implements UserInterface {
function create($data) {
$db->create_user($data);
}
function delete($id) {
$db->delete_user($id);
}
}
Introspection
in·tro·spec·tion /ˌɪntrəˈspɛkʃən/ [in-truh-spek-shuhn] –noun
1. observation or examination of one’s own mental and emotional state, mental processes, etc.; the act of looking within oneself.
Dictionary.comIn computing, type introspection is a capability of some object-oriented programming languages to determine the type of an object at runtime. This is a notable capability of the Objective-C language, and is a common feature in any language that allows object classes to be manipulated as first-class objects by the programmer.
Wikipedia
Introspection in PHP5 allows you to check the object’s (or class’) attributes such as its name, the parent class’ name, members and methods. Thanks to introspection, you can write applications that will work differently depending on whether the class has inherited particular properties or not. Below, you’ll find the list of the most useful introspection functions, along with the arguments they take and the values they return.
class_exists()uses the class’ name as its parameter, and returns a boolean.get_declared_classes()returns an array of all declared classes.get_class_methods()or (get_object_methods()) returns an array of all methods (including the inherited ones) that have been defined in the given class (or object).get_class_vars()(orget_object_vars()) returns an array of all members (including the inherited ones) that have been defined in the given class (or object).get_parent_class()returns the name of current class’ parent class.class_parents()returns an array of all of the current class’ parent classes.class_implements()returns an array of all the interfaces the given class implements.is_object()checks whether the given variable is an object.get_class()returns the name of the class the given object is based on.method_exists()uses an object and the method’s name as arguments, and returns a boolean.instanceofchecks whether the given object is an instance of the given class or whether the given object implements the given interface. Example usage:if ($object instanceof Class) {}.
To be continued
All the information above will let you write simple OOP-based scripts. However, to understand the true power of object-oriented programming, there are many more things to learn. Be sure to read the second part of the article, explaining more advanced methods of coding good object-oriented applications. Have a good time using classes and objects - hope you enjoyed this post and understood that the true PHP isn’t just functions and control structures.
Thanks to PiotrLegnica for his help.
posted on Sunday, 14th October, 2007 at 21:29 (UTC +1000)
comments feed
leave a response or trackback

April 9th, 2008 at 06:13
Article Opinion <a
May 20th, 2008 at 16:50
A good man would prefer to be defeated than to defeat injustice by evil means.
May 21st, 2008 at 11:39
Eat a third and drink a third and leave the remaining third of your stomach empty. Then, when you get angry, there will be sufficient room for your rage.
May 22nd, 2008 at 06:35
The most remarkable thing about my mother is that for thirty years she served the family nothing but leftovers. The original meal has never been found.
July 20th, 2008 at 20:41
Ìîäóëü Àãðî http://www.modul-agro.com ïðåäëàãàåò îáîðóäîâàíèå è êîìïëåêòóþùèå ïðîèçâîäñòâà Óêðàèíû è Ðîññèè äëÿ ïðåäïðèÿòèé çåðíîïåðåðàáàòûâàþùåé îòðàñëè.
Íàøå ïðåäïðèÿòèå ïðåäëàãàåò âåñü ñïåêòð îáîðóäîâàíèÿ è êîìïëåêòóþùèõ äëÿ çåðíîâîãî, ìóêîìîëüíîãî, êðóïÿíîãî è êîìáèêîðìîâîãî ïðîèçâîäñòâà. Îáîðóäîâàíèå ðîññèéñêèõ ïðîèçâîäèòåëåé ïðîõîäèò ïîëíîå òàìîæåííîå îôîðìëåíèå íà òåððèòîðèè Óêðàèíû è ïîñòàâëÿåòñÿ àâòîòðàíñïîðòîì, æ/ä êîíòåéíåðîì è ïî÷òîâî-áàãàæíûì ñïîñîáîì.
Ñåëüõîçòåõíèêà, ýëåâàòîðû, ëþáàÿ àãðîòåõíèêà, ìåëüíèöû, ìåëüíè÷íîå îáîðóäîâàíèå, çåðíîî÷èñòèòåëüíîå îáîðóäîâàíèå, ìåëüíè÷íîå îáîðóäîâàíèå, ìóêîìîëüíîå îáîðóäîâàíèå, ìåëüíè÷íî-ýëåâàòîðíîå îáîðóäîâàíèå ïî öåíàì íà 5-10% íèæå çàâîäîâ-ïðîèçâîäèòåëåé.