Hash tables vs Switches

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
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Hash tables vs Switches

Post by BDKR »

Anybody have any comments on the idea of using hash tables in the place of switches? I've heared talk of this idea at various times, but never really jumped into it. What are you opinions on it's use in PHP?

Cheers
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Hash tables vs Switches

Post by Weirdan »

BDKR wrote:Anybody have any comments on the idea of using hash tables in the place of switches?
it depends on what do you mean exactly. Is it something like this:

Code: Select all

$switch = array(
   'some_action' => 'some_action_func',
   'some_other_action' => 'some_other_func',
);

if( isset($_GET['action']) && isset($switch[$_GET['action']]) ) {
   $func = $switch[$_GET['action']];
   unset($_GET['action']);
   call_user_func_array($func, $_GET);
}

function some_action_func() {
  $args = func_get_args();
  // do something
}

function some_other_func() {
  $args = func_get_args();
  // do something else
}
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

No, that's not what I had in mind. I was thinking something along the lines of...

Code: Select all

$hash_table=array
    (
    'one' => 'echo_one',
    'two' => 'echo_two',
    'three' => 'echo_three',
    );

$action=&$hash_table;

function echo_one()
    { echo '1'; }

function echo_two()
    { echo '2'; }

function echo_three()
    { echo '3'; }

$action[$var]();
... as opposed to ...

Code: Select all

$action = 'two';       /* This could be a var coming from a form */
switch ($action)
    {
     case 'one':
            { echo_one(); break; }    
        
     case 'two':
            { echo_two(); break; }    
            
     case 'three':
            { echo_three(); break; }                
     }
I really don't think too much of this as I really don't see it much being used in PHP. Perhaps in the PHP-GTK crowd where an execution loop of sorts may be run, in a web application there would only be one run through the script so any possible gains would most likely be extremely negligible.

Just messin' around. :wink:
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

most languages already implement a switch as a hash table with addresses.....

if you are using php i don't think the speed gain (if any) will be substantial...
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

Or lose the hash table and just call a variable function?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

BDKR wrote:No, that's not what I had in mind. I was thinking something along the lines of...
Actually I don't see any substantial difference between your example and mine :)

Sometime I use this approach myself (mostly when behaviour should be controlled via configuration files).
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Weirdan wrote: Actually I don't see any substantial difference between your example and mine :)
Ooops! :oops: I went back and looked a little closer. But I have to be honest and say it seemed a little involved at first. That's one of the reasons I didn't see it for what it is. But then you obviously have a need that I don't, as evidenced by the call_user_func_array() and unset() calls. So where you have...

Code: Select all

$func = $switch[$_GET['action']];
unset($_GET['action']);
call_user_func_array($func, $_GET);
...I would come up with...

Code: Select all

$func=&$switch[$_GET['action']];
$switch[$func]($_GET);
... because my need is a little different.

Sorry about the that.

But anyway, I was really just thinking about it. I doubt there would be much (if any) in the way of a serious speed increase with this method. In spite of the fact I've been called a code smith (with derogatory intent) this wasn't my reason for asking.

Instead, I'm thinking about a design/orginaztion approach that would make sense in code where there is an execution loop of sorts with many possible logic paths. As opposed to using some gigantic switch, I am wondering if this is an option that could improve readibility. Such an thing wouldn't be that likely in a web app but maybe in a PHP-GTK application.

One drawback tho is the question of vary agument requirement for the different functions / object->methods().

But like I said, I am just kinda thinking out loud.

Cheers
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

you pass all the functions an array or object...

in those you can stuff all the required parameters ;)


or you can use [php_man]functions.arguments.php#functions.variable-arg-list[/php_man]
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

timvw wrote:you pass all the functions an array or object...

in those you can stuff all the required parameters ;)


or you can use [php_man]functions.arguments.php#functions.variable-arg-list[/php_man]
I agree. Much like Weirdan's example. In his, the $_GET superglobal is passed.
User avatar
llimllib
Moderator
Posts: 466
Joined: Mon Jul 01, 2002 2:19 pm
Location: Baltimore, MD

Post by llimllib »

All this work because the language is not sufficiently expressive. Come to the python side, BDKR:

Code: Select all

actions = {'alpha': do_alpha, 'beta': do_beta}

actions.get(funcname, print_error)()

def do_alpha():
   #do something

def do_beta():
    #do the other thing

def print_error():
    print "encountered an error"
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

llimllib wrote:All this work because the language is not sufficiently expressive. Come to the python side, BDKR:

Code: Select all

actions = {'alpha': do_alpha, 'beta': do_beta}

actions.get(funcname, print_error)()

def do_alpha():
   #do something

def do_beta():
    #do the other thing

def print_error():
    print "encountered an error"
In cheesiesf Luke Skywalker voice, "Twigletmac! Why didn't you tell me llimlib is my father?"

Seriously, you don't have to tell me about Python. It's an awesome language. After spending some time where I'm at now, I'm planning on doing some wxPython stuff. Or at least that's the plan.

Cheers
Post Reply