note 102615 added to functions.anonymous

[email protected] Thu, 24 Feb 2011 07:51:10 -0800
Newsgroups php.notes
Message-ID <[email protected]>
You may have been disapointed if you tried to call a closure stored in an instance variable as you would regularly do with methods:

<?php

$obj = new StdClass();

$obj->func = function(){
 echo "hello";
};

//$obj->func(); // doesn't work! php tries to match an instance method called "func" that is not defined in the original class' signature

// you have to do this instead:
$func = $obj->func;
$func();

// or:
call_user_func($obj->func);

// however, you might wanna check this out:
$array['func'] = function(){
 echo "hello";
};

$array['func'](); // it works! i discovered that just recently ;)
?>

Now, coming back to the problem of assigning functions/methods "on the fly" to an object and being able to call them as if they were regular methods, you could trick php with this lawbreaker-code:

<?php
class test{
 private $functions = array();
 private $vars = array();
 
 function __set($name,$data)
 {
  if(is_callable($data))
    $this->functions[$name] = $data;
  else
   $this->vars[$name] = $data;
 }
 
 function __get($name)
 {
  if(isset($this->vars[$name]))
   return $this->vars[$name];
 }
 
 function __call($method,$args)
 {
  if(isset($this->functions[$method]))
  {
   call_user_func_array($this->functions[$method],$args);
  } else {
   // error out
  }
 }
}

// LET'S BREAK SOME LAW NOW!
$obj = new test;

$obj->sayHelloWithMyName = function($name){
 echo "Hello $name!";
};

$obj->sayHelloWithMyName('Fabio'); // Hello Fabio!

// THE OLD WAY (NON-CLOSURE) ALSO WORKS:

function sayHello()
{
 echo "Hello!";
}

$obj->justSayHello = 'sayHello';
$obj->justSayHello(); // Hello!
?>

NOTICE: of course this is very bad practice since you cannot refere to protected or private fields/methods inside these pseudo "methods" as they are not instance methods at all but rather ordinary functions/closures assigned to the object's instance variables "on the fly". But I hope you've enjoyed the jurney ;)
----
Server IP: 69.147.83.197
Probable Submitter: 187.54.190.149
----
Manual Page -- http://www.php.net/manual/en/functions.anonymous.php
Edit        -- https://master.php.net/note/edit/102615
Del: integrated  -- https://master.php.net/note/delete/102615/integrated
Del: useless     -- https://master.php.net/note/delete/102615/useless
Del: bad code    -- https://master.php.net/note/delete/102615/bad+code
Del: spam        -- https://master.php.net/note/delete/102615/spam
Del: non-english -- https://master.php.net/note/delete/102615/non-english
Del: in docs     -- https://master.php.net/note/delete/102615/in+docs
Del: other reasons-- https://master.php.net/note/delete/102615
Reject      -- https://master.php.net/note/reject/102615
Search      -- https://master.php.net/manage/user-notes.php