Hello Andrew, how about @<expression>?:<default> style?
Like: $val = $myarray[$key] ?: $default; marcus Tuesday, September 11, 2007, 6:33:42 PM, you wrote: > On 9/11/07, Marcus Boerger <[EMAIL PROTECTED]> wrote: >> Hello Andrew, >> >> did you check out '?:' shortcut in HEAD? >> >> php -r 'echo 4?:2;' -> 4 >> php -r 'echo 0?:2;' -> 2 >> >> best regards >> marcus > Yes, I had hoped that the ?: operator would solve this. But it 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. > Example: > array_get($_GET, 'foo') ?: slowDefaultCalculation() > Here is a test of ?: with CVS HEAD + the array_get function: >>>> var_dump($_SERVER['test'] ?: 'nope'); > PHP Notice: Undefined index: test in - on line 2 > string(4) "nope" >>>> var_dump(array_get($_SERVER, 'test', 'nope')); > string(4) "nope" >> >> 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 >> >> Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php