Forum Moderators: coopster

Message Too Old, No Replies

Superglobal getter with PHP8 Match

         

D3mon

6:12 pm on Dec 22, 2020 (gmt 0)

10+ Year Member



I've built a little function to fetch superGlobals using the PHP 8's new Match expression.It works but still feels overly bulky/complex. Any tips on simplifying it?

Thanks.


function get(string $type = null, string $name = null)
{
if (is_null($type)) return false;
if (is_null($name)) return false;

return match($type) {
'SERVER' => $this->exists($_SERVER, $name) ? $_SERVER[$name] : false,
'GET' => $this->exists($_GET, $name) ? $_GET[$name] : false,
'POST' => $this->exists($_POST, $name) ? $_POST[$name] : false,
'FILES' => $this->exists($_FILES, $name) ? $_FILES[$name] : false,
'COOKIE' => $this->exists($_COOKIE, $name) ? $_COOKIE[$name] : false,
'SESSION' => $this->exists($_SESSION, $name) ? $_SESSION[$name] : false,
'REQUEST' => $this->exists($_REQUEST, $name) ? $_REQUEST[$name] : false,
'ENV' => $this->exists($_ENV, $name) ? $_ENV[$name] : false,
default => false
};
}

w3dk

2:47 am on Dec 23, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



My initial thoughts are:

1. Why declare the function parameters as optional in the function prototype but then immediately reject any omitted arguments at the start of the function? (It looks like the parameters should be declared as mandatory?)
2. Where/what is the exists() method?

Unless your exists() method is doing something special then won't the null coalescing operator do the same job more succinctly?

For example:


function get(string $type, string $name)
{
return match($type) {
'SERVER' => $_SERVER[$name] ?? false,
'GET' => $_GET[$name] ?? false,
'POST' => $_POST[$name] ?? false,
'FILES' => $_FILES[$name] ?? false,
'COOKIE' => $_COOKIE[$name] ?? false,
'SESSION' => $_SESSION[$name] ?? false,
'REQUEST' => $_REQUEST[$name] ?? false,
'ENV' => $_ENV[$name] ?? false,
default => false
};
}


Alternatively:


function get(string $type, string $name)
{
$superglobal = match($type) {
'SERVER' => $_SERVER,
'GET' => $_GET,
'POST' => $_POST,
'FILES' => $_FILES,
'COOKIE' => $_COOKIE,
'SESSION' => $_SESSION,
'REQUEST' => $_REQUEST,
'ENV' => $_ENV,
default => []
};
return $superglobal[$name] ?? false;
}

[edited by: phranque at 8:05 am (utc) on Dec 23, 2020]
[edit reason] ?? operator [/edit]

w3dk

2:54 am on Dec 23, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



^^^ Just noticed these forums have reduced all the double-? (coalescing operator) to a single-? (ternary operator) in my post above! ^^^

All the single-? in the code samples in my post above should be replaced with double-? (*sigh*)

How do you type double-?

phranque

8:07 am on Dec 23, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



i think i fixed them.
please report your post if there are still "typos"

D3mon

3:02 pm on Dec 23, 2020 (gmt 0)

10+ Year Member



I think maybe I go overboard with guard clauses. I do like the freedom to have the function react in a specific way to missing parameters using the guard clause rather than stipulating that the parameters are required right off the bat - although I'd welcome not having to use guard clauses at all and will see how that works out in future.

Here's the exists() method:


public function exists(
&$type,
string $name = null
)
{
if (is_null($name)) return false;
if (!isset($type[$name])) return false;

return true;
}


In this case, it accesses the superglobal by-reference so allows me to minimize the code but I wanted to pass in a string to the get() method rather than a reference to the the superglobal set (mainly because I get a warning in VS code every time I have a line that accesses a superglobal in the rest of my code).

This seems like the sleekest version possible for the get() method, as you suggest:


function get(string $type, string $name)
{
$superglobal = match($type) {
'SERVER' => $_SERVER,
'GET' => $_GET,
'POST' => $_POST,
'FILES' => $_FILES,
'COOKIE' => $_COOKIE,
'SESSION' => $_SESSION,
'REQUEST' => $_REQUEST,
'ENV' => $_ENV,
default => []
};
return $superglobal[$name] ? false;
}


...but I suppose I was looking for some way to convert a string 'SESSION' into a meaningful reference to the superglobal set $_SESSION, that could then be used to get the content, rather like exists() does, but without the by-reference action in the passed-in parameters:

Optimistically speaking, something like this would be ideal:


function get(string $type, string $name)
{
$superglobal = '$_'.$type;
return $superglobal[$name] ? false;
}


... but of course doesn't work because $superglobal is just a string and not a legitimate superglobal reference. I suspect the switch/match is required to make it work.