Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:23151 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 12222 invoked by uid 1010); 4 May 2006 19:27:18 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 12207 invoked from network); 4 May 2006 19:27:18 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 4 May 2006 19:27:18 -0000 X-PHP-List-Original-Sender: dante@vocalspace.com X-Host-Fingerprint: 69.56.193.72 fox02.stravio.com Linux 2.5 (sometimes 2.4) (4) Received: from ([69.56.193.72:55300] helo=fox02.stravio.com) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id C1/26-63443-6955A544 for ; Thu, 04 May 2006 15:27:18 -0400 Received: from [127.0.0.1] (unknown [66.243.31.162]) by fox02.stravio.com (Postfix) with ESMTP id 50D5A26C320; Thu, 4 May 2006 14:27:15 -0500 (CDT) Message-ID: <445A558D.1070102@vocalspace.com> Date: Thu, 04 May 2006 14:27:09 -0500 User-Agent: Thunderbird 1.5.0.2 (Windows/20060308) MIME-Version: 1.0 To: Rasmus Lerdorf Cc: Jochem Maas , Rick Widmer , PHPdev References: <44584619.60400@lorenso.com> <200605030815.34801.johannes@php.net> <44585828.1030603@vocalspace.com> <44585E89.6000400@vocalspace.com> <44586BDF.6040600@developersdesk.com> <4459410D.9090802@vocalspace.com> <445942E9.201@developersdesk.com> <44594553.6020009@iamjochem.com> <44594A27.4040201@vocalspace.com> <4459558D.7050703@lerdorf.com> <445959DD.9030607@vocalspace.com> <44595F95.6090607@lerdorf.com> In-Reply-To: <44595F95.6090607@lerdorf.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] Seeking 'coalesce' php internal function From: dante@vocalspace.com ("D. Dante Lorenso") Rasmus Lerdorf wrote: > D. Dante Lorenso wrote: >> In my PHP zen world, empty() and filled() are friends. Ok, I've been >> selling 'filled()' for a while now. Can we reverse the sell and try >> this .. why SHOULDN'T filled() be added to the language? > Because it doesn't do enough. Unlike empty(), when there actually is > something there, you have to check the type before using it anyway. > eg. > $a = filled($_GET['a'],$_GET['b']); > You still have to do: > if(!is_array($a)) echo $a; You are correct that filled() does not serve the purpose of proper user input filtering. filled() is not trying to solve the input filtering problem as much as it's trying to solve the problem of accessing array/object members in a cascading order of defaulting to a non-empty value. Currently I have a 'hack' object called ObjArray() which I use to wrap "maybe" PHP arrays in order to access their array elements 'safely' (no E_NOTICE thrown) with options of a default value. I use code like this: $maybe_array = function_which_returns_array_or_false(); $obj = new ObjArray($maybe_array); print $obj->array_key; print $obj->get("array_key", $default_value); The ObjArray class makes use of __get and __set functions to avoid tripping the E_NOTICE warnings that would occur otherwise when trying to access array properties that are not set. In turn, ObjArray allows arrays to be accessed like objects. ObjArray, however, can't be used on multi-level array access, but filled() could. print filled($maybe_array["array_key"], $default_value); That avoids having to wrap arrays inside objects and also allows more powerful accesses: print filled($maybe_array["array_key"]->maybe_some_property, $default_value); And unlike the pass-by-reference hacks, '$maybe_array["array_key"]->maybe_some_property' will not magically come into existence after calling the filled() function. INPUT FILTERING != filled() The example of using $_GET and $_POST as arrays in my examples might be a bad idea. In most cases, I plan to use filled() to set default values for arrays or objects which contain empty or non-set keys or properties. Most times the variable being accessed is known to be a certain list of possible types and in one call to filled() I want to get the data I want or use a cascading set of defaults: define('HARD_CODED_CONSTANT', "HARD_CODED"); $filtered_user_input = get_safely_filtered_user_input_as_object(); $database_row = fetch_database_row_as_array(); $config_settings = fetch_config_file_as_array(); $value = filled($filtered_user_input->thekey, $database_row["thekey"], $config_settings["thekey"], HARD_CODED_CONSTANT); This works WITH input filtering especially when the default value is not just a default for the user input, but is a default for the chain of search locations. I have many lines of PHP code which deal with if (!$variable) ..., if (!isset($array["key"]) ..., if (empty($var))... trying to find defaults for data which does not exist or was not found. None of those deal with $_GET or $_POST user inputs. Especially when moving into CLI development, $_GET and $_POST are irrelevant. > Because people could put ?a[]=1 in the GET args there and you have to > check for that before using it. That second type check defeats the > purpose of filled() as far as I am concerned. We need a quick way to > do a check and default assignment without throwing a notice which is > what ?: provides, then we need a decent way to check input arguments > which is what pecl/filter is being brought into the core for (among > other things). People CAN do a lot of things (and some maliciously do). I don't believe filled() prevents the input filtering from being added to the core. Input filtering and filled() shared some commonality (selecting alternate values under specific conditions), but do not nullify the need for one or the other. Detracting from my goal of having 'filled()' included in core, I'd have to say that as I see input filtering defined, that could be entirely written as part of Zend Framework in PHP and doesn't need to exist as part of the language core. filled(), OTOH, must be written in 'zend' core because it simply can not be written as an extension or in userspace without triggering errors (undefined variables) or creating unwanted variables (pass by reference). Dante