Using PHP Generic Objects To Organize Your Code

Written by David Walsh on Wednesday, December 5, 2007


I like using PHP classes to keep my code organized and easy to maintain. I know that they consume more memory than simply using an array or variable system, but if memory is an issue, I’d get more memory. Saving time by coding in a maintainable fashion is more important to me than upgrading a server. I’ve written a very generic, flexible PHP class that I use in my PHP code to get and set variables for use within the page.

The PHP Class

/* generic class */
class generic
{

	var $vars;

	//constructor
	function generic() {  }

	// gets a value
	function get($var)
	{
		return $this->vars[$var];
	}

	// sets a key => value
	function set($key,$value)
	{
		$this->vars[$key] = $value;
	}

	// loads a key => value array into the class
	function load($array)
	{
		if(is_array($array))
		{
			foreach($array as $key=>$value)
			{
				$this->vars[$key] = $value;
			}
		}
	}

	// empties a specified setting or all of them
	function unload($vars = '')
	{
		if($vars)
		{
			if(is_array($vars))
			{
				foreach($vars as $var)
				{
					unset($this->vars[$var]);
				}
			}
			else
			{
				unset($this->vars[$vars]);
			}
		}
		else
		{
			$this->vars = array();
		}
	}

	/* return the object as an array */
	function get_all()
	{
		return $this->vars;
	}

}

Simple Usage

/* simple usage -- just gets and sets */
$person = new generic();

// set sample variables
$person->set('name','David');
$person->set('age','24');
$person->set('occupation','Programmer');

// echo sample variables
echo '<strong>Name:</strong> ',$person->get('name'),''; // returns Name: David
echo '<strong>Age:</strong> ',$person->get('age'),''; // returns Age: 24
echo '<strong>Job:</strong> ',$person->get('occupation'),''; // returns Job: Programmer

// erase some variables -- first a single variable, then an array of variables
$person->unload('name');
$person->unload(array('age','occupation'));

Database Usage

/* database-related usage */
$query = 'SELECT name,age,occupation FROM users WHERE user_id = 1';
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);

$user = new generic();

$user->load($row);
// echo sample variables
echo '</strong>Name:</strong> ',$user->get('name'),''; // returns Name: David
echo '</strong>Age:</strong> ',$user->get('age'),''; // returns Age: 24
echo '</strong>Job:</strong> ',$user->get('occupation'),''; // returns Job: Programmer

Save To The Session, Retrieve From The Session

$_SESSION['person'] = $person->get_all();

/* and on the next page, you'll retrieve it */

$person = new generic();
$person->load($_SESSION['person']);

Let me know your thoughts on this type of class. Do you have any suggestions for improvement?


Follow via RSS Epic Discussion

Commenter Avatar December 05 / #
Gevã says:

Hi, David

(please excuse my bad english speech)

It’s a very good aproach.

I like to use magic functions like __call() in one class called persistence and extend the others, because i use much get and set for organization and encapsulation porpouses.

function __call($method, $args) {
$atributo = strtolower(substr($method, 3, 1)).substr($method, 4);
switch (substr($method, 0, 3)) {
case “get”: return $this->{$atributo}; break;
case “set”: $this->{$atributo} = $args[0];
}
}

this work for generic too. Ex:
class person extends persistence {
/* No code here */
}
$person = new person();
$person->setName(‘David’);
$person->setAge(‘24′);
$person->setOccupation(‘Programmer’);
echo $person->getName(); /* etc */

The persistence have too methods for save, delete, contruct load and other things. So this is possible:

$person = new person(1);
$person->setAge(25) /* Next Year :-D */
$person->save();
$person->delete(); /* No more David :-( */

OBS: Please, how to you make the code PHP look so good?

David Walsh December 05 / #
david says:

I like what you’ve presented here Gevã. Makes sense and I think others will appreciate what you’ve posted!

I use SyntaxHighlighter for the code highlighting — some quick, light-weight javascript and viola — great looking code!

Commenter Avatar December 06 / #
harald says:

why don’t you use php’s array functions in load and unload? you can completely avoid your foreach loops using _faster_ builtin functions. or are those loops just for illustration purpose?

David Walsh December 06 / #
david says:

Thank you for commenting Harald. Which built in functions would you suggest to optimize the code?

Commenter Avatar December 06 / #
Thiago says:

using PDO you can generate the object with the fetch method

http://br.php.net/manual/en/function.PDOStatement-setFetchMode.php

David Walsh December 06 / #
kenman says:

