1

In PHP, I would like to refer to a member function.

For general functions I can assign the function to a variable, like so:

php > function h1() {echo "h1";}; h1();
h1
php > function h2() {echo "h2";}; h2();
h2
php > $hh = h1; $hh(); // ok: assign to a variable and call
h1
php > $hh = h2; $hh(); // ok: assign to a variable and call
h2

This is useful if you want to pass a function as an argument to another function.

But what about member functions?

class C { 
    function k(){ echo "k";}
    function j(){ $a = $this->k; $a();} // assign k() to a variable
    function m(){ $a = "k"; $this->$a();} // assign the name "k" to a variable
};

This works:

php > $c = new C();
php > $c->k();
k
> $c->m(); // variable-function approach
k

But this does not (tested in CLI)

php > $c->j();
Warning: Uncaught Error

Is my syntax wrong, or is the variable-function approach the only way?

P2000
  • 1,042
  • 8
  • 14
  • 1
    Possible duplicate of [Pass a function by reference in PHP](https://stackoverflow.com/questions/6475136/pass-a-function-by-reference-in-php) – Noah Boegli May 20 '20 at 21:38
  • Good find @NoahBoegli. That question is about general functions, and it is possibly answered by my first example with h1 and h2. I am not sure how new this capability is in PHP, so perhaps it was not available at the time of the older post in 2011. My question here is about member functions. – P2000 May 20 '20 at 21:54
  • Thanks @JaredFarrish, yes that's my example for function m(), above. It turns out $hh = h1; $hh(); is NOT a reference to h1(), but rather the same as $hh="h1". Yes, PHP accepts an unquoted word as a string. However, instead of function h1(){...} you can do $h1 = function() { ...}. Now $h1 is an Object, not a string, and you can reassign it as $hh = $h1. BTW I have meanwhile figure it out: you can use "Complex callables". In class C above: function j(){ $func = array($this,"k"); $func(); } does what I need. The 1st element in the array can be any object. – P2000 May 23 '20 at 05:29
  • 1
    After some digging @NoahBoegli, the question you mention does have an answer that applies (even though that question was not quite what I was after). So thanks for pointing me to it. – P2000 May 23 '20 at 06:35

2 Answers2

1

function j(){ $a = $this->k; $a();} // assign k() to a variable

Slight misunderstanding here. That is assigning the value of class property k to $a. That is not the same as class member k(). If k does not exist as a class property of C, the value of $a will be NULL.

Change that to k() you might think, but that just assigns the return of k(), not the contents of the function itself.

I think this might help: What is the scope of a PHP function defined within a PHP anonymous function?

parttimeturtle
  • 1,125
  • 7
  • 22
  • Indeed, which is why $a = $this->k is not an error, although method k() already exists and an eponymous property k should really not be allowed. But alas. it's PHP. As the referenced post mentions, this is a typical construct used with anonymous functions, but that is not what I have here. So, do you know of a syntax to get what I want? – P2000 May 20 '20 at 22:00
  • I'm not sure what you want honestly. Your question seems predicated on the fact that you're "assigning the function to a variable" in the first code block but that's not what's actually happening. You're using what's known as 'variable functions' in PHP, which is basically just string expansion: https://www.php.net/manual/en/functions.variable-functions.php. – parttimeturtle May 22 '20 at 20:54
  • You are right! $hh = h1 is a string assignment, without quotes! I thought $hh = h1 would assign function h1 to variable $h, treating it like a (first class) function object similar to $h1 = function(){echo "inside anon";} You can call it as $h1(); or, as I intend, reassign $hh = $h1 and call $hh(); BTW I have meanwhile figure it out: you can use "Complex callables". In class C above: function j(){ $func = array($this,"k"); $func(); } does what I need. – P2000 May 23 '20 at 05:23
  • 1
    So thanks for pointing me to the variable-functions page, which mentions the array( object, name) under complex callables. – P2000 May 23 '20 at 06:47
0

I wrote simple example to illustrate what's happening here. In your example internal function (method) calls non-existing function k() from outer scope, that's why there is fatal error.

function k() {
    return 'k()';
}

class C {
    function k(){ return 'C->k()';}
    function l(){ return 'C->l()';}

    function g(){ return k();}
    function h(){ return l();}
};

$c = new C();

print($c->k()); //C->k()

print($c->g()); //k()

print($c->h()); //PHP Fatal error:  Uncaught Error: Call to undefined function l()

Simple work-around for that is use of complex callables.

class C {
    function l(){ return 'C->l()';}

    function i(){
        $callable = array($this,'l');
        return $callable(); }
};

$c = new C();

print($c->i()); // C->l()
Jsowa
  • 9,104
  • 5
  • 56
  • 60