0

As for me, i avoid using global, but i stumbled about a point, there the use seems to be the best solution. I build this function:

function _get($parameter_name)
{
    global $argv; // register the argv array as a global variable

    if (isset($argv))
    {
        parse_str(implode('&', array_slice($argv, 1)), $_GET);
    }

    return $_GET[$parameter_name];
}

The purpose of this method is to call _get('test') and fetch the value of an argument passed by argv or otherwise an url GET parameter. But i'm not sure about it.

I'm already aware, that the usage of global is bad pratice like mentioned in Are global variables in PHP considered bad practice? If so, why?. But the argv array is a little special. It's automatically filled through the php-cli and only accessible from the called script. If i want to access this variable from within a class method or a function, i need to pass it where, or put it in a public static class member. That would be a solution, but i don't want to write the same lines in every script to pass the array through many functions. That is not really nice. So i'm thinking about this way as another possible solution.

Your opinions about this or maybe a better way i'm not seeing at the moment?

MIB
  • 137
  • 1
  • 12

2 Answers2

1

Using global could be confusing. I suggest you something like this to avoid the usage of that keyword for your purpose, abstract of $argv vs $_GET.

class Params
{
    static private $args = [] ;

    static public function init($args = null)
    {
        if (! is_null($args)) {
            parse_str(implode('&', array_slice($args, 1)), self::$args);
        }
        if (isset($_GET) && !empty($_GET)) {
            self::$args = $_GET ;
        }
    }

    static public function get($parameter_name, $default = null)
    {
        if (! isset(self::$args[$parameter_name]))
        {
            return $default ;
        }
        return self::$args[$parameter_name] ;
    }
}

// Usage :
Params::init($argv) ;
$value = Params::get("test") ;
Syscall
  • 16,959
  • 9
  • 22
  • 41
  • First, thanks for your suggestion. That would be a solution, yes, but ends in the same lines in every file, which could be called both ways. Isn't that against the pratice to build a single function doing the stuff? – MIB Jan 26 '18 at 08:45
  • 1
    The class is indented to be used with an "autoload". Only the `Params::init($argv) ;` should be call once at the begining of your script, as same as you could initialize a database connection. – Syscall Jan 26 '18 at 08:50
1

While the advice to avoid global is important and correct, it's important to know why you're avoiding it. Being dogmatic about it for its own sake is counter productive. This is just about the only use case where global is appropriate. $argv is essentially a PHP API, which is only accessible in the global scope. But of course you want to encapsulate the logic of retrieving values from it in a function, instead of having to have that code be global as well. The only choice then in pure functional programming (disregarding OO alternatives) is to import $argv from the global scope.

deceze
  • 471,072
  • 76
  • 664
  • 811
  • What would be the OO alternative? Something different to Syscall's answer? – MIB Jan 26 '18 at 09:36
  • I think, i'm clear about the reason why to avoid globals. A global variable might be changed anywhere else. It can get a really painful experience, to search for the point, there the variable was changed (i made these mistakes long time ago and learned from it). – MIB Jan 26 '18 at 09:39
  • 1
    Yes, Syscall's answer is an example of an OO approach. The only advantage it has is that it allows you to mock or replace `$argv` with something else; whether that's ever necessary is another question. – Since `$argv` is a defined PHP API, you should not generally run into any of the usual `global` caveats. – deceze Jan 26 '18 at 09:42