Having a PHP function use a global variable as a default?

Viewed 310

Let's say I have a lot of functions like the following, and will be making more involving some variable. For example, I'll use timezone...

function tell_time($values, $timezone = "Greenwich"){
     // Do something dealing with the timezone
}

function expected_arrival_time($values, $timezone = "Greenwich"){
     // Do something dealing with the timezone
}

function delayed_shipment_arrival($values, $timezone = "Greenwich"){
     // Do something dealing with the timezone
}
// ... and so on....

Now, if the server moves to a different timezone, all of those need to be updated. What would be 'normal' would be something like individually changing all the defaults...

function tell_time($values, $timezone = "Mountain"){
     // Do something dealing with the timezone
}

function expected_arrival_time($values, $timezone = "Mountain"){
     // Do something dealing with the timezone
}

function delayed_shipment_arrival($values, $timezone = "Mountain"){
     // Do something dealing with the timezone
}
// ... and so on....

However, if I'm wanting to make this code accessible in an open source setting, where the server timezone may change frequently depends on who downloads and installs, this may get very cumbersome for many people real fast. However, reworking all the logic isn't ideal. What would be simplest (assuming I have the server variable set), would be something like...

function tell_time($values, $timezone = $_SERVER["timezone"]){
     // Do something dealing with the timezone
}

function expected_arrival_time($values, $timezone = $_SERVER["timezone"]){
     // Do something dealing with the timezone
}

function delayed_shipment_arrival($values, $timezone = $_SERVER["timezone"]){
     // Do something dealing with the timezone
}
// ... and so on....

Then, when someone downloads and installs, it just pulls from a server variable that gets set at install time, or potentially some other global variable. Or maybe pulling from some session data for customer or something else even. The point is, I want default where I can set many functions to share the same default, so that default is easy to update. Is there a good way to do this? I'd prefer not going into every single function and having to change it to setting defaults and pulling from variables with separate internal logic, as it just makes the code filled with busywork for any who come later.

4 Answers

You could use a constant. Define it at the top of a file and let your functions use that. E.g.

define('CUSTOM_TIMEZONE', 'Mountain');

function tell_time($values, $timezone = CUSTOM_TIMEZONE) {
// Your code here
}

Just change the constants value and it's changed everywhere.

IMHO that is a good idea to use .env file and put your timezone on it and then get it in your constructor like this

<?php

class Test {
    private $timezone;

    function __construct($timezone = null) {
        $this->timezone = is_null($timezone) ? $_ENV["timezone"] : $timezone;
    }

    function tell_time($values){
            // Do something dealing with the timezone
    }
    
    function expected_arrival_time($values){
            // Do something dealing with the timezone
    }
    
    function delayed_shipment_arrival($values){
            // Do something dealing with the timezone
    }
}

This package will help you to work with .env file in php
I also give you this chance to set the timezone in your constructor if you want

You cannot use a variable as a default value.

From the docs, section "Example #6 Using non-scalar types as default values section":

The default value must be a constant expression, not (for example) a variable, a class member or a function call.

I suggest using a nullable field and set your default at the top of the method.

function tell_time($values, ?string $timezone) {
  $timezone = is_null($timezone) ? $_SERVER["timezone"] : $timezone;
}

You could still set a default value in the parameter definition if you wish, but I don't think that makes much sense with the issue you're describing, unless you set it to be null.

You could do something like this:

function tell_time($values, $timezone = null) {
    if ($timezone === null) {
        $timezone = $_SERVER["timezone"];
    }
}

But I wouldn't even bother, as PHP already provides a built-in default timezone feature. Better, you could override that once at run-time, during your app's set up, via a call to date_default_timezone_set(), passing it a value that's read from a configuration file or an environment variable. In any case, you should not have this parameter as an argument for every function, and you should not implement the feature such that changing the timezone requires a source code change. If you release this, and your customers have changed the source to customize their timezone, then they won't be able to apply updates to new versions because they'll have conflicting local changes.

Related