开发者

Unable to call a function stored as string from inside a class

开发者 https://www.devze.com 2023-02-09 05:04 出处:网络
EDIT: Sorry guys, it was a typo =( I feel embarrassed for wasting your time on this. I\'m leaving this thread open in hopes that someone might find the discussed information useful.

EDIT: Sorry guys, it was a typo =(

I feel embarrassed for wasting your time on this. I'm leaving this thread open in hopes that someone might find the discussed information useful.

To clarify further, the code below will work as expected, I mistyped 'classHandler' in my code, and that's the reason PHP couldn't find it.

Also, the syntax errors noted by some commenters have been corrected

I feel obligated to summarize the discussion on this thread:


@wimvds suggests u开发者_如何学Csing inheritance and that my implementation is not a good practice.

@Victor Nicollet disagrees saying extending the behavior of an existing instance is 1. impossible and 2. bad design

@ircmaxell adds: Remember, you should always favor composition over inheritance. And this isn't spaghetti code, it's a pretty standard method of implementing a stripped down notification system (You could build a full blown observer or mediator pattern, but for really simple tasks, this may be a whole lot better since it's easier to maintain).

@Victor asks for a minimal one file example returning this error. This is what helped me solve the issue. When I tried the sample file, it work perfectly leading me to believe that something else indeed was wrong.

@Shakti Singh suggests trying call_user_func( array( $this, $this->handler ), $var);

@Victor Nicollet responds saying This would attempt to call a member function $this->classHandler (which probably doesn't exist) instead of the global classHandler

@abesto gives it a shot, ends up with a very similar implementation as my own, which works without my typo.

@Victor Nicollet answers by claiming that the classHandler needs to be defined prior to the call.

@Blizz responds by saying that PHP parses classes and functions first and then the regular code.


MyClass.php ( singleton )

public $handler;

public function myMethod()
{
    $var = "test";
    call_user_func( $this->handler, $var ); 
    // PHP Warning: First argument is expected to be a valid callback
}

Script.php

$myClass = new MyClass;
$myClass->handler = "classHandler";
$myClass->myMethod();

function classHandler( $var )
{
    echo $var;
}

If this is incorrect, what is the commonly practiced means of invoking handlers / event handlers in php?

Note that this is a simplified version of the actual script


You have to call something like this

call_user_func( array( $this, $this->handler ), $var);


Read your Script.php code again. What it's doing is:

  1. Instantiate MyClass (I'm assuming you forgot the new here).
  2. Define the handler to be classHandler.
  3. Run myMethod(), which attempts to call classHandler.
  4. Define classHandler.

Obviously, if you run 3 before you run 4, it's not going to work. You must define the function first, and then run any code that might want to call it.

In the larger scheme of things, I suspect there is no file like Script.php, and instead file A defines the class, file B instantiates the class and runs myMethodand file C defines classHandler. In such a situation, you need to make sure that file C is loaded before B is run.


First of all: if by storing functions as strings you mean that the actual implementation is in the string, then this is bad practice. You don't have to do it to get what you want.

function afun($param) {}
class BClass { function bfun($param) {} }

call_user_func('afun', 'param');  // Calls function afun

$binstance = new BClass();
call_user_func(array($binstance, 'bfun'), 'param'); // Calls bfun on binstance 


// Update according to comment
class CClass {
    private $handler;

    public function __construct($handler) { $this->handler = $handler; }

    public foo() {
      // do stuff
      call_user_func($this->handler, 'param');
    }
}
$cinstance = new CClass('afun');
$cinstance->foo();
0

精彩评论

暂无评论...
验证码 换一张
取 消