All,
I'm sure this has been asked somewhere, but since I see requests for
features for 5.2 or 6.0, I'd like to add a "simple" item to the list
which would be quite useful to me and would simplify and clean up a lot
of code out there:
function coalesce(...)
This works much like in the SQL version of the same. In SQL, the
function returns the first non-null argument from an arbitrary list. In
our use, it should return the first non-empty value from the list:
Example:
$x = "dante";
$y = "";
$z = "";
$value = coalesce($z, $y, $x); // $value = "dante"
This function would ideally be built into the language and bypass
warnings about undefined variables like 'empty' does. It might be nice
to have several varieties of this function:
* return first parameter where empty() is `FALSE`
* return first parameter where isset() is `TRUE`
I don't think something like this can NOT be written in userspace
because the 'isset' and 'empty' checks need to be run before arguments
can be passed to a user function or warnings will start flying. A
function like this simplifies code which used to look like this:
if (!empty($_POST["postkey"])) {
$value = $_POST["postkey"];
}
elseif (!empty($_GET["getkey"])) {
$value = $_POST["getkey"];
}
elseif (!empty($default_value)) {
$value = $default_value;
}
else {
$value = "hard coded value";
}
Into this:
$value = coalesce($_POST["postkey"], $_GET["getkey"],
$default_value, "hard coded value");
Can this be built and included?
Dante
D. Dante Lorenso wrote:
I don't think something like this can NOT be written in userspace
because the 'isset' and 'empty' checks need to be run before arguments
can be passed to a user function or warnings will start flying. A
function like this simplifies code which used to look like this:if (!empty($_POST["postkey"])) {
$value = $_POST["postkey"];
}
elseif (!empty($_GET["getkey"])) {
$value = $_POST["getkey"];
}
elseif (!empty($default_value)) {
$value = $default_value;
}
else {
$value = "hard coded value";
}Into this:
$value = coalesce($_POST["postkey"], $_GET["getkey"],
$default_value, "hard coded value");
I mean "I DON'T think like this CAN be written in userspace". And, yes,
there is a bug in that code up above (around $_GET testing), but the
'coalesce' function removes the test/set with identical values so
removes those kinds of careless bugs.
Dante
D.
Please read the mailing list archives. And don't mention it again ;)
- Steph
----- Original Message -----
From: "D. Dante Lorenso" dante@vocalspace.com
To: dante@lorenso.com
Cc: internals@lists.php.net
Sent: Wednesday, May 03, 2006 8:05 AM
Subject: Re: [PHP-DEV] Seeking 'coalesce' php internal function
D. Dante Lorenso wrote:
I don't think something like this can NOT be written in userspace
because the 'isset' and 'empty' checks need to be run before arguments
can be passed to a user function or warnings will start flying. A
function like this simplifies code which used to look like this:if (!empty($_POST["postkey"])) {
$value = $_POST["postkey"];
}
elseif (!empty($_GET["getkey"])) {
$value = $_POST["getkey"];
}
elseif (!empty($default_value)) {
$value = $default_value;
}
else {
$value = "hard coded value";
}Into this:
$value = coalesce($_POST["postkey"], $_GET["getkey"],
$default_value, "hard coded value");I mean "I DON'T think like this CAN be written in userspace". And, yes,
there is a bug in that code up above (around $_GET testing), but the
'coalesce' function removes the test/set with identical values so
removes those kinds of careless bugs.Dante
--
__________ NOD32 1.1380 (20060125) Information __________
This message was checked by NOD32 antivirus system.
http://www.eset.com
Hi,
please search the archives for "ifsetor".
johannes
All,
I'm sure this has been asked somewhere, but since I see requests for
features for 5.2 or 6.0, I'd like to add a "simple" item to the list
which would be quite useful to me and would simplify and clean up a lot
of code out there:function coalesce(...)
This works much like in the SQL version of the same. In SQL, the
function returns the first non-null argument from an arbitrary list. In
our use, it should return the first non-empty value from the list:Example:
$x = "dante"; $y = ""; $z = ""; $value = coalesce($z, $y, $x); // $value = "dante"
This function would ideally be built into the language and bypass
warnings about undefined variables like 'empty' does. It might be nice
to have several varieties of this function:* return first parameter where empty() is `FALSE` * return first parameter where isset() is `TRUE`
I don't think something like this can NOT be written in userspace
because the 'isset' and 'empty' checks need to be run before arguments
can be passed to a user function or warnings will start flying. A
function like this simplifies code which used to look like this:if (!empty($_POST["postkey"])) { $value = $_POST["postkey"]; } elseif (!empty($_GET["getkey"])) { $value = $_POST["getkey"]; } elseif (!empty($default_value)) { $value = $default_value; } else { $value = "hard coded value"; }
Into this:
$value = coalesce($_POST["postkey"], $_GET["getkey"],
$default_value, "hard coded value");
Can this be built and included?
Dante
Johannes Schlueter wrote:
please search the archives for "ifsetor".
I have completed this search and find:
http://marc.theaimsgroup.com/?r=1&w=2&q=b&l=php-dev&s=coalesce
http://marc.theaimsgroup.com/?l=php-dev&w=2&r=1&s=ifsetor&q=b
I am using PHP 5.1.2 currently and thought using pass-by-reference was
frowned upon. Assuming a mistaken assumption I move forward and see the
following code which was presented to the list:
<?php
function ifsetor(&$var, $value) {
return (isset($var)) ? $var : $value;
}
print ifsetor($x, "dante");
?>
This works as I'd like in my dev environment, however, this does not
solve the problem of allowing variable number of parameters (variables
and values). So, I've whipped up this 10 variable version:
<?php
function ifsetor(&$var1, &$var2, &$var3, &$var4, &$var5, &$var6, &$var7,
&$var8, &$var9, &$var10) {
if (isset($var1)) return $var1;
if (isset($var2)) return $var2;
if (isset($var3)) return $var3;
if (isset($var4)) return $var4;
if (isset($var5)) return $var5;
if (isset($var6)) return $var6;
if (isset($var7)) return $var7;
if (isset($var8)) return $var8;
if (isset($var9)) return $var9;
if (isset($var10)) return $var10;
return false;
}
print ifsetor($x["notset"]->notset, $y["notset"]->notset, $z->notset,
"dante");
?>
PHP Fatal error: Only variables can be passed by reference in
.../ifsetor.php on line 15
PHP Warning: Missing argument 5 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 6 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 7 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 8 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 9 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 10 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
I can work around passing values by reference by calling the function
like this:
print ifsetor($x["notset"]->notset, $y["notset"]->notset,
$z->notset, $temp = "dante");
But you have to admit that's getting ugly and still, there are undefined
parameters declared ... so then I tried it by assigning default values:
<?php
function ifsetor(&$var1=null, &$var2=null, &$var3=null, &$var4=null,
&$var5=null, &$var6=null, &$var7=null, &$var8=null, &$var9=null,
&$var10=null) {
if (isset($var1)) return $var1;
if (isset($var2)) return $var2;
if (isset($var3)) return $var3;
if (isset($var4)) return $var4;
if (isset($var5)) return $var5;
if (isset($var6)) return $var6;
if (isset($var7)) return $var7;
if (isset($var8)) return $var8;
if (isset($var9)) return $var9;
if (isset($var10)) return $var10;
return false;
}
print ifsetor($x["notset"]->notset, $y["notset"]->notset, $z->notset,
$temp = "dante")."\n";
print_r($x);
?>
Now, $x, $y, and $z ARE set ...
dante
Array ( [notset] => stdClass Object ( [notset] => ) )
This is a nasty side-effect and can not be accepted. I did not want to
set these variables, just check their existance.
I am willing to go away and concede that this should be done in
userspace IF you can show me that it is in fact possible. The 2
argument ifsetor is trivial in userspace, yes, but the variable case is
more useful in a variety of situations and provides the most benefit to
simplify code. I did not find the answer in the archives. Can you
point me in the right direction? I need to be able to do all of the
following:
* variable number of parameters
* test 'isset' or 'empty'
* testing variables and non-variable values (pass-by-reference won't
work on values)
* not have side-effect of defining values which are not already set
* not trigger notices or warnings
* returns value of first proper match
Dante
johannes
All,
I'm sure this has been asked somewhere, but since I see requests for
features for 5.2 or 6.0, I'd like to add a "simple" item to the list
which would be quite useful to me and would simplify and clean up a lot
of code out there:function coalesce(...)
This works much like in the SQL version of the same. In SQL, the
function returns the first non-null argument from an arbitrary list. In
our use, it should return the first non-empty value from the list:Example:
$x = "dante"; $y = ""; $z = ""; $value = coalesce($z, $y, $x); // $value = "dante"
This function would ideally be built into the language and bypass
warnings about undefined variables like 'empty' does. It might be nice
to have several varieties of this function:* return first parameter where empty() is `FALSE` * return first parameter where isset() is `TRUE`
I don't think something like this can NOT be written in userspace
because the 'isset' and 'empty' checks need to be run before arguments
can be passed to a user function or warnings will start flying. A
function like this simplifies code which used to look like this:if (!empty($_POST["postkey"])) { $value = $_POST["postkey"]; } elseif (!empty($_GET["getkey"])) { $value = $_POST["getkey"]; } elseif (!empty($default_value)) { $value = $default_value; } else { $value = "hard coded value"; }
Into this:
$value = coalesce($_POST["postkey"], $_GET["getkey"],
$default_value, "hard coded value");
Can this be built and included?
Dante
http://us3.php.net/func_get_args
http://us3.php.net/array
Enjoy.
Eric Coleman
Eric Coleman
http://aplosmedia.com
home: 412 399 1024
cell: 412 779 5176
Johannes Schlueter wrote:
please search the archives for "ifsetor".
I have completed this search and find:
http://marc.theaimsgroup.com/?r=1&w=2&q=b&l=php-dev&s=coalesce
http://marc.theaimsgroup.com/?l=php-dev&w=2&r=1&s=ifsetor&q=bI am using PHP 5.1.2 currently and thought using pass-by-reference
was frowned upon. Assuming a mistaken assumption I move forward
and see the following code which was presented to the list:<?php
function ifsetor(&$var, $value) {
return (isset($var)) ? $var : $value;
}
print ifsetor($x, "dante");
?>This works as I'd like in my dev environment, however, this does
not solve the problem of allowing variable number of parameters
(variables and values). So, I've whipped up this 10 variable version:<?php
function ifsetor(&$var1, &$var2, &$var3, &$var4, &$var5, &$var6, &
$var7, &$var8, &$var9, &$var10) {
if (isset($var1)) return $var1;
if (isset($var2)) return $var2;
if (isset($var3)) return $var3;
if (isset($var4)) return $var4;
if (isset($var5)) return $var5;
if (isset($var6)) return $var6;
if (isset($var7)) return $var7;
if (isset($var8)) return $var8;
if (isset($var9)) return $var9;
if (isset($var10)) return $var10;
return false;
}
print ifsetor($x["notset"]->notset, $y["notset"]->notset, $z-notset, "dante");
?>PHP Fatal error: Only variables can be passed by reference in .../
ifsetor.php on line 15
PHP Warning: Missing argument 5 for ifsetor(), called in .../
ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 6 for ifsetor(), called in .../
ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 7 for ifsetor(), called in .../
ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 8 for ifsetor(), called in .../
ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 9 for ifsetor(), called in .../
ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 10 for ifsetor(), called in .../
ifsetor.php on line 15 and defined in .../ifsetor.php on line 2I can work around passing values by reference by calling the
function like this:print ifsetor($x["notset"]->notset, $y["notset"]->notset, $z-
notset, $temp = "dante");
But you have to admit that's getting ugly and still, there are
undefined parameters declared ... so then I tried it by assigning
default values:<?php
function ifsetor(&$var1=null, &$var2=null, &$var3=null, &
$var4=null, &$var5=null, &$var6=null, &$var7=null, &$var8=null, &
$var9=null, &$var10=null) {
if (isset($var1)) return $var1;
if (isset($var2)) return $var2;
if (isset($var3)) return $var3;
if (isset($var4)) return $var4;
if (isset($var5)) return $var5;
if (isset($var6)) return $var6;
if (isset($var7)) return $var7;
if (isset($var8)) return $var8;
if (isset($var9)) return $var9;
if (isset($var10)) return $var10;
return false;
}
print ifsetor($x["notset"]->notset, $y["notset"]->notset, $z-notset, $temp = "dante")."\n";
print_r($x);
?>Now, $x, $y, and $z ARE set ...
dante
Array ( [notset] => stdClass Object ( [notset] => ) )This is a nasty side-effect and can not be accepted. I did not
want to set these variables, just check their existance.I am willing to go away and concede that this should be done in
userspace IF you can show me that it is in fact possible. The 2
argument ifsetor is trivial in userspace, yes, but the variable
case is more useful in a variety of situations and provides the
most benefit to simplify code. I did not find the answer in the
archives. Can you point me in the right direction? I need to be
able to do all of the following:
- variable number of parameters
- test 'isset' or 'empty'
- testing variables and non-variable values (pass-by-reference
won't
work on values)- not have side-effect of defining values which are not already set
- not trigger notices or warnings
- returns value of first proper match
Dante
johannes
All,
I'm sure this has been asked somewhere, but since I see requests for
features for 5.2 or 6.0, I'd like to add a "simple" item to the list
which would be quite useful to me and would simplify and clean up
a lot
of code out there:function coalesce(...)
This works much like in the SQL version of the same. In SQL, the
function returns the first non-null argument from an arbitrary
list. In
our use, it should return the first non-empty value from the list:Example:
$x = "dante"; $y = ""; $z = ""; $value = coalesce($z, $y, $x); // $value = "dante"
This function would ideally be built into the language and bypass
warnings about undefined variables like 'empty' does. It might
be nice
to have several varieties of this function:* return first parameter where empty() is `FALSE` * return first parameter where isset() is `TRUE`
I don't think something like this can NOT be written in userspace
because the 'isset' and 'empty' checks need to be run before
arguments
can be passed to a user function or warnings will start flying. A
function like this simplifies code which used to look like this:if (!empty($_POST["postkey"])) { $value = $_POST["postkey"]; } elseif (!empty($_GET["getkey"])) { $value = $_POST["getkey"]; } elseif (!empty($default_value)) { $value = $default_value; } else { $value = "hard coded value"; }
Into this:
$value = coalesce($_POST["postkey"], $_GET["getkey"],
$default_value, "hard coded value");
Can this be built and included?
Dante
Eric,
This reply is too basic and is not the answer. The problem is more
complex then you have grasped.
The only way to remove the notice and warning errors is by using
pass-by-reference in the userspace function. Pass-by-reference can not
be done for literal values and will only work on variables. All notices
and warnings have been thrown long before func_get_args can be run.
Besides, func_get_args will return an array and then isset() and empty()
no longer apply to the original variables.
Dante
Eric Coleman wrote:
http://us3.php.net/func_get_args
http://us3.php.net/arrayEnjoy.
Eric Coleman
Eric Coleman
http://aplosmedia.com
home: 412 399 1024
cell: 412 779 5176Johannes Schlueter wrote:
please search the archives for "ifsetor".
I have completed this search and find:
http://marc.theaimsgroup.com/?r=1&w=2&q=b&l=php-dev&s=coalesce
http://marc.theaimsgroup.com/?l=php-dev&w=2&r=1&s=ifsetor&q=bI am using PHP 5.1.2 currently and thought using pass-by-reference
was frowned upon. Assuming a mistaken assumption I move forward and
see the following code which was presented to the list:<?php
function ifsetor(&$var, $value) {
return (isset($var)) ? $var : $value;
}
print ifsetor($x, "dante");
?>This works as I'd like in my dev environment, however, this does not
solve the problem of allowing variable number of parameters
(variables and values). So, I've whipped up this 10 variable version:<?php
function ifsetor(&$var1, &$var2, &$var3, &$var4, &$var5, &$var6,
&$var7, &$var8, &$var9, &$var10) {
if (isset($var1)) return $var1;
if (isset($var2)) return $var2;
if (isset($var3)) return $var3;
if (isset($var4)) return $var4;
if (isset($var5)) return $var5;
if (isset($var6)) return $var6;
if (isset($var7)) return $var7;
if (isset($var8)) return $var8;
if (isset($var9)) return $var9;
if (isset($var10)) return $var10;
return false;
}
print ifsetor($x["notset"]->notset, $y["notset"]->notset, $z->notset,
"dante");
?>PHP Fatal error: Only variables can be passed by reference in
.../ifsetor.php on line 15
PHP Warning: Missing argument 5 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 6 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 7 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 8 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 9 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2
PHP Warning: Missing argument 10 for ifsetor(), called in
.../ifsetor.php on line 15 and defined in .../ifsetor.php on line 2I can work around passing values by reference by calling the function
like this:print ifsetor($x["notset"]->notset, $y["notset"]->notset,
$z->notset, $temp = "dante");But you have to admit that's getting ugly and still, there are
undefined parameters declared ... so then I tried it by assigning
default values:<?php
function ifsetor(&$var1=null, &$var2=null, &$var3=null, &$var4=null,
&$var5=null, &$var6=null, &$var7=null, &$var8=null, &$var9=null,
&$var10=null) {
if (isset($var1)) return $var1;
if (isset($var2)) return $var2;
if (isset($var3)) return $var3;
if (isset($var4)) return $var4;
if (isset($var5)) return $var5;
if (isset($var6)) return $var6;
if (isset($var7)) return $var7;
if (isset($var8)) return $var8;
if (isset($var9)) return $var9;
if (isset($var10)) return $var10;
return false;
}
print ifsetor($x["notset"]->notset, $y["notset"]->notset, $z->notset,
$temp = "dante")."\n";
print_r($x);
?>Now, $x, $y, and $z ARE set ...
dante
Array ( [notset] => stdClass Object ( [notset] => ) )This is a nasty side-effect and can not be accepted. I did not want
to set these variables, just check their existance.I am willing to go away and concede that this should be done in
userspace IF you can show me that it is in fact possible. The 2
argument ifsetor is trivial in userspace, yes, but the variable case
is more useful in a variety of situations and provides the most
benefit to simplify code. I did not find the answer in the
archives. Can you point me in the right direction? I need to be
able to do all of the following:
- variable number of parameters
- test 'isset' or 'empty'
- testing variables and non-variable values (pass-by-reference won't
work on values)- not have side-effect of defining values which are not already set
- not trigger notices or warnings
- returns value of first proper match
Dante
johannes
All,
I'm sure this has been asked somewhere, but since I see requests for
features for 5.2 or 6.0, I'd like to add a "simple" item to the list
which would be quite useful to me and would simplify and clean up a
lot
of code out there:function coalesce(...)
This works much like in the SQL version of the same. In SQL, the
function returns the first non-null argument from an arbitrary
list. In
our use, it should return the first non-empty value from the list:Example:
$x = "dante"; $y = ""; $z = ""; $value = coalesce($z, $y, $x); // $value = "dante"
This function would ideally be built into the language and bypass
warnings about undefined variables like 'empty' does. It might be
nice
to have several varieties of this function:* return first parameter where empty() is `FALSE` * return first parameter where isset() is `TRUE`
I don't think something like this can NOT be written in userspace
because the 'isset' and 'empty' checks need to be run before arguments
can be passed to a user function or warnings will start flying. A
function like this simplifies code which used to look like this:if (!empty($_POST["postkey"])) { $value = $_POST["postkey"]; } elseif (!empty($_GET["getkey"])) { $value = $_POST["getkey"]; } elseif (!empty($default_value)) { $value = $default_value; } else { $value = "hard coded value"; }
Into this:
$value = coalesce($_POST["postkey"], $_GET["getkey"],
$default_value, "hard coded value");
Can this be built and included?
Dante
D. Dante Lorenso wrote:
Eric,
This reply is too basic and is not the answer. The problem is more
complex then you have grasped.
function ifsetor() {
$args = func_get_args()
;
$count = count( $args );
for( $i=0; $i<$count; $i++ ) {
if isset( $args[ $i ] )) {
return $args[ $i ];
}
return false;
}
Rick Widmer wrote:
D. Dante Lorenso wrote:
Eric,
This reply is too basic and is not the answer. The problem is more
complex then you have grasped.
function ifsetor() {
$args =func_get_args()
;
$count = count( $args );for( $i=0; $i<$count; $i++ ) {
if isset( $args[ $i ] )) {
return $args[ $i ];
}return false;
}
No, that doesn't address the problem. See this:
---------- 8< -------------------- 8< -------------------- 8< ----------
<pre> <?php function ifsetor() { $args = `func_get_args()`; $count = count($args); for ($i=0; $i<$count; $i++) { if (isset($args[$i])) { return $args[$i]; } } return false; } print ifsetor($x, $y, $z, "dante")."\n"; ?> </pre>PHP Notice: Undefined variable: x in .../ifsetor.php on line 13
PHP Notice: Undefined variable: y in .../ifsetor.php on line 13
PHP Notice: Undefined variable: z in .../ifsetor.php on line 13
---------- 8< -------------------- 8< -------------------- 8< ----------
See my post regarding a specification for 'filled()' as a function. An
important feature is that warnings about unset variables should not
occur. Your suggestion does not qualify. This problem can not be
solved in userspace.
Dante
D. Dante Lorenso wrote:
No, that doesn't address the problem. See this:
print @ifsetor($x, $y, $z, "dante")."\n";
Rick Widmer wrote:
D. Dante Lorenso wrote:
No, that doesn't address the problem. See this:
print @ifsetor($x, $y, $z, "dante")."\n";
point 1: regardless of how people think there should be an ifsetor()
in the engine - the devs don't so there wont be one.
point 2: anything trying to implement this functionality in userspace
is a hack. (to stregethen that stance: Rasmus reiterated the point a few
days ago [can't remember which mailinglist] that people should be trying to
write error free code - ergo the error suppression is not a proper solution)
Dante, live with the hack. :-)
Jochem Maas wrote:
point 1: regardless of how people think there should be an ifsetor()
in the engine - the devs don't so there wont be one.
Arrrrvvhggghh! Don't you just want to scream!
point 2: anything trying to implement this functionality in userspace
is a hack. (to stregethen that stance: Rasmus reiterated the point a few
days ago [can't remember which mailinglist] that people should be
trying to
write error free code - ergo the error suppression is not a proper
solution)
Ok. You CAN NOT implement 'ifsetor/coalesce/filled' in userspace. And
the devs don't want it to exist ... so, WTF?
<soap box> Come on devs, I'm pleading with you. Say it isn't so. You force me to write so much extra code unless this functionality exists in the core.Dante, live with the hack. :-)
Translate to: Dante, you don't need PHP to be better, adequate is good
enough.
Explain to me how every possible thing you might want to do to an array
gets it's own function in the language, but something as trivial as this
gets refused so strongly!
I mean really: array_change_key_case, array_chunk, array_combine,
array_count_values, array_diff_assoc, array_diff_key, array_diff_uassoc, ...
http://www.php.net/manual/en/ref.array.php
You can't tell me that most if not all of these functions could not have
been implemented in userspace? I might use 10% of all the array
functions, but I'd use 'coalesce' and 'filled' daily.
</soap box>
Tell me at least this much. Can these two functions be implemented as
an extension? From what you know about PHP internals, does what WE want
have to be a language construct? If I can write coalesce() and filled()
as extensions, I'll submit a new extension/patch. Maybe it could join
PECL and with popularity make it's way begrudgingly into the core?
Dante
Not sure what you guys are talking about. ?: is on the roadmap.
-Rasmus
D. Dante Lorenso wrote:
Jochem Maas wrote:
point 1: regardless of how people think there should be an ifsetor()
in the engine - the devs don't so there wont be one.
Arrrrvvhggghh! Don't you just want to scream!point 2: anything trying to implement this functionality in userspace
is a hack. (to stregethen that stance: Rasmus reiterated the point a few
days ago [can't remember which mailinglist] that people should be
trying to
write error free code - ergo the error suppression is not a proper
solution)Ok. You CAN NOT implement 'ifsetor/coalesce/filled' in userspace. And
the devs don't want it to exist ... so, WTF?<soap box> Come on devs, I'm pleading with you. Say it isn't so. You force me to write so much extra code unless this functionality exists in the core.Dante, live with the hack. :-)
Translate to: Dante, you don't need PHP to be better, adequate is good
enough.Explain to me how every possible thing you might want to do to an array
gets it's own function in the language, but something as trivial as this
gets refused so strongly!I mean really: array_change_key_case, array_chunk, array_combine,
array_count_values, array_diff_assoc, array_diff_key, array_diff_uassoc,
...
http://www.php.net/manual/en/ref.array.phpYou can't tell me that most if not all of these functions could not have
been implemented in userspace? I might use 10% of all the array
functions, but I'd use 'coalesce' and 'filled' daily.
</soap box>Tell me at least this much. Can these two functions be implemented as
an extension? From what you know about PHP internals, does what WE want
have to be a language construct? If I can write coalesce() and filled()
as extensions, I'll submit a new extension/patch. Maybe it could join
PECL and with popularity make it's way begrudgingly into the core?Dante
Rasmus Lerdorf wrote:
Not sure what you guys are talking about. ?: is on the roadmap.
-Rasmus
Ok. That has some signs of hope. What is ?: exactly, though. I
searched '?:' and yeah, good luck with that in documentation. It
doesn't smell like it supports all the specifics that 'filled()' does.
Am I supposed to do this:
$value = $x ?: $y ?: $z ?: $default;
And no warnings will be thrown for $x, $y, and $z not existing? Did you
see my post about 'filled()'?
http://news.php.net/php.internals/23132
Honestly, I'm happy to see '?:' because that's better than nothing, but
I think filled() is more like empty() and would be a better
implementation. If you want to look at the language from a consistency
point of view '?:' is very PERL-like whereas filled(...) is PHP-like:
PERL-like:
$x ~= s/\s+//;
$x = $a ?: $b ?: $c;
PHP-like:
$x = preg_replace("/\s+/", "", $x);
$x = filled($a, $b, $c);
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?
Dante
D. Dante Lorenso wrote:
Rasmus Lerdorf wrote:
Not sure what you guys are talking about. ?: is on the roadmap.
-RasmusOk. That has some signs of hope. What is ?: exactly, though.
Rasmus is referring to making the middle operand in the ternary operator
optional, I believe.
Jasper
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;
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).
By the way, the lack of array checks is rampant out there. Pick just
about any PHP site and find a page where it has arguments and add [] to
one of them and watch it blow up. In some cases where the developers
were smart enough to send errors to their error log, you can't see that
you made it blow up, but in surprisingly many you can:
http://en.wikipedia.org/w/index.php?title[]=Special:Userlogin&returnto[]=Main_Page
-Rasmus
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
On Thu, 04 May 2006 14:27:09 -0500
dante@vocalspace.com ("D. Dante Lorenso") wrote:
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).
I think it is time for you to do two things. The first is to read this
list archive about ifsetor (and other names it has), it will spare you
some ink and us some bandwidth. The second is to actually try the
filter extension and get some knowledge about what can be done where
and why. There is eventually a third one, try to imagine than the Z
Framework has nothing to do with php.net.
It is not an attack, but it seems you are putting so much effort on
this topic without actually having read what has been said and decided.
-- Pierre
On Thu, 04 May 2006 14:27:09 -0500
dante@vocalspace.com ("D. Dante Lorenso") wrote: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).I think it is time for you to do two things. The first is to read this
list archive about ifsetor (and other names it has), it will spare you
some ink and us some bandwidth. The second is to actually try the
filter extension and get some knowledge about what can be done where
and why. There is eventually a third one, try to imagine than the Z
Framework has nothing to do with php.net.It is not an attack, but it seems you are putting so much effort on
this topic without actually having read what has been said and
decided.
Well, from where I'm setting, Dante has brought up excellent points
that were never covered before according to my look at the list
archives. In fact, I find this situation indicative of a larger
problem, which is that extremely important discussions of major
issues with the language get breezed by far too quickly just because
someone decides it's not interesting enough or it's time to move on
(cough named parameters cough). I think the concept behind filled
() is sound, has merit, and is worth talking about seriously.
Jared
Well, from where I'm setting, Dante has brought up excellent points that
were never covered before according to my look at the list archives. In
fact, I find this situation indicative of a larger problem, which is
that extremely important discussions of major issues with the language
get breezed by far too quickly just because someone decides it's not
interesting enough or it's time to move on (cough named parameters
cough). I think the concept behind filled() is sound, has merit, and
is worth talking about seriously.Jared
+1
Dante's discussion has nothing to do with ifsetor() or the filter
extension IMO.
Brian Moon
dealnews.com
Jared, Brain,
Dante's discussion has nothing to do with ifsetor() or the filter
extension IMO.
His last answer has obviously something to do with both.
My answer answer is to his last post, which has obviously something to
do with that. My answer is also about his wrong statement (must be in
ZE2). Also did I take his point unserioulsy? no. I only told Dante to
read the list archives and to get the required knowledge before to
continue arguing.
--Pierre
Rick Widmer wrote:
D. Dante Lorenso wrote:
No, that doesn't address the problem. See this:
print @ifsetor($x, $y, $z, "dante")."\n";
Usage of the shutup operator, @, in this context is a shameful coding
habit and hides too much:
print @ifsetor($x, fakefunction($y), $z, "dante")."\n";
Does not show any warnings or errors, but REALLY hides this:
PHP Notice: Undefined variable: x in .../ifsetor.php on line 13
PHP Fatal error: Call to undefined function fakefunction() in
.../ifsetor.php on line 13
Ignoring the notice on $x is fine, but that fatal error shouldn't be
ignored.
Dante
Dear Internals,
I'd like a white bikeshed, but until you can decide on a color, how
about we just build the bikeshed already. Please consider the following
specification:
========== 8< ==================== 8< ==================== 8< ==========
filled
(PHP 5.2.0)
filled - Find first non-empty value in a variable list where empty()
evaluates as FALSE.
Description
mixed filled ( mixed varname [, mixed ...] )
filled() takes a variable number of parameters. For each of these,
filled() looks for a variable where !empty( varname ) evaluates as
TRUE. It returns the first non-empty value or NULL
if all values are
empty().
Note: filled() only checks variables as anything else will result in a
parse error. In other words, the following will not work:
filled(trim($name)).
filled() is the opposite of empty(), and no warning is generated
when any one of the variables is not set.
Return Values
Returns first non-empty() value.
If all values are empty(), returns NULL.
Example
<?php
echo filled($x["somekey"], $_GET["getkey"], $default, "example");
echo filled("yes"); // prints yes
filled(false); // returns NULL
echo filled($x["apple"], $y, "banana"); // prints banana
$y = "cat";
echo filled($x["apple"], $y, "banana"); // prints cat
$x["apple"] = "pear";
echo filled($x["apple"], $y, "banana"); // prints pear
unset($x["apple"]);
echo filled($x["apple"], $y, "banana"); // prints cat
?>
See also empty()
========== 8< ==================== 8< ==================== 8< ==========
Dante
The default value for 'filled()' if all values test TRUE
for empty()
should be FALSE, not NULL. This is more consistent with the return
values of empty().
Since filled() returns the first non-empty() value in the list of
parameters provided, it works well when cast into a boolean context
because the non-empty() value should evaluate as TRUE. Example:
filled("testing") // returns testing
if (filled("testing")) {} // true
filled(87) // returns 87
(boolean) filled(87) // true
$x["apple"] = "42";
filled($x["apple"]) // returns 42
filled($x["pear"]) // returns false
if (filled($x["apple"]) !== false) {} // true
if (filled($x["pear"]) !== false) {} // false
Just wanted to chime in with an update in case 'filled()' can actually
be considered. I'd like everyone to consider this one function to be
evaluated on it's merits alone and apart from any other functions which
also might be wanted. filled() is the opposite of empty() and is not
dealing with tests for 'isset()'. Another function should be proposed
to solve that problem if it would still be needed after filled() is
implemented.
Do I have any power to call a vote on this?
Dante
D. Dante Lorenso wrote:
Dear Internals,
I'd like a white bikeshed, but until you can decide on a color, how
about we just build the bikeshed already. Please consider the
following specification:========== 8< ==================== 8< ==================== 8< ==========
filled
(PHP 5.2.0)
filled - Find first non-empty value in a variable list where empty()
evaluates as FALSE.Description
mixed filled ( mixed varname [, mixed ...] )
filled() takes a variable number of parameters. For each of these,
filled() looks for a variable where !empty( varname ) evaluates as
TRUE. It returns the first non-empty value orNULL
if all values are
empty().Note: filled() only checks variables as anything else will result in a
parse error. In other words, the following will not work:
filled(trim($name)).
filled() is the opposite of empty(), and no warning is generated
when any one of the variables is not set.Return Values
Returns first non-empty() value.
If all values are empty(), returns NULL.
Example
<?php
echo filled($x["somekey"], $_GET["getkey"], $default, "example");
echo filled("yes"); // prints yes
filled(false); // returnsNULL
echo filled($x["apple"], $y, "banana"); // prints banana
$y = "cat";
echo filled($x["apple"], $y, "banana"); // prints cat
$x["apple"] = "pear";
echo filled($x["apple"], $y, "banana"); // prints pear
unset($x["apple"]);
echo filled($x["apple"], $y, "banana"); // prints cat
?>See also empty()
========== 8< ==================== 8< ==================== 8< ==========
Dante