tags:

views:

50

answers:

3

I am not sure if the term "Wildcard" can explain my point, but sometimes in some ready scripts we are able to call a non defined function like find_by_age(23) where age can be anything else that's mapped to a database table record. So i can call find_by_name, find_by_email, find_by_id and so on. So how can we do such thing either in procedural or object oriented ways ?

+1  A: 

You can use them by defining a __call magic method in your class, you can use them only in classes. on global scope

Quoting from PHP Manual:

<?php
class MethodTest {
    public function __call($name, $arguments) {
        // Note: value of $name is case sensitive.
        echo "Calling object method '$name' "
             . implode(', ', $arguments). "\n";
    }

    /**  As of PHP 5.3.0  */
    public static function __callStatic($name, $arguments) {
        // Note: value of $name is case sensitive.
        echo "Calling static method '$name' "
             . implode(', ', $arguments). "\n";
    }
}

$obj = new MethodTest;
$obj->runTest('in object context');

MethodTest::runTest('in static context');  // As of PHP 5.3.0
?>

The above example will output:

Calling object method 'runTest' in object context
Calling static method 'runTest' in static context
aularon
+4  A: 

The term you are looking for is magic method.

Basically like this:

class Foo {
    public function __call($method,$args) {
        echo "You were looking for the method $method.\n";
    }
}

$foo = new Foo();
$foo->bar(); // prints "You were looking for the method bar."

For what you are looking for, you just filter out bad function calls and redirect good ones:

class Model {
    public function find_by_field_name($field,$value) { ... }
    public function __call($method,$args) {
        if (substr($method,0,8) === 'find_by_') {
            $fn = array($this,'find_by_field_name');
            $arguments = array_merge(array(substr($method,8)),$args);
            return call_user_func_array($fn,$arguments);
        } else {
            throw new Exception("Method not found");
        }
    }
}
Austin Hyde
A: 

For a procedural solution you can simply use string concatenation to get the job done. You can also fancy things up a bit by calling it an implementation of the strategy pattern.

<?php

/**
 * Employ a find by name strategy
 */
function find_by_name($name)
{
    echo "You are searching for users with the name $name";
    return array();
}

/**
 * Employ a find by age strategy
 */
function find_by_age($age)
{
    echo "You are searching for users who are $age years old";
    return array();
}

/**
 * Find users by using a particular strategy
 */
function find_using_strategy($strategy='age', $parameter)
{
    $results = array();
    $search_function = 'find_by_' . $search_field;
    if (function_exists($search_function)) {
        $results = $search_function($parameter);
    }

    return $results;
}


$users = find_using_strategy('name', 'Matthew Purdon');
var_dump($users);
Matthew Purdon