1

What would be the right way of using variable with same data in two functions? Is next approach good practice? I have a few of these variables set up in functions.php

    $a = array('asdf', 'asdf', 'asdfasd');

    add_filter( 'query_vars', 'themeslug_query_vars' , 10, 1 );
    function themeslug_query_vars( $qvars ) {
      global $a;        
      ...
    }


    add_action('pre_get_posts', 'search_pre_get_posts');
    function search_pre_get_posts($query){
      global $a;
    }
3

As a matter of good coding practice, global variables are problematic at best, dangerous at worst. They should be avoided if at all possible. Why? Because what if some other plugin developer also decides to define$a as a global? Whatever that plugin is doing will now overwrite your global $a and yours has the potential to wreak havoc with theirs.

WordPress sets a bad precedent by using so many of them within its own code, but the good news is that you don't have to, and in most cases you can avoid adding to the mess of them that are already there.

One easy way to avoid a global is to wrap the variable in another function that will return a value:

function my_theme_array() {
    return array('asdf', 'asdf', 'asdfasd');
}

This would allow you to retrieve it from within other functions while keeping it in local scope and out of conflict with other code:

function themeslug_query_vars( $qvars ) {
  $a = my_theme_array();        
  ... // Now use $a for whatever.
}

function search_pre_get_posts($query){
  $a = my_theme_array();
}

If you want to be able to change the contents that the function returns rather than having your array hard-coded into the my_theme_array() function, you could set up the function to take parameters that would change the currently set values of the array:

function my_theme_array_ver_2( array $new_values = null ) {
    static $my_array = array('asdf', 'asdf', 'asdfasd'); // default values
    if ( isset( $new_values ) ) {
        $my_array = $new_values;
    } else {
        return $my_array;
 }

So now you can call the function to set it's return value:

my_theme_array_ver_2( array( 1, 2, 3 ) );

or you can simply ask it to return whatever value is currently set:

$a_this_time_around = my_theme_array_ver_2();
|improve this answer|||||
  • Thank you for extensive comment! a function seems a smart way of retrieving variable :) – Boris Kozarac Apr 25 '16 at 21:51
1

Your array is a state, your functions are behavior. The standard way of combining state and behavior is an object. That's exactly what objects are made for.

Create a class, pass the array to its constructor, and assign its public methods as callbacks to the hooks. This way, you keep everything nicely encapsulated, readable and testable. And maybe you can reuse the class in other projects.

Example:

namespace WPSE;

class QueryVars
{
    private $vars;

    public function __construct( array $vars )
    {
        $this->vars = $vars;
    }

    public function add_query_vars( array $wp_vars )
    {
        foreach ( $this->vars as $key => $value )
            $wp_vars[ $key ] = $value;

        return $wp_vars;
    }

    public function pre_get_posts( \WP_Query $query )
    {
        foreach ( $this->vars as $key => $value )
        {
            if ( $query->get( $key ) )
            {
                // do something
            }
        }
    }
}

And then register the callbacks:

$my_query_vars = new \WPSE\QueryVars(
    [
        'hello' => 'world',
        'foo'   => 'bar',
    ]
);
add_filter( 'query_vars', [ $my_query_vars, 'add_query_vars' ] );
add_action('pre_get_posts', [ $my_query_vars, 'pre_get_posts' ] );
|improve this answer|||||
  • 1
    +1 for distinction between state and behavior. I'd still want to encapsulate the instantiation somehow, instead of letting it hang out as a global object. Finding a good way to do that in the WP spaghetti-and-meatballs environment, though, is not always easy. – Caspar Apr 26 '16 at 12:53
  • 1
    @Caspar This, of course, just a part of a plugin. Normally, you handle the object creation in a controller or a factory where it stays out of the global namespace and might be accessible per filter/action only. – fuxia Apr 26 '16 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.