Hello Andrew,
you can easily implement this function run time. It is not very flexible
and far away from what ifsetor was meant to be. Thus I do not think it is a
good idea. See comments below.
marcus
Tuesday, September 11, 2007, 12:12:55 AM, you wrote:
> Here's a patch against HEAD that implements the array_get function
> previously suggested on this list. I also attached a test suite,
> which should go in ext/standard/tests/array/array_get.phpt. Feedback
> is welcome.
> Independently, someone else had posted the same idea as a feature
> request for PHP 5, and if there's interest I can backport it.
> 40792 Open Wish: Function array_get(&$mixed, $key, $defaultvalue)
> /* Prototype:
> * mixed array_get ( array $search, mixed $key, mixed $default );
array should not be passed as reference as that would be a slowdown unless
the function is supposed to create the index key which according to the
specs below it doesn't.
> * Description:
> * Returns the value corresponding to the given key if the key exists
> * in the array. $key can be any value possible for an array index.
> * If the key does not exist, the function returns $default, or FALSE
> * if $default is not specified. Also works on objects.
> * Similar semantics to array_key_exists.
> */
> Here is the original proposal:
> =======
> array_get, a more palatable alternative to ifsetor
Things this cannot do but ifsetor can.
- Check whether the array exists
- Mulitlevel queries
- Other types of queries (e.g. object members)
- In theory we could have ifsetor even return a writeable reference where a
non existing key would either be created or (pretty bad imo) a reference to
the default value gets returned.
> MOTIVATION
> There is an unmet need for an accessor that doesn't generate an
> E_NOTICE when the value is missing, as shown by ongoing discussions
> and repeated requests for an ifsetor operator. However, ifsetor had a
> special-case syntax and generally didn't fit very well with the rest
> of the language.
> http://devzone.zend.com/node/view/id/1481#Heading2 has a brief
> summary. See the Related Functions and Proposals section for more.
> Reading over those ideas (firstset(), coalesce(), :?, ifset(), and a
> workaround using settype()), most of the best uses boil down to
> retrieving values from arrays.
> PROPOSAL
> As a simpler alternative to constructs such as this common double
> array reference...
>
> $value = isset($_POST['command']) ? $_POST['command'] : '';
>
> I propose an array_get function, like this...
>
> $value = array_get($_POST, 'command', '');
>
> The third argument provides a default. This function would require no
> special syntax, and makes a very common construct easier to read and
> less error-prone to type. It's a concise way of saying that missing
> values can be handled gracefully.
> Though request processing was used as an example, the function has
> wide applicability across many other uses of associative arrays.
>
> GREAT, BUT WHY NOT ADD IT TO AN INCLUDE FILE, INSTEAD OF THE CORE?
> One of the goals is to make everyday PHP code simpler and clearer.
> Writers of sample code snippets should be able to rely on array_get()
> being available. Otherwise, they will not use it. Clearer sample code
> particularly benefits beginners, who would probably find array_get
> easier to understand, but anyone else who has to read or maintain
> other people's code would benefit from its wide deployment in core as
> well. The function is generally useful enough to be part of the
> language, and the implementation in C is also more efficient than a
> PHP version.
> That said, a compatibility function for older versions of PHP is
> given below.
> SEMANTICS
> mixed array_get(array $array, mixed $key[, mixed $default = FALSE]);
>
> If $array contains the key $key, $array[$key] is returned. Otherwise
> $default is returned.
>
> If $default is not specified, it defaults to FALSE. (NULL would also
> be possible, and would more closely match other languages such as
> Python with its dict.get method, but other PHP functions tend to
> return FALSE to indicate no value.)
>
> The semantics match
>
> array_key_exists($key, $array) ? $array[$key] : $default
>
> ... but for comparison,
>
> isset($array[$key]) ? $array[$key] : $default
>
> is subtly different. The preferred array_key_exists version has these
> differences:
> 1. If $array[$key] exists but has been set to null, that null
> value will be returned instead of $default. This is likely to be the
> least surprising thing to do.
> 2. If $array itself is unset, an error is generated. This is good.
> The intention is to gracefully handle a missing $key. But if even
> $array itself doesn't exist, there may be another problem, such as
> misspelling the array variable. isset() ignores all errors, sweeping
> more under the rug than we typically want.
> IMPLEMENTATION
> A core C implementation of array_get() benchmarked between two and
> three times as fast as the implementation in PHP. I'll attach the
> patch after responding to feedback.
> See the last section for the code of the PHP implementation.
> RELATED FUNCTIONS AND PROPOSALS
> This function is different than the array_get function proposed and
> rejected in http://bugs.php.net/bug.php?id=28185. That function had
> no default value and throws a notice when the key doesn't exist,
> eliminating the major purpose of this function.
> The ?: operator doesn't serve the same purpose, because it causes an
> E_NOTICE for missing values. However, ?: and array_get can be used
> together to provide short-circuit evaluation, overcoming the
> limitations of both. See the LIMITATIONS section for an example.
> ifsetor: as discussed above, ifsetor wasn't a regular function. It
> required special language syntax support because it attempted to test
> whether a direct parameter itself was set or unset, and was
> ultimately rejected.
> ifset: a related proposal to ifsetor, with a simpler syntax, ifset
> was missing a way to control the default value.
> See here for more discussion about the 'E_STRICT ternary pain-in-the-
> ass expression' and alternatives:
> http://keithdevens.com/weblog/archive/2005/Nov/24
> http://www.php.net/~derick/meeting-notes.html#id39
> http://devzone.zend.com/node/view/id/1481#Heading2
>
> LIMITATIONS
> This proposal doesn't address every requested feature. The third
> parameter is always evaluated, so calling a slow function there would
> be undesirable. However, the limitation appears to be unavoidable
> without special language support, and there are workarounds. These
> snippets have approximately equal meanings (though they may differ is
> the handling of array values that convert to false):
> array_get($_GET, 'foo', slowDefaultCalculation())
> $val = array_get($_GET, 'foo'); if (!$val) $val =
> slowDefaultCalculation();
> array_get($_GET, 'foo') ?: slowDefaultCalculation()
> The last example uses the new PHP 6 ?: operator.
> This function applies only to array elements. Unlike other proposed
> functions, it doesn't also attempt to determine whether variables are
> set. However, the practical uses suggested for the other functions
> generally ended up applying to array elements.
> COMPATIBILITY FUNCTION FOR OLDER VERSIONS OF PHP
> if (!function_exists('array_get')) {
> function array_get($arr, $key, $default = false) {
> if (array_key_exists($key, $arr)) {
> return $arr[$key];
> }
> else {
> return $default;
> }
> }
> }
> (This version turned in the fastest times out of several variants.
> Passing $arr by reference or attempting to return the result by
> reference had a huge negative impact, and using the ternary ? :
> operator instead of the if/else was slightly slower.)
> =======
> --
> Andrew Shearer
> http://ashearer.com/
Best regards,
Marcus