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

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to