Forum Moderators: coopster
// neato, easy to read and write:
var str = 'StRiiiNg'.toLowerCase().replace(/i+/, 'i').toUpperCase();
alert(str); // STRING
I got to thinking yesterday if you could achieve this effect in PHP to chain together functions. There are two patterns that I use right now when I need to apply multiple transformations to a value:
// sucky, easy to nest parentheses wrong, hard to read
$str = strtoupper(preg_replace('/i+/','i', strtolower('StRiiiNg')));
echo $str; // STRING
// good, easy to read but takes up lots of lines for simple transformations
$str = 'StRiiiNg';
$str = strtolower($str);
$str = preg_replace('/i+/','i',$str);
$str = strtoupper($str);
echo $str; // STRING
Since this was bugging me, I played around and put together the following little test. Since each function returns $this (a handle to the object) you can call functions one right after the other.
class str_functions {
var $a;
function str_functions($string = null){
$this->a = $string;
return $this;
}
function get(){
return $this->a;
}
function strtoupper(){
$this->a = strtoupper($this->a);
return $this;
}
function strtolower(){
$this->a = strtolower($this->a);
return $this;
}
function preg_replace($find, $replace){
$this->a = preg_replace($find, $replace, $this->a);
return $this;
}
}
[b]$str = new str_functions('StRiiiNg');
$str = $str->strtolower()->preg_replace('/i+/','i')->strtoupper()->get();
echo $str; // STRING
[/b]
Would it really suck to have to rewrite every existing function into a custom class just for this benefit? Yeah, definitely.
Could this be applied to new custom classes? Maybe... What do you think? :)
I need to understand your solutions benefits
actually what is the dif between "yours" and:
OOP
$db = new stuffs
$db= conn this and that
and then $num=$db->num_rows($result);
or
while($row=$db->fetch_array($result));
where both functions are custom ()
and both easy to implement and read
the domino effect is also there
A) conn
B) use result of conn for any custom ()
but again I probably miss your point :)
your solutions benefits
I'm actually not sure it's worth it myself. :)
A definite drawback to having the functions return $this is that if you only need one function performed, then you have to call an extra function to get the actual result back out:
echo $str->strtolower()->get(); // this is less efficient typing :(
free transform function
Hmm. This is how far I got before realizing I don't have a clue how to do that. :)
// ...inside the str_functions class...
function e($function_name){
if(function_exists($function_name)){
if(func_num_args()==1){
$this->a = $function_name($this->a);
} else {
$_args = func_get_args();
$function_name = array_shift($_args);
$this->a = $function_name($this->a, $_args);
// err, how would i pass an unknown number of arguments to the function?
}
}
return $this;
}
The code above works for simple ones like strtolower and strtoupper but anything with multiple parameters chokes. Obviously, I realize, since I can't pass an array as the second parameter and expect the function to magically extract the values out of that array.
$str = new str_functions('StRiiiNg');
$str = $str->e('strtolower')->e('preg_replace','/i+/','i')->e('strtoupper')->get(); // Warning: Wrong parameter count for preg_replace()
since I can't pass an array as the second parameter...
Problem now is that there is no way to know what each function returns and what to do with it. With an assumption of string manipulation, you can always just assign the return of the user function to $this->a. But if you assume array manipulation, assigning the return of the functions often overwrites the $this->a with a boolean, causing you to lose the original array.
class Chain {
private $a;
function chain($string = null){
$this->set($string);
return $this;
}
function get(){
return $this->a;
}
function set($string = null){
$this->a = $string;
return $this;
}
function e($function_name){
if(function_exists($function_name)){
if(func_num_args()==1){
$return = $function_name($this->a);
$this->a = $return; // this is not always what you'd expect :/
} else {
$_args = func_get_args();
$function_name = array_shift($_args);
$return = call_user_func_array($function_name, $_args);
$this->a = $return; // this is not always what you'd expect :/
}
}
return $this;
}
}
// works
echo $c->set('StRiiiNg')->e('strtolower')->e('preg_replace','/i+/','i', $c->get())->e('strtoupper')->get();
// the shuffle hoses the array
print_r($c->set($array)->e('shuffle')->e('array_merge', $c->get(), array(12,13,16))->e('sort')->get());