Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:4074 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 45139 invoked from network); 18 Aug 2003 21:48:33 -0000 Received: from unknown (HELO webteks.com) (64.49.255.97) by pb1.pair.com with SMTP; 18 Aug 2003 21:48:33 -0000 Received: (qmail 11297 invoked from network); 18 Aug 2003 21:48:33 -0000 Received: from wsip-68-15-138-59.hr.hr.cox.net (HELO webteks.com) (68.15.138.59) by webteks.com with SMTP; 18 Aug 2003 21:48:33 -0000 Message-ID: <3F4149AC.80509@webteks.com> Date: Mon, 18 Aug 2003 17:48:28 -0400 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.0.2) Gecko/20021216 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Robert Cummings CC: internals@lists.php.net References: <017801c365cc$22455a10$6901a8c0@dexby> <1061241995.32231.4.camel@blobule.suds> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] Get value if set, or default From: hurst@webteks.com ("Guy N. Hurst") Hi, The function Robert proposes only works for going one key deep. That means one would have to specify getd($arr['sublevel'],$subkey), which would then create the key 'sublevel'. (That is assuming one has access to the parent keys) I have addressed this in the following function: function arr_getd(&$space,$path,$default=""){ if (is_array($space) ): if (array_key_exists($path,$space) ): return $space[$path]; endif; if($path{0}=="$"): $path=substr($path,1); endif; if(strpos($path,"]")>0): $tmp_pos = strpos($path,"["); if ($tmp_pos>0): // rep arr x[.] $path = '["'.substr($path,0,$tmp_pos).'"]'.substr($path,$tmp_pos); endif; return eval("return (isset(\$space$path))?\$space$path:\$default;"); endif; endif; return $default; } Now, I can pass in a string representation like this: $val = arr_getd($arr,"['sublevel']['$subkey']","default"); This allows me to control at what point the reference autovivifies the passed-in array space. Unfortunately, this approach requires the use of eval in order to access the isset() function. Coupled with the logic and string functions, it takes a significant performance hit. Since I use this inside loops, I would very much appreciate a language-level implementation similar to isset(), which doesn't require that a variable be passed in as a string representation. Is such a thing is acceptable to the majority? Guy N. Hurst Robert Cummings wrote: > Why not augment the userland function to the following: > > function getd( &$sourceArray, $key, $default=null ) > { > if( isset( $sourceArray[$key] ) ) > { > return $sourceArray[$key]; > } > > return $default; > } > > Cheers, > Rob. > > > On Mon, 2003-08-18 at 17:03, Griggs Domler wrote: > >>It's rare to find functionality that cannot be effectively implemented >>in userland PHP code, but this appears to be one of them. >> >>The issue here is the capability to check if an array index (or >>variable) is set, if so, return its value, or return a passed in default >>value. This can be accomplished using if statements or the ternary >>operator, but they quickly become tiresome for so routine a task. >>Especially when dealing with nested associative arrays, for example: >> >>$myVar = >>(isset($_SESSION['application']['section']['page']['title']))?$_SESSION[ >>'application']['section']['page']['title']:"Default Title"; >> >>Wouldn't this be better: >> >>$myVar = >>getd($_SESSION['application']['section']['page']['title'],"Default >>Title"); >> >>At first glance defining a function that will accomplish this appears >>easy: >> >>function getd($var,$default='') >>{ >> if(isset($var)) >> return $var; >> else >> return $default; >>} >> >>$myVar = getd($arr['noindex']); >> >>But this is not notice level compliant, producing an error if the index >>doesn't already exist. >> >>Re-writing the function to pass by reference seems to fix this at first >>glance: >> >>function getd(&$var,$default='') >>{ >> . . . >>} >> >>$myVar = getd($arr['noindex']); >> >> >>It no longer gives a notice. But the call mentioned above will now >>create the index mentioned, setting its value to null, which, while not >>necessarily wrong, still means that a foreach iteration or array_keys() >>call will show that the key now exists. (though isset() will not.) >> >>Since writing a userland function to accomplish this seems impossible >>while maintaining notice-level compliance, could this be accomplished at >>the language level? Perhaps by adding a statement similar to isset? It >>would seem a very helpful addition to PHP and would not need to affect >>other language constructs. > -- Guy Hurst Senior Developer Web Teks, Inc. http://www.webteks.com Phone: 757.578.4923 Toll free: 877.Web.Teks Fax: 757.578.4996