Page 1 of 1
Passing object messages back and fourth
Posted: Wed Sep 10, 2003 12:55 pm
by JPlush76
Hey all,
I'm trying to get message passing between objects down in my cranium.
I have two classes I want to talk to each other:
1. user class = registers a user
2. validation class = verify data
for example lets say I'm doing a sign up form, user enters in a username and I want to check that user name and if its good - let them register
in the user class I want to set the username from the form and verify its in the right format using the validator class.
Here comes my question....
When using methods of other objects do I need to do a $object = NEW class ? or can I just include that class file and call its methods?
Actually I wanna know what the best way is (most proper for OO)
Right now if I have a class that uses another class I do a NEW in the constructor
Any thoughts? thanks.. I hope that was semi clear. lol
Code: Select all
<?php
class user{
function user()
{
// SET ERROR CLASS
$error = new validation_class();
}
function register()
{
// call to validation class
$error->is_numeric($string);
}
} // end class
?>
Posted: Wed Sep 10, 2003 4:24 pm
by JPlush76
I tested it and both ways seem to work actually, so I guess it comes down to does it matter how its done or is there one way thats better?
does using "NEW CLASS" in a class file use up more memory than using class::method ?
I'm including both sets of test code I used:
Code: Select all
<?php
class user
{
var $username;
function set_username($field)
{
error::isEmpty($field, 'Please enter a valid username');
}
function set_password($field)
{
error::isEmpty($field, 'Please enter a valid password');
}
function return_errors()
{
if (sizeof(error::getErrorList()) > 0)
{
$errors = error::getErrorList();
echo "<font color="#000000">The Following Errors Occured: </span><p>";
echo "<ul class='error'>";
foreach ($errors as $e)
{
echo "<li>" . $e['msg'];
}
echo "</ul></font>";
}
}
}
class error
{
var $_errorList;
// check whether input is empty
function isEmpty($field, $msg)
{
if (trim($field) == "")
{
$this->_errorList[] = array("field" => $field, "value" => $value, "msg" => $msg);
return false;
}
else
{
return true;
}
}
// return the current list of errors
function getErrorList()
{
return $this->_errorList;
}
}
$reg = new user();
$reg->set_username('');
$reg->set_password('');
$reg->return_errors();
?>
and the 2nd way
Code: Select all
<?php
class user
{
var $username;
function user()
{
$this->error = new error();
}
function set_username($field)
{
$this->error->isEmpty($field, 'Please enter a valid email address');
}
function return_errors()
{
if (sizeof($this->error->getErrorList()) > 0)
{
$errors = $this->error->getErrorList();
echo "<font color="#000000">The Following Errors Occured: </span><p>";
echo "<ul class='error'>";
foreach ($errors as $e)
{
echo "<li>" . $e['msg'];
}
echo "</ul></font>";
}
}
}
class error
{
var $_errorList;
// check whether input is empty
function isEmpty($field, $msg)
{
if (trim($field) == "")
{
$this->_errorList[] = array("field" => $field, "value" => $value, "msg" => $msg);
return false;
}
else
{
return true;
}
}
// return the current list of errors
function getErrorList()
{
return $this->_errorList;
}
}
$reg = new user();
$reg->set_username('');
$reg->return_errors();
?>
?>
Posted: Wed Sep 10, 2003 8:27 pm
by McGruff
OK.. I'd wait until the site gurus have had their say before taking any of this as gospel but here's my take.
AFAIK, the :: syntax essentially treats the class as a function library but does not create an instance of the object - ie you can't tee it up with an initial state.
Instead, instantiating the object let's you start it up with a constructor. In this case, it doesn't seem to make much difference but I'd personally always use the latter though.
I THINK the :: syntax is intended more for avoiding ambiguities in inherited classes where parents and childs share the same method names. Pulling out methods one at a time from an object which was presumably designed to encapsulate them all as a unit doesn't sound like a good idea in general.
Other options you didn't mention are to instantiate the second class outside the first class, then pass it in (by ref). Inheritance could be another option although not for this particular example.
The Gruff (Duff?) Rule
If the two objects work in tandem, link them by instantiating one inside the other or by using inheritance.
If they basically work independently, it's better to instantiate them independently and make each a property of the other (passing by ref) if you need to allow them to communicate.
For example, I was busy refactoring last night and ended up splitting a paginator class into two objectss: one to get the paged $query and one to set a page 1 | 2 | etc nav link.
Separating means I can change the nav link format easily but the classes still have to work closely together - sharing many vars. So the nav link class gets instantiated inside the paginator class (at the same time passing the creator to it**). When I tried them independently I ran into all sorts of problems and temporal dependencies (Ach Captain! A temporal dependency! The engines cannae handle it!").
Your errors class, on the other hand, looks to me to be completely independent of any other objects, so I'd instantiate it in the calling script and pass it in by ref. That way it's also available to any other objects you might add to the script.
-------------------------------
**A instantiates B as one of its properties and passes $this as an arg to B - ie A creates an object containing a reference back to A. This allows B to access all the properties and methods of A. It's all getting a bit star trek again: A contains B which contains A which contains B.. etc. "Captain! We're trapped in an unknown multi-dimensional phenomena at brain warp 9!"
My two cents
Posted: Thu Sep 11, 2003 1:55 pm
by phpScott
Just to add on to what McGruff said.
Unless you are going to have a large number of large objects, memory or speed probably isn't going to be an issue.
I would say that if you are going to need other methods or properties of the class that is not instatiated then create an object as it will save time later. Other wise just accessing the one method that you need using the :: is fine with me.
I'm not sure what the proper OO way is but since the :: method is used in Java ,where everything is an object, I would think that it is an acceptable standard to use.
phpScott
Posted: Thu Sep 11, 2003 2:05 pm
by JPlush76
its very interesting to me that using :: kept the state of the Error List variable. You would think it would overwrite it, but it kept its value like I was instasiating it.
Posted: Thu Sep 11, 2003 7:06 pm
by McGruff
JPlush76 wrote:its very interesting to me that using :: kept the state of the Error List variable. You would think it would overwrite it, but it kept its value like I was instasiating it.
I THINK what is happening here is as follows:
// inside ClassA..
ClassB::method();
When called from ClassA with ::, "$this" in the fn definition of method() refers to the object ClassA and not ClassB (which has not been instantiated).
So, you are declaring properties in ClassA and NOT in a second object, ClassB.
That's my take anyway.
Pulling out methods one at a time from an object which was presumably designed to encapsulate them all as a unit doesn't sound like a good idea in general.
I was probably wrong to say this - I guess there's no reason why you can't use the correct interface calling methods with ::
I'm slightly suspicious of :: because I'm not sure I understand it 100% - one day that last few per cent will jump up and bite me
