Baylock
Baylock

Reputation: 1264

Dynamic function name in php

I would like to simplify the creation of "Custom Post Types" in WordPress as it is tedious to go through the same script and change all the custom post type name instances manually over and over.

It's quite simple to achieve by creating a variable containing the CPT name and use it everywhere it is needed. This way, All I have to do is declare the variable in the beginning of the script and that should take care of the rest.

The only issue is that, to make it work, I also need to prefix the CPT name in front of every function inside the script and it seems that using a variable in a function name is not easy or even recommended in PHP.

So how could I solve this?

Here is an example below to make it clear:

$prefix = 'news';

function news_custom_type_init()
{
    global $prefix;

    register_post_type($prefix, array(
    'labels' => array(
          'name' => $prefix,
          'singular_label' => $prefix,
          'add_new' => 'Add',
          ...
        ));

        register_taxonomy_for_object_type( 'category', $prefix );
}
add_action('init', $prefix.'_custom_type_init');

This is almost fine and could be standardized if only I could dynamically rename the function in order not to have to write the word "news" in front of it but use the "$prefix" instead.

This could have been nice but just doesn't work:

$prefix = 'news';

$functionName= $prefix."_custom_type_init";

function $functionName()
{
    global $prefix;

    register_post_type($prefix, array(
    'labels' => array(
          'name' => $prefix,
          'singular_label' => $prefix,
          'add_new' => 'Add',
          ...
        ));

        register_taxonomy_for_object_type( 'category', $prefix );
}
add_action('init', $prefix.'_custom_type_init');

Having to name manually the function kinda defeat the original purpose of my attempt (especially when the script embeds dozens of functions like this one).

What would be the best way to do this?

PS: I googled and "stackoverflowed" a lot about this but didn't find any working solution that fit my needs and doesn't generate a WordPress error message.

Thank you.

Upvotes: 14

Views: 43481

Answers (10)

zabatonni
zabatonni

Reputation: 89

You can use string in brackets

("function_name_{$dynamic_var}")()

Upvotes: 2

Vitalicus
Vitalicus

Reputation: 1379

eval() is the simpliest method https://www.php.net/manual/en/function.eval.php

$name='new_func';
$var = eval($name."();");

function new_func(){echo "It work";}

Upvotes: 0

Praise Dare
Praise Dare

Reputation: 540

I was also looking for a way to do this, as I wanted to create a function that could make aliases for functions, just like in ruby. e.g.

function an_insanely_long_function_name($a, $b) {
    // do something with $a and $b
}

// I'll go insane if I have to type that stupidly long function name every time 😵
// Aliases to the rescue :)
define_alias('shrt_nm', 'an_insanely_long_function_name');

shrt_nm('a', 'b');

I did quite a lot of research — for like 2 mins :p — and found nothing that could help me achieve that functionality.

I was about to give up and do it all manually, but then I remembered good old "eval", my long time buddy :).

Here's what you need to do:

function define_alias($alias, $function) {
    if (function_exists($alias))
        throw new \Exception('A function named ' . $alias . ' already exists!');

    // create the function
    eval("function $alias(...\$args) { $function(...\$args); }")
}

Upvotes: 0

Cryptorrior
Cryptorrior

Reputation: 119

Dynamic function named in PHP as variable functions

https://www.php.net/manual/en/functions.variable-functions.php

as example

$functionName = function () {
    global $prefix;

    register_post_type($prefix, array(
    'labels' => array(
          'name' => $prefix,
          'singular_label' => $prefix,
          'add_new' => 'Add',
          ...
        ));

        register_taxonomy_for_object_type( 'category', $prefix );
}

you can call it by typing $functionName()

Upvotes: 0

JohnG
JohnG

Reputation: 497

I'm not sure any of the above actually answer the question about dynamically creating custom post types. This works for me though:

$languages = ("English", "Spanish", "French");

foreach($languages as $language):

    $example = function () use ($language) {

        $labels = array(
                'name' => __( $language . ' Posts' ),
                'singular_name' => __( $language . ' Post' )
        );

        $args = array(
   
            'labels'              => $labels,
            'hierarchical'        => false,
            'public'              => true,
            'show_ui'             => true,
            'show_in_menu'        => true,
            'show_in_nav_menus'   => true,
            'show_in_admin_bar'   => true,
            'menu_position'       => 5,
            "rewrite" => array( "slug" => $language . "_posts", "with_front" => true ),
            'capability_type'     => 'page',
         );
        register_post_type( $language . "_posts", $args );  

    };
    add_action( 'init', $example, 0 );

endforeach;

Upvotes: 0

Terry Lin
Terry Lin

Reputation: 2599

This post is old, but PHP 7 may solve this question.

Try:

$prefix = 'news';

$functionName = $prefix . "_custom_type_init";

${$functionName} = function() use ($prefix) {

    register_post_type($prefix, array(
        'labels' => array(
            'name' => $prefix,
            'singular_label' => $prefix,
            'add_new' => 'Add'
        )
    );

    register_taxonomy_for_object_type( 'category', $prefix );
};

add_action('init', '$' . $functionName);

I think it should work for WordPress.

Upvotes: 1

ryczypior
ryczypior

Reputation: 31

I think you could use

runkit_function_add

http://php.net/manual/pl/function.runkit-function-add.php

One other available method is to use eval()

Upvotes: 2

cernunnos
cernunnos

Reputation: 2806

Edit (2017-04): Anonymous functions (properly implemented) are the way to go, see answer by David Vielhuber.

This answer is ill advised, as is any approach that involves code as a string, because this invites (among other things) concatenation.


Im not sure if it is advisable to use, or if it helps you, but php allows you to create "anonymous" functions :

function generateFunction ($prefix) {
    $funcname = create_function(
        '/* comma separated args here */', 
        '/* insert code as string here, using $prefix as you please */'
    );
    return $funcname;
}

$func= generateFunction ("news_custom_type_init");
$func(); // runs generated function

I am assuming add_action just calls whatever function you passed.

http://php.net/manual/en/function.create-function.php

Note: create_function will not return a function with the name you want, but the contents of the function will be under your control, and the real name of the function is not important.

Upvotes: 3

David Vielhuber
David Vielhuber

Reputation: 3569

This is an old thread but simply use anonymous functions:

add_action('init', function() use($args) {
    //...
});

Then there is no need to declare so many functions.

Upvotes: 11

Nick Andriopoulos
Nick Andriopoulos

Reputation: 10643

Simple enough, here's a similar snipped form a project:

$function = $prefix . '_custom_type_init';
if(function_exists($function)) {
  $function();
}

Upvotes: 20

Related Questions