Page 1 of 1

Please help - class abstraction issues

Posted: Sat Mar 05, 2011 6:40 am
by Skidmark
So what I am trying to do now is create an object tree to translate objects into part of a MySQL query (the WHERE clause). I am very close, I just keep getting an error when I try and call the shared class method from one derived classes (inside a function I mean). Basically, I have two sides to this; one object acting as a container for comparison operators that could relate them as AND or OR. These container objects must be nestable (container in container). The other kind of object simply compares a field with a value, ie username = 'Skidmark', or toes >= '9'. My troubles lie in the dump() function of the Combo object:

Here is the parent abstract class:

Code: Select all

abstract class MySQLClause
{

abstract function get()
;
abstract function dump()
;
}
Here are the two files making the field operation value like sequence:

Code: Select all

abstract class Simple extends MySQLClause

{

	protected $field, $value;

	//abstract function get();

	

	//========== RETRIEVAL ==========//

	function get_field()

	{

		return $this->field;

	}

	

	function get_value()

	{

		return $this->value;

	}

	

	function dump()

	{

		echo $this->get_field() . $this->get_value();

	}

	

	//========== ASSIGNMENT METHODS ==========//

	function set_field($new_field)

	{

		if ( is_string($new_field) )

		{

			$this->field = $new_field;

			$return = 1; //Success

		}

		else

		{

			$return = 0; //Wrong input type

		}

		return $return;

	}

}

Code: Select all

class MySQLNumeric extends Simple

{

	var $type;

	

	function __construct()

	{

		

	}

	

	//========== ASSIGNMENT METHODS ==========//

	function set_value($new_value)

	{

		if ( is_numeric($new_value) )

		{

			$this->value = $new_value;

			$return = 1; //Success

		}

		else

		{

			$return = 0; //Wrong input type

		}

		return $return;

	}

	

	function set_equal()

	{

		$this->type = '=';

		return 1;

	}

	

	function set_notequal()

	{

		$this->type = '<>';

		return 1;

	}

	

	function set_great()

	{

		$this->type = '>';

		return 1;

	}

	

	function set_less()

	{

		$this->type = '<';

		return 1;

	}

	

	function set_greatequal()

	{

		$this->type = '>=';

		return 1;

	}

	

	function set_lessequal()

	{

		$this->type = '<=';

		return 1;

	}

	

	//========== RETRIEVAL METHODS ==========//

	function get_type()

	{

		return $this->type;

	}

	

	function get()

	{

		$return = '';

		$return = $this->get_field() . $this->get_type() . "'" . $this->get_value . "'";

		return $return;

	}

	

	function dump()

	{

		echo $this->get_field() . $this->get_type() . $this->get_value();

	}

}
And here is the Combo (container) object where I keep getting my error:

Code: Select all

class Combo extends MySQLClause

{

	var $contents; //Holder of operations

	var $mult; //Bool to see if this object relates operations with AND or OR

	

	function __construct()

	{

		$contents = array();

	}

	

	//========== ASSIGNMENT METHODS ==========//

	function set_and()

	{

		$this->mult = ' AND ';

		return 1;

	}

	

	function set_or()

	{

		$this->mult = ' OR ';

		return 1;

	}

	

	function set_child($child, $index)

	{

		if ( is_a($child, 'MySQLClause') ) //Make sure object being set is the right kind of object

		{

			if ( is_int($index) )

			{

				if ( $index < count($this->contents) )

				{

					$this->contents[$index] = $child;

					$return = 1; //Success

				}

				else

				{

					$return = 0; //Invalid index input value

				}

			}

			else

			{

				$return = -1; //Invalid index type

			}

		}

		else

		{

			$return = -2; //Invalid assignment type

		}

	}

	

	//========== ADDITION METHODS ===========//

	function add_child($child, $index = -1)

	{

		if ( is_a($child, 'MySQLClause') ) //Make sure object being set is the right kind of object

		{

			if ( is_int($index) )

			{

				if ( $index < count($this->contents) )

				{

					$tempArray = array();

					//Basically I am inserting this new child

					for ($i = 0; $i < $index; $i++)

					{

						$tempArray[] = $this->contents[$i];

					}

					$tempArray[] = $child;

					for ($i = $index; $i < count($this->contents); $i++)

					{

						$tempArray[] = $this->contents[$i];

					}

					$this->contents = $tempArray;

					$return = 1; //Success

				}

				elseif ( $index = -1 ) // Default value

				{

					$this->contents[] = $child;

					$return = 1;

				}

				else

				{

					$return = 0; //Invalid index input value

				}

			}

			else

			{

				$return = -1; //Invalid index type

			}

		}

		else

		{

			$return = -2; //Invalid assignment type

		}

		return $return;

	}

	

