Hello Andrew,

  did you check out '?:' shortcut in HEAD?

  php -r 'echo 4?:2;' -> 4
  php -r 'echo 0?:2;' -> 2

best regards
marcus

Tuesday, September 11, 2007, 3:20:46 PM, you wrote:

> If there's a workable proposal for ifsetor() that fixes the concerns  
> brought up by the original and is likely to go in PHP 6, that would  
> be great.

> In this case, perfect can be the enemy of good. array_get() helps  
> with many common use cases of ifsetor() while fitting into the the  
> standard PHP syntax and function model, potentially making its  
> adoption much easier.

> See below for answers to what you mentioned.

> On Sep 11, 2007, at 5:27 AM, Marcus Boerger wrote:

>> 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.

> True, as you suggest, it is not passed by reference. (That bug title  
> was posted independently by someone who might not have thought that  
> particular aspect through, and it isn't important to the text.)

>>
>>> * 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
> True, though there's an argument that this could even be better (less  
> error-prone) for the typical uses I've seen in my code and elsewhere,  
> where we're interested in whether the key exists in an array we  
> already have. An isset-like function doesn't allow you to separate  
> the two existence checks, allowing spelling errors in the array name  
> to go undetected when they could easily be caught. In circumstances  
> where you really do need to check both, you can call isset() or !empty 
> () on the array first:
> $value = isset($array) ? array_get($array, 'mykey') : FALSE;

>> - Mulitlevel queries
> Use nested array_get().

>> - Other types of queries (e.g. object members)
> array_get() supports object members, just like array_key_exists().

>> - 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.
> Something like that would be nice, but it doesn't exist and I haven't  
> seen a concrete proposal for it.

>>
>>> 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

> 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