bruffstar
bruffstar

Reputation: 21

Variable Function Names

I have the following list... "ch", "uk", and "eu" ... this list will be added to dynamically.

I need to create a loop that will create function for each item in the list. Each of these functions will have exactly the same code inside. (See below for full exmaple of function). The only thing that is different is the function name. Below you will see the function name is "filterthis_uk" - for each item in the list the function name should be "filterthis_ch", "filterthis_eu" etc...

function filterthis_uk($form){

foreach( $form['fields'] as &$field ) {

$funcNameCode = substr(__FUNCTION__, strpos(__FUNCTION__, "_") + 1);

if ( false === strpos( $field['cssClass'], __FUNCTION__ ) || ! rgar( $field, 'allowsPrepopulate' ) )
continue;


$args = array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => 'courses', 'meta_key' => 'course_start_date', 'meta_query' => array(
    array(
        'key'       => 'course_start_date',
        'compare'   => '>',
        'value'     => $today,
    ),
     array(
        'key'       => 'course_end_date',
        'compare'   => '>',
        'value'     => $today,
    ),
    array(
        'key'       => 'course_location',
        'value'     => $funcNameCode,
    )
),  'orderby' => 'meta_value_num', 'order' => 'ASC' );



$query = new WP_Query( $args );
$field['choices'] = array();
if ( empty( $query->posts ) ) {
// Empty field if needed
$field['choices'] = array( array( 'text' => 'No Courses Found', 'value' => '' ) );
}
else {
foreach( $query->posts as $post )
$field['choices'][] = array( 'text' => $post->post_title . $funcNameCode, 'value' => $post->ID );
}

// Add Other Choice
$field['enableOtherChoice'] = 1;

break;
}
return $form;
}

There must be a way that it can be done so the function code does not need to be repeated. The only thing that changes is the two letters after the "_" in the function name. After that it is the value of the item in the list, ie.. "uk", "ch" etc...

Upvotes: 0

Views: 64

Answers (3)

Kver
Kver

Reputation: 787

You should just have the country be a parameter; that's what parameters are for.

But if you feel the need to have a function-based API, why not make a class and use the __callstatic function? It'd be much easier, it would be much cleaner, and it wouldn't crowd your namespace;

class filterCountry
{
  static $countries = ['uk', 'eu', 'ch'];
  static function __callstatic ($country, $args) 
  {
    if (in_array($country, self::$countries))
      /* logic. Note that $form will be under $args[0] */
    else
      /* graceful error handling */
  }
}

The API from your end would look like...

filterCountry::uk($form);
filterCountry::eu($form);
filterCountry::ch($form);

Edit: added error handling. The problem with the function approach is that if the function doesn't exist it will kill your entire script; using classes and __callstatic you can provide graceful error handling, and you just expand the array of countries according to your needs - or better yet - you could pull those countries from another source, like a database.

Edit 2: Switch to a PHP5 array syntax. Cleaner.

When you feel you start needing to get 'clever' with your code, it's the sign of a bad decision being made that will bite you in the butt.

Upvotes: 1

Steve
Steve

Reputation: 20469

What you are asking does not make a lot of sense (why have numerous identical functions??) but is possible with variable variables and closures:

$list = ['uk','ch','eu'];

foreach($list as $item){

    $filterthis_$item = function(){
        return 'hello';
    }
}

echo $filterthis_uk();
echo $filterthis_ch();
echo $filterthis_eu();

Upvotes: 0

fdehanne
fdehanne

Reputation: 1718

You can use Variable functions

$function = 'filterthis_'. $lang;
$function($form);

If you can change the function, you can also change her name and send the lang as param

function filterthis($lang, $form) { ... }

Upvotes: 0

Related Questions