Page 1 of 1

OOP Confusion, need help...

Posted: Fri Oct 27, 2006 11:26 pm
by christian_phpbeginner
Hello,

I have a general interface named Person and a class named Validator for the start. But I need help, see the question below the code, please !....

Then, I create the classes:

Code: Select all

<?php
   
   require ('interface.Person.php');
   require ('class.Validator.php');

   class Employee implements Person {
      
      private $_name;
      
      //constructor for the Employee class
      public function Employee ($name) {
         $validator = new Validator();
          
         //the isChar($param) function is already hard-coded in the Validator class
         if ($validator->isChar($name)) {
            $this->_name = $name;
         } else {
            throw new Exception ('ERROR: Employee name must be characters, not numbers.');
         }
      } //end constructor
      
      //method to set and get the name
      public function _setName ($name) {
         if ($validator->isChar($name) {
            $this->_name = $name;
         }  else {
            throw new Exception ('ERROR: Employee name must be characters, not numbers.');
         }
      }

      public function _getName() {
         if (isset($this->_name)) {
            return $this->_name;
         } else {
            throw new Exception ('ERROR: This employee name has not yet set, please set one.');
         }
      }
   }
?>
Now, when you looked at the code, there is nothing wrong ! But then, I need to create another class, which is class Member. Means that, each time I created another class, I needed to instantiate anothr VALIDATOR class, then use it....When I have 1000 classes of this...I would be die on my sit, only applying and instantiating each classes with Validator....so, please help me.....what should I do to prevent this ?

Thanks,
Chris

Posted: Fri Oct 27, 2006 11:45 pm
by feyd
Composition. Pass the Validator class instance to the constructor for it to store as a reference.

Posted: Fri Oct 27, 2006 11:51 pm
by John Cartwright
Okay, lets start with the obvious first.

1. Firstly, your php allows you to use the magic __construct() method name for constructors, instead of having to reproduce the class name.

Code: Select all

class Employee implements Person {
     
      private $_name;
     
      //constructor for the Employee class
      public function __construct($name) {
2. This method ...

Code: Select all

//method to set and get the name
      public function _setName ($name) {
         if ($validator->isChar($name) {
            $this->_name = $name;
         }  else {
            throw new Exception ('ERROR: Employee name must be characters, not numbers.');
         }
      }
... does not initialize $validator, and should spit out an uninitialize variable or unknown function error. Well come back to this in a moment.

Thirdly, you can initialize the variable once and pass it along to each of the classes. Better yet, use the validator as a static class. I see no reason for the information given to have it as an object (I would generally need to see the class though).

The first method by initializing the variable once and passing it to the classes would look like

Code: Select all

$validator = new validator();
$company = new Company('Some Company Name');
$employees = $company->getEmployees();

$listing = array();
foreach ($employees as $employee)  {
   $listing[] = new Employee($employee, $validator);
}
The second method is more internal, and well avoid creating a new object all together.

Code: Select all

public function __construct($name) {
         //the isChar($param) function is already hard-coded in the Validator class
         if (!Validator::isChar($name)) {
            throw new Exception ('ERROR: Employee name must be characters, not numbers.');
         }

         $this->_name = $name;
      } //end constructor

Posted: Sat Oct 28, 2006 12:36 am
by christian_phpbeginner
Hi, thanks for the responses..

To feyd:
Thanks feyd !...

To Jcart:
Thanks for the great examples.

1) About the constructor:
I use PHP 5, but the _construct() for the constructor of my classes won't work. So, if I write....

Code: Select all

<?php
   class Employee implements Person {
      private $_name;
      public function _construct($name) {
         $this->_name = $name;
      }

      public function getName() {
          return $this->_name = $name;
      }
   }
?>
..then I use the Employee class and echo the method of getName(), I won't get any output. But, when I use the same name of my class name, it works.

2) About your method:
[quote = "Jcart"]

Code: Select all

$validator = new validator();
$company = new Company('Some Company Name');
$employees = $company->getEmployees();

$listing = array();
foreach ($employees as $employee)  {
   $listing[] = new Employee($employee, $validator);
}
[/quote]

I'm sorry, not meant to criticize, but I am really confuse about static class ?? Does it mean static method ? Right at the $validator = new validator();. Did you intend that the new validator() not uses the capital letter ? Or is it the way that you create static class in PHP ?

Your approach is nice, but is it possible to do something like:

Code: Select all

$validator = new Validator ('Employee');
But I don't know how...And I am not sure that by passing the Employee as a parameter I can validate its attribute of Employee object ?

Thanks,
Chris

Posted: Sat Oct 28, 2006 12:40 am
by feyd
The magic method constructor has two underscores, not one.

_construct() vs __construct()

Posted: Sat Oct 28, 2006 12:43 am
by christian_phpbeginner
feyd wrote:The magic method constructor has two underscores, not one.

_construct() vs __construct()
LOL....didn't notice that ! hahaha....thanks for that ! But would it actually a problem when the constructor name is the same as the class name ?

Posted: Sat Oct 28, 2006 12:48 am
by feyd
The constructor being the same as the class name is the older (PHP 4) style. As long as you only have one form of the constructor method, PHP won't complain that I've had happen. I wouldn't necessarily say you have to use one over the other, but I will say that the trend appears to be moving toward the magic style.

Re: OOP Confusion, need help...

Posted: Sat Oct 28, 2006 1:20 am
by Christopher
From your original code I think maybe is could be something like:

Code: Select all

class Employee implements Person {
      
      private $_name;
      private $_validator;
      
      //constructor for the Employee class
      public function __construct ($name) {
         $this->_validator = new Validator();
          
         $this->_setName ($name);
      } //end constructor
      
      //method to set and get the name
      public function _setName ($name) {
         if ($this->_validator->isChar($name)) {
            $this->_name = $name;
         }  else {
            throw new Exception ('ERROR: Employee name must be characters, not numbers.');
         }
      }

...

Posted: Sat Oct 28, 2006 3:30 am
by christian_phpbeginner
feyd wrote:The constructor being the same as the class name is the older (PHP 4) style. As long as you only have one form of the constructor method, PHP won't complain that I've had happen. I wouldn't necessarily say you have to use one over the other, but I will say that the trend appears to be moving toward the magic style.
Yes, thank you. __construct() is anyway better, so that anybody knows that it is a constructor.
arborint wrote: From your original code I think maybe is could be something like: ....
Thanks arborint...but is it possible to pass OBJECT, in this case is EMPLOYEE object to Validator object ? And if yes, how do you check Object's attributes, and etc.. ? Please show me just an example or a hint of how doing it, I am still confuse here (how dumm!)...

Now, in Validator class, I have....and I need to reuse the Validator class, so that I can pass an object to the validator class. So it would be like:

Code: Select all

$validator = new Validator('Employee');

Code: Select all

<?php
   class Validator {
       
          /**
   	    * Check for numbers. Returns TRUE if it's, FALSE if it's not
   	    * @name isNumber()
   	    * @param String $postedVariables
   	    * @return boolean
   	    */	   
   	   public function isNumber($postedVariables) {
   	      
   	      	$pattern = '/\d[0-9]*/';
   	      	$matches = preg_match($pattern, $postedVariables);
   	      	
   	      	if (!empty ($postedVariables)) {
   	      	      if ($matches) {   	      	      	 
   	      	         return true;
   	      	      } else {
   	      	   	     return false;
   	      	      } //end nested if-else block
   	      	} else {
   	      		return true;	      	
   	      	}//end main if-else block
   	   } //end function isNumber()
   	   
   	   /**
   	    * Check for characters. Returns TRUE if it's, FALSE if it's not
   	    * @name isChar()
   	    * @param array $postedVariables
   	    * @return boolean
   	    */
   	   public function isChar($postedVariables) {
   	   	   
   	   	   $pattern = '/[a-zA-Z]/';   	   	   
   	   	   $matches = preg_match($pattern, $postedVariables);
   	   	   
   	   	   if (!empty ($postedVariables)) {
   	      	      if ($matches) {   	      	      	 
   	      	         return true;
   	      	      } else {
   	      	   	     return false;
   	      	      } //end nested if-else block
   	      	} else {
   	      		return true;	      	
   	      	}//end main if-else block
   	      	
   	   } //end function isChar()
       }
   }
?>
Many thanks,
Chris

Re: OOP Confusion, need help...

Posted: Sat Oct 28, 2006 3:32 am
by christian_phpbeginner
arborint wrote:From your original code I think maybe is could be something like:

Code: Select all

class Employee implements Person {
      
      private $_name;
      private $_validator;
      
      //constructor for the Employee class
      public function __construct ($name) {
         $this->_validator = new Validator();
          
         $this->_setName ($name);
      } //end constructor
      
      //method to set and get the name
      public function _setName ($name) {
         if ($this->_validator->isChar($name)) {
            $this->_name = $name;
         }  else {
            throw new Exception ('ERROR: Employee name must be characters, not numbers.');
         }
      }

...
Holy....sorry, I'm so stoooopidddd !......You have actually showed me how to pass an object through the constructor then initialize the object within the constructor....holy moly !.....

Thank you ... really appreciate it,
Chris