Pixel Everywhere

There are only 10 types of people in this world. Those who know binary and those who don't.

Expert OOP in PHP — October 15, 2010

Expert OOP in PHP

This tutorial is the next step to combining and enhancing the concepts of the previous tutorial called Advanced OOP in PHP. We will create a fictional company complete with departments, employees, database records, conventions and algorithms.

Advertisements
WordPress —
Advanced OOP in PHP — October 14, 2010

Advanced OOP in PHP

This tutorial is the next step to combining and enhancing the concepts of the previous tutorial called Basic OOP in PHP. We will create a fictional company complete with departments, employees, conventions and algorithms.

Based on the previous tutorial, we created two classes called DepartmentType.php and Employee.php. This time, let’s create a class called Department.php and add a few methods to manipulate an employee class.

include_once 'Employee.php';

class Department{
	private var $aEmployees;
	private var $sType
	//
	public function __construct(){
		$this->setType("");
		$this->aEmployees = array();
	}
	//
	public function setType($type){
		$this->sType = $type;
	}
	public function getType(){
		return $this->sType;
	}
	public function addEmployee(Employee $employee){
		//Check for an existing employee.
		for($i = 0; $iaEmployees); $i++){
			if($this->aEmployees[$i] == $employee){
				return false;
			}
		}
		array_push($this->aEmployees, $employee);
		return true;
	}
	public function removeEmployee(Employee $employee){
		//Check for an existing employee.
		for($i = 0; $iaEmployees); $i++){
			if($this->aEmployees[$i] == $employee){
				array_splice($this->aEmployees, $i);
				return true;
			}
		}
		return false;
	}
	public function getEmployees(){
		//Return a clone to avoid modifying the original list.
		return array_slice($this->aEmployees);
	}
}

Let’s first break the code into small pieces.

public function __construct(){
	$this->setType("");
	$this->aEmployees = array();
}

Since this is a constructor, we initialize both the type and the list of employees.

To add a new employee, we need an instance of an employee type in the parameter.

public function addEmployee(Employee $employee){
	//Check for an existing employee.
	for($i = 0; $iaEmployees); $i++){
		if($this->aEmployees[$i] == $employee){
			return false;
		}
	}
	array_push($this->aEmployees, $employee);
	return true;
}

What is does is loop through a list of employees. If it does find a duplicate, the function automatically returns false, which would indicate an unsuccessful insertion. Otherwise, it adds the employee being passed in the parameter and returns true.

The next method is removing an employee based on the employee data type being passed.

public function removeEmployee(Employee $employee){
	//Check for an existing employee.
	for($i = 0; $iaEmployees); $i++){
		if($this->aEmployees[$i] == $employee){
			array_splice($this->aEmployees, $i);
			return true;
		}
	}
	return false;
}

What it does is almost the same with adding, however in reverse order. If it finds the specific requested employee in the list, it removes it and automatically returns true to indicate successful deletion. Otherwise, returns false.

To use it in our company.php file, we do it like this:

