note 88528 added to ref.funchand
| From: | php dot spamguard at pulseforce dot com | Date: | Wed, 28 Jan 2009 02:31:04 +0000 |
| Subject: | note 88528 added to ref.funchand | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-149873@lists.php.net to get a copy of this message | ||
PHP is great in how it allows you to send a variable-length argument list to a function by using the
func_* functions. However, unfortunately (and this has been brought up numerous time in PHP bug
reports/feature requests), it doesn't support passing arguments by reference which would have
greatly simplified processing multiple variables at once by simply doing: somefunction($a, $b, $c)
and having them processed, without having to do any additional assignment.
However, I've discovered a way to leverage several features of PHP and created a very good
example that shows how you can process multiple variables in one fell swoop!
The usage is (with my example function/class):
"list($a, $b, $c, $d, $e) = TextEscape::escape_multi($a, $b, $c, $d, $e);"
If PHP had ACTUALLY been capable of passing variables by reference when using variable-length
argument lists, that could have been reduced to:
"TextEscape::escape_multi($a, $b, $c, $d, $e);"
It's extremely close though, both in simplicity and speed. Just be VERY sure to ALWAYS have the
SAME NUMBER AND ORDER of arguments on both sides of that statement.
The use of a static class was just to make the code cleaner and easier to look at. This can be
applied to any functions!
Now, onto the code, enjoy the sheer brilliance and enjoy modifying multiple variables at once in
just ONE statement! ;-)
<?php
class TextEscape
{
public static function escape_string($sString)
{
/* can be anything, using htmlspecialchars() in this example */
return htmlspecialchars($sString);
}
public static function escape_multi()
{
/* get all variables passed to the function */
$aVariables = func_get_args();
/* loop through the array, escaping each variable */
foreach ($aVariables as $iKey => $sValue)
{
$aVariables[$iKey] = TextEscape::escape_string($sValue);
}
/* return the escaped values */
return $aVariables;
}
}
// Create test variables
$a = "A<bar";
$b = "B>bar";
$c = "C<bar";
$d = "D>bar";
$e = "E<bar";
// Variables Before:
// Array
// (
// [0] => A<bar
// [1] => B>bar
// [2] => C<bar
// [3] => D>bar
// [4] => E<bar
// )
print_r(array($a, $b, $c, $d, $e));
// Process every variable at once,
// we're exploiting both how list() and
// variable-length argument lists work
// to make the usage this smooth! ;-)
list($a, $b, $c, $d, $e) = TextEscape::escape_multi($a, $b, $c, $d, $e);
// Variables After:
// Array
// (
// [0] => A<bar
// [1] => B>bar
// [2] => C<bar
// [3] => D>bar
// [4] => E<bar
// )
print_r(array($a, $b, $c, $d, $e));
?>
That's the CLEAN LOOKING version of the code, which illustrates exactly what is HAPPENING.
I also made a speedfreak edition of the function, but didn't want to post it as the main
example since it's harder to read.
But it's faster, much faster! It passes by reference where it can and loops in a more efficient
way.
Just replace the above function with this one, the outcome is the same but the speed is better:
<?php
class TextEscape
{
public static function escape_string(&$sString) // CHANGED: we now pass by reference to the
actual text processing function
{
/* can be anything, using htmlspecialchars() in this example */
$sString = htmlspecialchars($sString);
}
public static function escape_multi()
{
/* get all variables passed to the function */
$aVariables = func_get_args();
/* loop through the array, escaping each variable */
for ($i=(count($aVariables)-1); $i>=0; $i--) // CHANGED: a more efficient for-loop is used
instead of a foreach; and for anyone wondering about the counter declaration, this is a common
optimization trick which makes it so that the size of the array only has to be checked ONCE, by
initializing the counter to the index of the last element (which is size of array minus 1) and then
iterating downwards until we reach 0 (the first element)
{
TextEscape::escape_string($aVariables[$i]); // CHANGED: this has been changed to modify the
variable by reference instead
}
/* return the escaped values */
return $aVariables;
}
}
?>
Enjoy!
----
Server IP: 80.67.2.2
Probable Submitter: 217.73.106.170
----
Manual Page -- http://www.php.net/manual/en/ref.funchand.php
Edit -- https://master.php.net/note/edit/88528
Del: integrated -- https://master.php.net/note/delete/88528/integrated
Del: useless -- https://master.php.net/note/delete/88528/useless
Del: bad code -- https://master.php.net/note/delete/88528/bad+code
Del: spam -- https://master.php.net/note/delete/88528/spam
Del: non-english -- https://master.php.net/note/delete/88528/non-english
Del: in docs -- https://master.php.net/note/delete/88528/in+docs
Del: other reasons-- https://master.php.net/note/delete/88528
Reject -- https://master.php.net/note/reject/88528
Search -- https://master.php.net/manage/user-notes.php