The true focus of this post is how to retrieve given member values of associative arrays in PHP, but it will touch on analagous constructs in other popular languages, namely Java’s Map
, Python’s dict
, Ruby’s Hash
, and Javascript objects. The operation can be characterized as:
Given an object Foo, if the Bar property is set, return that; otherwise return a default value Default
This is such a common use case that I would expect this to have decent syntax support in any language that deals with open-ended maps such as the above.
Disclaimer: I’m not well-versed in all of these languages, so forgive any syntax blunders or missed opportunities.
BTW: One of the few “features” of PHP that I genuinely hate is the blurring of the map/list distinction that is the array
. I’m psyched that Hack is trying to fix this.
Java
Map.get(key)
returns the value for the requested key, or null
if it is not set. This has the unfortunate consequence of a logic flaw if null
is a possible member of the Map
(which is a separate can of worms). So the implementation would still have to be:
foo.containsKey(bar) ? foo.get(bar) : default;
Python
Python’s dict
hooks us up proper. Full stop.
foo.get('bar', default)
Ruby
Hash
is a curious beast on this question. A default value can be set on the Hash itself as an instance setting, rather than as part of a specific retrieval call. This works either as an argument passed to the constructor, or via the setter #default=
:
foo = Hash.new(default)
# or
foo.default = default
foo[:bar] # returns default
To me, employing that technique in this use case seems like a misleading use of that instance setting, so I would be inclined to do:
foo.has_key?(:bar) ? foo[:bar] : default
JavaScript
JavaScript and its undefined
property is its own mess, so I’ll just say that JS gives you the in
operator:
("bar" in foo) ? foo.bar : default
PHP
Which brings us to the topic of this post. Similarly to Java, when accessing nonexistent members of an associative array in PHP, null
is returned, but with an E_NOTICE
error. So, leveraging the beautiful Elvis operator (one of my favorite syntactic sugar cubes), we get:
$foo['bar'] ?: $default // throws E_NOTICE
To bypass the logic flaw of the null
, we “can often assume” that null
is not a possible value for the array in question. I had (or saw someone employ) the brilliant idea of using PHP’s error suppression operator, @
, to make this behave like the Java version, i.e. not throw the E_NOTICE
:
@$foo['bar'] ?: $default // E_NOTICE is suppressed
Obviously suppressing errors is a controversial matter. Some would argue that it’s altogether poor style. It’s also a slippery slope, especially in a team setting: this is the only scenario where I would consider using @
, but it’s hard to enforce that discipline across a team. So, I posted this solution on our team chat for feedback.
We are fortunate enough to have Nils Adermann on our team, and he weighed in with some more fundamental concerns, aside from the question of code style.
The bad
Imagine the
@$params
being an array access object which triggers autoloading in one of its functions; then@$params['foo']
would hide parse errors in those PHP files. So it’s a generally bad idea, since you can never be quite certain what else you are accidently silencing in addition to what you mean to silence.Furthermore,
@
is actually slow, since it triggers the error, jumps into the error h
Truncated by Planet PHP, read more at the original (another 1806 bytes)
more
{ 0 comments... » Accessing undefined properties of hashes/objects (in PHP and more) read them below or add one }
Post a Comment