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

Reply via email to