This very much reminds me of the registry pattern. It’s also similar to the PEAR::Config. You should look into those- they’re both mature and look to accomplish what I believe you’re trying to accomplish here.

Commenter Avatar December 06 / #

What benefits do these generic objects have over associative arrays?

Is this done simply for the OO feel? How is the maintainability improved?

$state_of_mind['me'] = ‘confused’;

;)

Commenter Avatar December 06 / #
JP says:

Assuming you want to use php5, why not take what Gevã suggests and take it a step further to make things even easier (IMHO)? Instead of using __call(), use __set() and __get() like this:


function __get($key) { return $this->vars[ $key ]; }
function __set($key,$value) { $this->vars[ $key ] = $value; }

Then you can do something like this:

$person = new generic();
$person->Name = ‘David’;
$person->Age = ‘24′;
echo $person->Name,’ is ‘,$person->Age,”;

Much cleaner and, more importantly, less typing :)

David Walsh December 06 / #
david says:

@Wally: I prefer this over associative arrays mostly because I feel the OO way of set and get is much more “English” friendly. I don’t have a big issue with associative arrays. This method also makes it easier for me to explain the code to others.

@JP: Excellent work with your PHP5 example. Unfortunately, PHP5 isn’t always an option which is why I do things the way I do. Great post though — thank you!

Commenter Avatar December 06 / #

I use this code to append default values to my objects.

function append_default(&$obj)
{
$default = func_get_arg(1);
for($i = 2, $total = func_num_args(); $i < $total; $i++)
$obj->{func_get_arg($i)} = $default;
}

You can call this code like

append_default($some_object,”-”,”name”,”age”);

and the object will have name and age member variables set

Commenter Avatar December 09 / #

Under PHP5 this generic class is a perfect candidate for implementing the Iterator interfase:

http://en.wikipedia.org/wiki/Iterator#PHP

Commenter Avatar December 19 / #

IMHO, your class is too “generic” :)

Seems to be an excuse to use OOP.

I use Objects whenever I feel it is necessary, but I remind myself that every tool has its purpose. I wouldn’t use your class everywhere like you seem to be doing. I would use an ORM: something like Propel or Doctrine or even DB_DataObject (PEAR) or PDO for handling data from an SQL. I would use a class like PEAR’s Config for site-wide variables. I try to avoid re-inventing the wheel and I use stuff that already exists as much as possible.

Your code is very clean and almost perfectly consistent in its format. I like that :) Your braces in your ctor should follow the same format as your other methods.

You should use an existing documentation format like phpDocumentor to automatically generate API docs.

I agree with the others about using magic functions if you would be working in a PHP5 only environment.

Thank you for sharing your thoughts with us. :)

Commenter Avatar July 30 / #
Marc A. Champlain says:

I code only in PHP5 so I don’t know for earlier version, but you could simply do:

$person = (object) null; // or $person = new stdClass();
$person->name = “Marc”;
$person->age = “28″;
echo $person->age;

Commenter Avatar August 08 / #

Hey Dave! Nice class you have there! Did not think about this option before. But anyways, there is a big ‘error’ (if I can call it like that) which I like to point to. It’s not in the code, rather ‘visual’. After the heading “Database Usage” the whole content get’s bold, up to here! Dunno why, but it looks REALLY ugly! Hope you’ll fix that for others :-).

David Walsh August 08 / #
david says:

@Sat: I’ll fix this. Stupid WordPress…

Commenter Avatar June 22 / #
azwan says:

David, thanks for sharing this. I just started learning about OOP and this class really helps. Simple and seems practical.

Anyway, some questions to ask (maybe other ppl can also help)

Will you use this generic class as a class for other classes to inherit/extend?
What about retrieving mulitple records (will it be array in array) in vars?

I’m thinking of using the class for mainly data retrieving/manipulation from database.

Thanks in advance.

David Walsh June 22 / #

@azwan: I don’t do anything too terrible advanced with this class, although you could. That’s the beauty in its simplicity!

Commenter Avatar July 07 / #
Thomas Eng says:

You could alse do:

function puts($s) {
print $s . “\n”;
}

class Object {
function __construct() {
$a = array_shift( func_get_args() );
foreach($a as $key => $value) {
$this->{$key} = $value;
}
}
}
$o = new Object(array( “name” => “John Doe”, “age” => 31) );
puts($o->name);
puts($o->age);

Be Heard!

I want to hear what you have to say! Share your comments and questions below.

Name*:
Email*:
Website:  


© David Walsh 2007-2010. Contact David Walsh. Powered by the remarkable MooTools javascript framework.