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
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php