Class question - multiple objects

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
JPlush76
Forum Regular
Posts: 819
Joined: Thu Aug 01, 2002 5:42 pm
Location: Los Angeles, CA
Contact:

Class question - multiple objects

Post by JPlush76 »

I'm teaching myself more about classes and objects and interacting with multiple objects so here's my question...

I have a user class the user class does things like register user, verify password, etc...

I also have an error class, this class has methods such as is_string, is_numeric, etc... testing input basically.


I would like to keep the user class and the error class seperate but allow them to interact. What is the best way to do this?

For instance lets say I have a page called account.php and on this page I need to register a user so do I include both the error and user class or do I just include the user class and then let the user class include the error class?

What is the best way to interact with objects?

Code: Select all

<?php

class user{

function register()
{
    $error = new error_class();
    $error->is_numeric($string);

}


} // end class
?>
do I create the error object inside the user class? hope this isn't too much ranting. thanks!
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

I've always used on global header_include file for an application which includes all the class definations I need. I know its the not the best way, but its worked well for me. Jason I know has a rather slick class loader he talked about once.

Class often have to depend on each other, especially error/exception classes and the rest of the code.

What I would probably do is but a require_once at the top of the user class for the error class. That way you know you have it, and if you require it elsewhere you won't get messed up.

As to how to have the classes interact. It depends on if you are returning errors or passing errors as parameters. Either method works, but you should be consistent. If you are returning errors its, of course the job of the user class to create the error. If you passing error objects around, you could have the caller create the error object in advance, but that feels wrong to me, in this case. So I'd say in either case for exception/error objects its better to have the class issueing the error create the error instance.

Does this make any sense/ does it help?
JPlush76
Forum Regular
Posts: 819
Joined: Thu Aug 01, 2002 5:42 pm
Location: Los Angeles, CA
Contact:

Post by JPlush76 »

thanks Eric,
I was looking at a turorial online about a user registraion class and he has user signup, error checking, and DB variables all in the class.

It seems the class should be broken out into three 1. user info 2. error checking 3. database extraction

lets take the user class I want...
I set the username variable to what the user posts from a form.

before I set that variable I want to test it so I invoke the error class. I just want to know simply if the field is empty so I pass the variable to the error class.. if the variable does not exist I want to populate an array of errors to be displayed later within the error class.
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Hmm you're not talking about an error class in my mind. You're talking about a valiator class. The two are very different.

Normally an error class is a very lightweight little class used for passing error messages around and/or wrapping up error levels/severity information. Read up on exceptions in JAVA to get a feel for what I thought you were talking about.

Its harder to tell where to stick a validator class. Some people make a form class that handles the form display and validation, ie pushing validation away from the actual datastores. Some people use the "Strategy" pattern from GoF for their validators, etc.

I have a similar project with by DB abstraction class. Basically every object in the system ends up with a saved reference to the db. I could have used a "Singleton" pattern for it, but didn't probably should have. Of course I've also abstracted away a "Storeable-Object" class so typically speaking I'm not writing SQL or invoking the database directly. StoreableObject is an abstract class, that defines postToDB, retrieve, search. The postToDB handles the update/insert issues, retreive is given a primary key and returns the object built from that data stored in the database. Search allows you to set any of the classes attributes and get the list of any keys that match those attributes.
JPlush76
Forum Regular
Posts: 819
Joined: Thu Aug 01, 2002 5:42 pm
Location: Los Angeles, CA
Contact:

Post by JPlush76 »

here is some code samples

this is the main file where I call my user_register object

Code: Select all

<?php
require_once('class_user.php');
require_once('class_error.php');

// CREATE OBJECT
$user = new user_class();

// SET THE USER NAME
$user->set_username('jplush76');

// DISPLAY USER NAME
echo $user->display_user();


// RETURN ANY ERRORS IF PRESENT
echo $user->return_errors();
?>

here is the user class

Code: Select all

<?php
<?php

class user_class
{

var	 $username;

function user_class()
{
                // CREATE THE ERROR CHECKING OBJECT
	$this->error = new ValidateInput();
}



function display_user()
{

	return 'username: '.$this->username;

} // end display user


function return_errors()
{
	if (sizeof($this->error->getErrorList()) > 0)
	{
	
		$errors = $this->error->getErrorList();

		echo "<span class='error'>Errors: </span><p>";
		echo "<ul class='error'>";
		
		foreach ($errors as $e)
		{
			echo "<li>" . $e['msg'];
		}
			echo "</ul>";
	
	}

}





// helper methods

function set_username($username)
{


	$this->error->isEmpty($username, 'bad jimmy');
	

	$this->username = $username;
}



} // end class



?>

and finally here is the simple error class

Code: Select all

<?php
<?

class ValidateInput
{
	
	var $_ERRORS;
	
	function isEmpty($var, $msg)
	{
	
		if($var == '')
		{
			$this->_ERRORS[] =  array("field" => $field, "msg" => $msg);
			return false;
		} else {
		
			return true;
			
		}
	
	} // end is empty
	
	
	
	
	
	// return the current list of errors
	function getErrorList()
	{
		return $this->_ERRORS;
	}
				
				
}
?>

?>
Last edited by JPlush76 on Fri Jun 27, 2003 1:49 pm, edited 1 time in total.
JPlush76
Forum Regular
Posts: 819
Joined: Thu Aug 01, 2002 5:42 pm
Location: Los Angeles, CA
Contact:

Post by JPlush76 »

ohh sorry E, yes I was talking about a Validation class not a true error class
JPlush76
Forum Regular
Posts: 819
Joined: Thu Aug 01, 2002 5:42 pm
Location: Los Angeles, CA
Contact:

Post by JPlush76 »

I think you're right about doing the require_once within the class itself that way I'll know that the class is getting right includes instead of having to worry about each individual page.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

I think you're also in need of message passing. The act of an object passing a message to another object.

As an example, if you consider that a collection of objects all do some slightly different things, it may be needful for these objects to communicate. There are two methods that I know of. One of them is mostly just an idea that I'm working on and less than suitable for a web environment.

1) The first method is to make an object aware of other objects that can fulfill a need for it. This introduces some coupling, but in this case it's good.

2) The idea I have is to create an interrogation mechanism so objects can find other objects that can provide them a service.

The first one is far more feasible at this point so we'll continue with it.

To go on, I have an object for storing sessions in a db. However that object doesn't do any of it's own work against the db. It has another object do it via a command like this:

Code: Select all

$this->db_query->doQuery();
So my sessions object has registered to it a query object of which it knows the interface. The query object provides the service that the sessions object needs. How sweet. :D

Now that we're feeling warm and fuzzy, I would suggest you do something similar for your validation AND error class. To accomplish this, you need to:

Code: Select all

// Pass the error or validation object to let's say your'e db object.
$db_object->setErrorHandler(&$error_object);
Notice the '&'? Won't work otherwise until PHP5. 8O Also, you're not forced to use a set() type method. I pass it in the constructor, even though it's less flexible. Another option is to just do...

Code: Select all

$db_object->errorHandler=&$errorObject;
...which drives the zealots crazy! But who am I to care? :twisted:

Then somewhere in your db class, just dump errors to the error class when an error occurs.

Code: Select all

if($this->doQuery()==false)
    { $this->errorHandler->logError($this->mysql_error()); }
$this->errorHandler being a reference to your errorHandler object.

I hope this helps.

Cheers,
BDKR
Post Reply