Page 1 of 1

Function overloading workaround

Posted: Mon Feb 21, 2011 10:58 am
by Technical
Hi there.

I have a function Create(). It's a single function with no formal arguments declared.

Here, how it's supposed to be used:

Code: Select all

function Create($Type = null, $Title = null, $Icon = null, $URL = null, $Target = null, $Sort = null, $Active = null);
function Create($Type = null, $Title = null, $Icon = null, $Sort = null, $Active = null);
function Create($Type = null, $Sort = null, $Active = null);
I need all this calling variants into a one function. Which variant called is decided by the $Type argument.

First, I'm getting list of the arguments.

Code: Select all

$Arguments = func_get_args();
		if(count($Arguments) > 0)
		{
			switch($Arguments[0])
			{
So here comes the hard part: since there can be any amount of arguments because of default null value, I can't just set variables with value of $Arguments[$I]. Going with many if() statements, checking if $Arguments[$I] exists, is quite bad way.

How would you solve that problem? I have a couple of ideas with using arrays, but I want to hear your opinion.

P.S. No native support of overloading and no readonly properties makes me angry.

Re: Function overloading workaround

Posted: Mon Feb 21, 2011 11:14 am
by Technical
By the way, creating 3 separate functions is not an option. call_user_func_array() is too slow for using in a cycle.

Re: Function overloading workaround

Posted: Mon Feb 21, 2011 11:39 am
by Christopher
I have done this in the past by having arrays for each parameters list that define all the parameter names, types, etc. First check is if the number of parameters matches one of the allowed variations. Then using the information in the appropriate array to validate that the parameters are correct. It is not much different than receiving and validating $_REQUEST.

Re: Function overloading workaround

Posted: Mon Feb 21, 2011 10:28 pm
by Technical
Thanks for the reply, I did this by using array_pad() function.

Code: Select all

protected function Create()
	{
		$Arguments = func_get_args();
		if(count($Arguments) > 0)
		{
			$this->Type = Filters::Range($Arguments[0], array(Navigation::Link, Navigation::Header, Navigation::Separator), Navigation::Link);
			switch($this->Type)
			{
				case Navigation::Link:
					$Arguments = array_pad($Arguments, 7, null);
					$this->Icon = Filters::Path($Arguments[1]);
					$this->Title = Filters::Basic($Arguments[2]);
					$this->URL = Filters::URL($Arguments[3]);
					$this->Target = Filters::Range($Arguments[4], array('_blank', '_self', '_parent', 'top'), '_self');
					$Sort = 5;
					$Active = 6;
				break;
				case Navigation::Header:
					$Arguments = array_pad($Arguments, 5, null);
					$this->Icon = Filters::Path($Arguments[1]);
					$this->Title = Filters::Basic($Arguments[2]);
					$Sort = 3;
					$Active = 4;
				break;
				case Navigation::Separator:
					$Arguments = array_pad($Arguments, 3, null);
					$Sort = 1;
					$Active = 2;
				break;
			}
			$this->Sort = intval($Arguments[$Sort]);
			$this->Active = (bool) $Arguments[$Active];
		}
	}

Re: Function overloading workaround

Posted: Tue Feb 22, 2011 7:50 am
by Jenk
Can you not refactor those parameters onto a parameter object (to start with) and then have the associative behaviour on said object?

Seeing so many "primitive" parameters is simply screaming "Turn me into an object!".

Re: Function overloading workaround

Posted: Tue Feb 22, 2011 1:07 pm
by Technical
Jenk wrote:Can you not refactor those parameters onto a parameter object (to start with) and then have the associative behaviour on said object?

Seeing so many "primitive" parameters is simply screaming "Turn me into an object!".
Sounds like a good idea, I will think about it.