0

I sometimes have variables that might not be set and I would like to use a default parameter instead. Like here:

if ($p == "a") doSomething();

If $p is not defined PHP throws Notice: Undefined variable. To avoid this I often I used this construct in such a case:

$p = (isset($p) ? $p : "");

But that is ugly if you have to use it a lot. So I wrote a function for it:

function getIfSet(&$value, $default = '')
{
    return isset($value) ? $value : $default;
}

// Example
if (getIfSet($p) == "a") doSomething();

I wonder if there is a PHP function for this or how you solve this.

Aelios
  • 11,849
  • 2
  • 36
  • 54
PiTheNumber
  • 22,828
  • 17
  • 107
  • 180

4 Answers4

1

Just a little improvement, prefer passing null value to $default, passing empty string can be confusing, cause correct value can be empty string.

function getIfSet(&$value, $default = null)
{
    return isset($value) ? $value : $default;
}
$p = getIfSet($p);
Aelios
  • 11,849
  • 2
  • 36
  • 54
0

isset() is about as clean as it gets. Although I must admit that I'm not too fond of defaulting to an empty string, simply because a variable could be an empty string, yet still "be set". I think that a default of bool false or null would be truer to the behavior of isset:

function getIfSet(&$value, $default = false)
{
    return isset($value) ? $value : $default;
}

$p = getIfSet($p);

if($p !== false){
     //insert or whatever
}
else{
    header('Location: error.php');
    exit;
}
PiTheNumber
  • 22,828
  • 17
  • 107
  • 180
Wayne Whitty
  • 19,513
  • 7
  • 44
  • 66
0

Depending on what kind of values you're checking (maybe REQUEST data?), consider using classes. They are fun and they could be available anywhere.

Assuming you're checking POST data (if you don't, well, take this as an idea), create a class that checks this array:

class Post
{
    public function __get($index)
    {
        if (isset($_POST[$index]))
            return $_POST[$index];
        else
            return null;
    }
}

As simple as that. You know that __get() will trigger when you try to access a non-existant property. In this case, if the property (actually, the index in the $_POST array) doesn't exist, null will be returned and no errors are generated.

Now you can do:

$params = new Post();
$foo = $params->name ?: ''; // of course this doesn't make much sense.

if (!$params->password) ...
// instead of 
if (isset($_POST['password'])) ...

// you'll still have to use isset for cases like:
if (isset($_POST['user']['password']) ...
if (isset($params->user['password'])) ...
// but still looks neater I'd say

A problem you'll find soon is that $params isn't a super global variable, while $_POST are. How to solve this? Create it in the constructor of your controller class and use Dependency Injection for all other objects your are using.

PiTheNumber
  • 22,828
  • 17
  • 107
  • 180
Parziphal
  • 6,222
  • 4
  • 34
  • 36
  • Interesting! In `__get` I would use $_REQUEST instead or create PostParameters and GetParameters as separate objects. – PiTheNumber Oct 02 '12 at 11:26
  • Instead of `params()` you could add a [singleton](http://stackoverflow.com/questions/203336/creating-the-singleton-design-pattern-in-php5) to the object. – PiTheNumber Oct 02 '12 at 11:29
  • 1
    Yes, if you want more control. The thing about $_REQUEST is that it includes $_COOKIE, I don't like mixing them up with get and post, and the thing about singleton is that you have to type too much (RequestParameters::instance() or the like) or maybe I'm lazy, hehe (but for OOP that'd fine I guess). – Parziphal Oct 02 '12 at 11:36
  • If your autocompletion does not work you can still name it `R::p()` ;) – PiTheNumber Oct 02 '12 at 11:48
0

I tried to make renocor's answer more clean and OOP when I came up with this solution:

class NiceArray implements ArrayAccess {
    protected $array;

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

    public function offsetExists($offset) {
        return true;
    }

    public function offsetGet($offset) {
        if (isset($this->array[$offset]))
        {
            return $this->array[$offset];
        }
        else
        {
            return null;
        }
    }

    public function offsetSet($offset, $value) {
        $this->array[$offset] = $value;
    }

    public function offsetUnset($offset) {
        unset($this->array[$offset]);
    }
}

Usage:

$get = new NiceArray($_GET);
if ($get['p'] == "a") doSomething();

I know the class is kind of big but this way you still have an array and you can easily use it for every array you want. You do not need to change any code you may had before. You can still access and change the data. It will even change the original array.

PiTheNumber
  • 22,828
  • 17
  • 107
  • 180