TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Advanced PHP Programming (http://www.talkphp.com/advanced-php-programming/)
-   -   When PHP tries to imitate C (http://www.talkphp.com/advanced-php-programming/1528-when-php-tries-imitate-c.html)

Gibou 11-27-2007 08:38 AM

When PHP tries to imitate C
 
Hi !

I have been impressed by this topic where Wildhoney gives a fantastic use of the __call magic method and it gave me the idea to propose mine. Don't hesitate to criticize :)

If someone here knows the C development, you have certainly heard about va_list. it's this kind of functions which can take as many parameters as you want.

For instance, in C, the first function you learn (printf) is a va_list. Indeed, you can give to it a string and after, as many parameters you have defined in the first string.

The prototype of a such function is : "int printf (const char *format, ...);"

The goal is to do the same in PHP with __call

For instance, an easy example, you want to do this kind of operation :

PHP Code:

$op->add(1,2,3);
// but too :
$op->add(1,2,3,4,5,6); 

To do that, you have to declare two differents method or to give an array of values in parameter and it's not very easy to read.

I propose this (in a class "Operation")

PHP Code:

public function __call($method$args null)
{
    if(
$args)
    {
        
// Initiation of the allowed methods
        
$possibleOps = Array(
        
"add" =>
        Array(
"method" => "addition""init" => 0),
        
"sub" =>
        Array(
"method" => "substract""init" => $args[0]*2),
        
"mul" =>
        Array(
"method" => "multiplicate""init" => 1),
        
"div" =>
        Array(
"method" => "divide""init" => pow($args[0],2))
        );

        
// If the called method is allowed...
        
if(in_array($method,$possibleOps) && sizeof($args) >= 2)
        {
            
// Selection of the method
            
$tools $possibleOps($method);
            
// Initiation of the temporary value
            
$tmp $tools["init"];
            
// Operations
            
foreach($args as $val)
                
$tmp $this->$tools["method"]($tmp,$val);
            unset(
$tools);
            unset(
$possibleOps);
            return(
$tmp);
        }
        else
            return 
"Method not allowed";
    }
}

// Tests
$op = new Operation();
echo 
$op->add(1,2,3,4,5)."<br />";
echo 
$op->sub(5,4)."<br />";
echo 
$op->mul(2,5,3)."<br />";
echo 
$op->div(40,4,5); 

Perhaps a little too heavy.
I confess I haven't tested it yet. Like we say in french, "à vue de nez, c'est bon" :D

What do you think of the concept ? I ask myself if the regulars accesses to the private methods don't burden the code in ram.

sjaq 11-27-2007 03:26 PM

func_get_args(); would also solve this problem and looks a lot less messy. (My first post by the way! :) )

Gibou 11-27-2007 03:34 PM

Indeed, thank you, I didn't know this function :)

Wildhoney 11-27-2007 03:50 PM

It's an interesting class. Incidentally, welcome to the community Sjag! However, func_get_args wouldn't cut it here because I think Gibou intended it to be so he can call the function for what it is. Instead of:

php Code:
$pObject->maths('add', 5, 10);

You could do:

php Code:
$pObject->add(5, 10);

I've come with a much more condensed function - still using the unsurpassed power of the magic method, __call! Here it is - based on Gibou's function:

php Code:
class Maths
{
    public function __call($szMethod, $aArgs)
    {
        $iTotal = $aArgs[0];
        unset($aArgs[0]);
       
        switch($szMethod)
        {
            case('add'): foreach($aArgs as $iValue) $iTotal += $iValue; break;
            case('minus'): foreach($aArgs as $iValue) $iTotal -= $iValue; break;
            case('divide'): foreach($aArgs as $iValue) $iTotal /= $iValue; break;
            case('multiply'): foreach($aArgs as $iValue) $iTotal *= $iValue; break;
        }
       
        return $iTotal;
    }
}

You can then use it like so:

php Code:
$pM = new Maths();
var_dump($pM->add(7, 10, 5, 2));

Which would add 10 to 7, 5 to 17, and 2 to 22, totalling 24. You can also do more complex things such as:

php Code:
var_dump($pM->multiply(5, 10, 2));

Which multiplies 10 by 5, to give us 50, then 50 by 2 to give us 100! I'm quite proud of this as I've never been any good at maths :( !

sketchMedia 11-27-2007 05:43 PM

another interesting topic containing __call().
Welcome to talkphp guys.

Gibou 11-27-2007 11:19 PM

Wildhoney > Indeed, that was the aim of this method : a clear way to do some similar operations.

sketchMedia > Thank you for the welcome. I have already read this topic but I think it won't be useless for me to re-read it.


All times are GMT. The time now is 01:09 PM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0