include_once 'Employee.php';
include_once 'DepartmentType.php';
include_once 'Department.php';
//
//Create a new employee.
$emp = new Employee();
$emp->setName("Shiela");
//
//Create a department with a specific type.
$dept = new Department();
$dept->setType(DepartmentType::IT);
//
//Add the newly created employee to the department's list.
$dept->addEmployee($employee);
//
//Loop through all the employees of the newly created department and display the name.
for($i = 0; $i getEmployees()); $i++){
	$emp = $dept->getEmployees()[$i];
	echo "$emp->getName() 
"; }

And there you have it. A company complete with one department and one employee. Hope you will get the hang of it and refer later on to the Expert OOP in PHP for the next tutorial that involves saving the content to a database.

Basic OOP in PHP —

Basic OOP in PHP

In this PHP tutorial, you will learn how to structure an object oriented PHP files that can be used in all of your PHP related projects. The tutorial will include concepts, naming conventions and basic algorithms that will help you create better and modularized projects.


What is OOP anyways and why should I use it?

This is the very simple structure of an object in PHP. This will serve as a template and anything you create will have the same initial layout like this.

<?php
class ClassName{
	public function __construct(){
	}
}
?>

The word “__construct” with two underscores at the front is called a constructor. We’ll discuss about constructors in the later part. For now, we must save the file with the same name as the class, which in this case is ClassName.php. Let’s assume that all classes are enclosed with the php declaration tags. From now on, all sample codes will imply that they’re enclosed by the php declaration tags.

Once the layout is done, it is now possible to add custom properties. Let us create a simple object called Employee. An employee is a typical person that is a member of our entire system. Let us imagine our entire system is a fictional company. A person normally in has a name, an id and a type of department where he typically works at.

class Employee{
	private var $sName;
	private var $iID;
	private var $sDepartmentType;
	public function __construct(){
	}
}

Once the properties are declared, we must create accessor methods called getters and setters. Methods are just functions inside a class. These accessor methods can set or return a specific value in which it is assigned to. Let’s create both getters and setters for all the properties.

class Employee{
	private var $sName;
	private var $iID;
	private var $sDepartmentType;
	public function __construct(){
		//Constructor.
	}
	//Getters.
	public function getName(){
		return $this->sName;
	}
	public function getID($id){
		return $this->iID;
	}
	public function getDepartmentType(){
		return $this->sDpeartmentType;
	}
	//Setters.
	public function setName($name){
		$this->sName = $name;
	}
	public function setID($id){
		$this->iID = $id;
	}
	public function setDepartmentType($departmentType){
		$this->sDepartmentType = $departmentType;
	}
}

We can then initialize their values with an empty strings for both name and department types while 0 for the id from the constructor.

public function __construct(){
	$this->setName("");
	$this->setID(0);
	$this->setDepartmentType("");
}

The purpose of a constructor is to renew all the properties. Imagine creating a reset method without creating one. A typical usage of an object in PHP is like this:

$employee = new Employee();

Wherein the word “Employee()” in the line “new Employee()” is the constructor.

Once everything is set up in the Employee.php class file, we can now create another class called DepartmentType.php, which consists different standard department types that are declared as constants.

class DepartmentType{
	const IT = "IT";
	const ENGINEERING = "Engineering";
	const ELECTRONIC_PUBLISHING = "Electronic Publishing";
	public function __construct(){
		//Constructor.
	}
}

Since we now have two classes, let’s now combine them together. In a non-class company.php file, we create a new instance of an employee, assigned to a specific department and display them into the browser.

include_once 'Employee.php';
include_once 'DepartmentType.php';

$angel = new Employee();
$angel->setName("Shiela");
$angel->setID(1);
$angel->setDepartmentType(DepartmentType::IT);

echo "$angel->getName() <br />";
echo "$angel->getID() <br />";
echo "$angel->getDepartmentType() <br />";

Those were your first objects in PHP. We’ve created a fictional company with different types of standard departments and an employee that belongs to that certain department. There is another tutorial called Advanced Object Oriented Programming that provides a wider view in OOP using the examples that were just created.

Event Listeners —

Event Listeners

In this tutorial, you will learn how to create a basic event listener, which includes an understandable name, how to properly cast the calling object and how to efficiently determine certain type of events that’s currently dispatching.


There are infinite ways of naming a listener. Anyone can name it mouseEventListener, onMouseEventListener or onMouseEventDispatch. On my end, I typically name my event listeners according to their class names. For mouse events, I name it mouseEventListener.

public final function mouseEventListener(e:MouseEvent):void{}

Meanwhile, comparing different type of events that fired the event can be done like so:

public final function onMouseEvent(e:MouseEvent):void{
	switch(e.type){
		case MouseEvent.MOUSE_DOWN:
			//
		break;
		case MouseEvent.MOUSE_UP:
			//
		break;
		case MouseEvent.CLICK:
			//
		break;
	}
}

The Event.target method is a generic object type. This makes it dynamic but slow since Flash has to determine its correct data type. Also there are instances wherein you want to display the properties of the target object that is firing the event regardless of its phases. You can do so by casting it to its correct data type.

public final function onMouseEvent(e:MouseEvent):void{
	var i:Item = Item(e.target);
	switch(e.type){
		case MouseEvent.CLICK:
			i.visible = false;
		break;
	}
}

Congratulations. You have successfully created an efficient and easy to read event listener.

Custom Events —

Custom Events

In this tutorial, you will learn how to extend the native Event class to create your own custom events. Though there are many styles and forms this class can achieve, this tutorial will give you the basic way of creating one.


The very basic look of a custom event class is like this.

package Prezire.Mobiles.Games.HiddenObjectGames.Events{
	import flash.events.Event;
	public class ItemEvent extends Event{
		public function ItemEvent(type:String, 
						bubbles:Boolean, 
						cancelable:Boolean = false){
			super(type, bubbles, cancelable);
		}
	}
}

And to use it would be like:

this.dispatchEvent(new ItemEvent("onFound"));

One that’s vaguely used is the concept of creating a literal value in the first parameter. This of course is acceptable however, is considered unreliable for the reason that it could be misspelled. To solve this, you can create a static variable inside the class.

public static FOUND:String = "onFound";

This makes the whole class look like this.

package Prezire.Mobiles.Games.HiddenObjectGames.Events{
	import flash.events.Event;
	public class ItemEvent extends Event{
		public static FOUND:String = "onFound";
		public function ItemEvent(type:String, 
						bubbles:Boolean, 
						cancelable:Boolean = false){
			super(type, bubbles, cancelable);
		}
	}
}

Once the event is dispatched, the listener of that event can then correctly identify, which type of event is firing. In this case “onFound”.

private final function itemEventListener(e:ItemEvent):void{
	switch(e.type){
		case ItemEvent.FOUND:
			//Animate the target to fade out.
		break;
	}
}

In this example, the letter “n” of the word onFound is capitalized. This doesn’t produce an error however, rest assured that your switch-case’s condition won’t be met.

private final function itemEventListener(e:ItemEvent):void{
	switch(e.type){
		case "oNFound":
			//Animate the target to fade out.
		break;
	}
}

Avoid creating another property inside a custom event class unless it is absolutely necessary. In this example, a bonus method is added on any random occassion once the event is dispatched.

package Prezire.Mobiles.Games.HiddenObjectGames.Events{
	import flash.events.Event;
	public class ItemEvent extends Event{
		public static FOUND:String = "onFound";
		private var iBonus:int;
		public function ItemEvent(type:String, 
						bubbles:Boolean, 
						cancelable:Boolean = false){
			super(type, bubbles, cancelable);
		}
		public final function set bonus(value:int):void{
			this.iBonus = value;
		}
		public final function get bonus():int{
			return this.iBonus;
		}
	}
}

Refer to ie.bonus when adding a bonus value during dispatching.

private final function itemClickListener(e:MouseEvent):void{
	var i:Item = Item(e.target);
	switch(e.type){
		case MouseEvent.CLICK:
			var ie:ItemEvent = new ItemEvent(ItemEvent.FOUND);
			if(Math.random() * 3 < 1){
				ie.bonus = 300;
			}
			i.dispatchEvent(ie);
		break;
	}
}

The example above is acceptable however, why not just place the “bonus” method inside the Item class itself like so?

package Prezire.Mobiles.Games.HiddenObjectGames{
	import flash.displays.MovieClip;
	public class Item extends MovieClip{
		private var iBonus:int;
		public function Item(){
			//
		}
		public final function set bonus(value:int):void{
			this.iBonus = value;
		}
		public final function get bonus():int{
			return this.iBonus;
		}
	}
}

And set the bonus value during dispatch like so:

private final function itemClickListener(e:MouseEvent):void{
	var i:Item = Item(e.target);
	switch(e.type){
		case MouseEvent.CLICK:
			if(Math.random() * 3 < 1){
				i.bonus = 300;
			}
			i.dispatchEvent(new ItemEvent(ItemEvent.FOUND));
		}
	}
}