	//========== DELETION METHODS ==========//

	function del_child($index)

	{

		if (is_int($index))

		{

			if ($index > 0 && $index < count($this->contents))

			{

				$temp = array();

				for ($i = 0; $i < $index; $i++) //copy values before index

				{

					$temp[] = $this->contents[$i];

				}

				for ($i = ($index+1); $i < count($this->contents); $i++) //copy values after index

				{

					$temp[] = $this->contents[$i];

				}

				$this->contents = $temp;

				$return = 1; //Success

			}

			else

			{

				//Wrong index value

			}

		}

		else

		{

			//Wrong index type

		}

		return $return;

	}

	

	//========== RETRIEVAL METHODS ==========//

	function get_mult()

	{

		return $this->mult;

	}

	

	function get_child($index)

	{

		if (is_int($index))

		{

			if ($index >= 0 && $index < count($this->contents))

			{

				$return = $this->contents[$index];

			}

			else

			{

				$return = 0;//Wrong index value

			}

		}

		else

		{

			$return = -1;//Wrong index type

		}

		return $return;

	}

	

	function get()

	{

		$return = '';

		for ($i = 0; $i < count($this->contents); $i++) //Loop through contents

		{

			if ( is_a($this->contents[$i], "Combo") )

			{

				$return += '(';

			}

			

			$temp = new MySQLClause();

			$temp = $this->get_child($i);

			$return += $temp->get(); //Each one should be a MySQLClause object

			

			if ( is_a($this->contents[$i], "Combo") )

			{

				$return += ')';

			}

			if ($i != ( count($this->contents)-1 )) //Not after the last one

			{

				$return += $this->get_mult();

			}

		}

		return $return;

	}

	

	//========== DISPLAY METHODS ==========//

	function dump()

	{

		echo $this->get_mult() . '<br>';

		for ($i = 0; $i < count($this->contents); $i++)

		{

			global $temp;

			$temp = new MySQLClause();

			$temp = $this->get_child($i);

			var_dump($temp);

			$temp->dump();

		}

	}

}
Here is the error:
Fatal error: Call to a member function get() on a non-object in /home/a9427730/public_html/lib/MySQLClause/Combo/Combo.php on line 167

Line 167 is where the get() function is. Both that function and the dump() function will return errors, and I have no idea why :S
Can someone please help me? I am really wrestling with this one.

Re: Please help - class abstraction issues

Posted: Wed Mar 09, 2011 12:12 pm
by Skidmark
Any suggestions? I think my main problem isn't actually in the way I defined my classes, but the way I try and retrieve elements in the $contents array. I am thinking about using iterators, but I honestly have no idea; I'm reading about their uses right now. Can someone please steer me in the right direction?

Re: Please help - class abstraction issues

Posted: Thu Mar 10, 2011 9:54 am
by pickle
That's a lot of code to go through. Basically you're getting the error because the object you think you've instantiated, hasn't been. So at some point, you're calling Combo->get(), but that particular instance of "Combo" hasn't been created as an object yet.

Re: Please help - class abstraction issues

Posted: Tue Mar 15, 2011 10:20 am
by Skidmark
Ahh yeah it is a lot of code to go through. I've been reading "clean code" and a few tutorials on decoupling components in PHP with various patterns. I think what I need to do is scrub this whole thing down to the little parts and get some real organization going. What I want to do is make a facebook / message board that has a really intricate voting system. I am thinking I will separate the singleton instance of the system ( interaction with the database / xml files / cookies (?) ) and the objects of the page ( the structure and contents ). I am just wondering how I will make interaction between the two decoupled. Maybe create a manager class that does the interaction and main functions? This is a lot to chew on.

I was also wondering if there is a reference guide to commonly used website programming terms and vocabulary ( like what a module is compared to a component, and really just common terminology for the weird abstract ideas we have to use in order to make this whole thing work correctly )

Thanks guys.