Congratulations! You have successfully created your own custom event class that is considered reliable, efficient and suitable for the class that needs it.

Packages —

Packages

In this tutorial, you will learn how to name your libraries and their packages in an easy and readable way. Though most of these are unorthodox, it will make your packages readable and easier to maintain.


The word com really does mean computer or related to a word .com in the web.  It’s a concept of having a root name that is unique when compared to all other packages that exists in a specific directory.  In this case, the word com actually means the scope of your company. What’s missing typically is the company name. However, most classes nowadays can be used interchangeably either into a web or desktop application. So the point is, it’s OK to remove the scope if the purpose of your library is generic. In short, you can have a template for the three structures: companyname.scope.packagename.

prezire.com.packagename

or

prezire.local.packagename

or

prezire.packagename

Another feature of ActionScript 3’s is it’s ability to distinguish capital letters in package names.  You can actually name them with inter-caps, combined with a plural convention like Com.PackageNames1.PackageNames2.

For instance, I typically name most of my generic personal library packages as:

Prezire.Graphics.TransformTools

or

Prezire.Numbers.Converters

or

Prezire.Strings.RichTextEditors

So if you have multiple classes, you can just name them under the package as:

Prezire.Mobiles.HiddenObjectGames.HiddenObjectGameBasic

and

Prezire.Mobiles.HiddenObjectGames.HiddenObjectGameAdvanced

With this, conflicts can be avoided when having the same class names.  For example, both Senocular and I have a class called TransformTool.as in each of our own libraries.  If I decide to use either of these classes, on a single .as document, I can just say so using a fully qualified class name like so:

var myTool:Prezire.Graphics.TransformTools.TransformTool = new Prezire.Graphics.TransformTools.TransformTool();
var hisTool:Senocular.TransformTool = new Senocular.TransformTool();

Compare your code being like this. The conventional style wherein there is a word com in the first, mixed plural and / or singular package names and all lower cased letters.  The first one is using a singular hiddenobjectgame folder name all in lower case…

import com.mobiles.hiddenobjectgame.HiddenObjectGameIntro;

…to an unorthodox like this, which maintains the plural form of a folder name HiddenObjectGames using inter-caps.

import Prezire.Mobiles.HiddenObjectGames.HiddenObjectGameIntro;

So there you have it. A cleaner and easier to maintain package!