3

The following is a static method of a given class:

class myClass {
  public static function contentFilter($content) {
    // ... irrelevant code
    if (!function_exists('replaceCallback')) {
        function replaceCallback($matches) {
            // relevant line of code 
            $result = return_setting($params);
            return $result;
        };
    }
    $new_content = preg_replace_callback($regex, 'replaceCallback', $new_content);
    return $new_content;
  }
}

The function return_setting inside replaceCallback is a globalized version of the static returnSetting method from the same class. The code works, but it doesn't feel right that I have to globalize the function before I can access it, I feel like I should be able to do self::returnSetting(). When I do this, I get the error ofc.

Fatal error: Cannot access self:: when no class scope is active

Doing myClass::returnSetting works, but it's kind of awkward to refer to the class by its name inside one of its methods. Or can one do self::replaceCallback in the replace_callback function? Is there any preferred way to do this?

PS: I need to pass the replaceCallback function as a string to preg_replace_callback because I need to support PHP 5.2.

webketje
  • 10,376
  • 3
  • 25
  • 54
  • the function `replaceCallback`, the one your defining in `contentFilter`, is not a member of the class `myClass` in any way. Anyhow you can't use `self` because the method is not invoked inside the class itself but outside it. That why `self` is not accessible, it will be invoked through `call_user_function` when the preg_replace is done – DarkBee Mar 26 '15 at 20:32
  • I know, apparently I haven't made myself clear enough. The problem is not `replaceCallback`, the problem is `myClass::returnSetting` should be executed inside `replaceCallback`, how to do that? – webketje Mar 26 '15 at 20:34

2 Answers2

1

The solution I went with (derived from a previously posted answer here that got deleted by its author) is the following:

I made the replaceCallback function a private member of the class, so that I could directly do self::returnSetting() inside of it. For compatibility, i passed the replaceCallback function to preg_replace_callback as array('self','replaceCallback').

class myClass {
  private static function replaceCallback($match) {
    $output = self::returnSetting('param');
    // bunch of other stuff
    return $output;
  }
  public static function contentFilter($content) {
    // ... irrelevant code
    $new_content = preg_replace_callback($regex, array('self','replaceCallback'), $new_content);
    return $new_content;
  }
}
webketje
  • 10,376
  • 3
  • 25
  • 54
0

a function always has a global scope no matter where it's declared ,even though replaceCallback declared in myClass its scope will always be global (i.e it doesn't have the class scope,the self:: reference doesn't work)

so you need to do myClass::functionName() as you would do outside of the class

"All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa." doc

wonde
  • 1,181
  • 10
  • 20
  • Ok, but isn't there a way to "import" the parent scope into `replaceCallback` ? With `global`? Assigning `self` to a variable? Ideally I would do `self::functionName()` **inside** the `replaceCallback` function, instead of referring to it as `myClass`.. – webketje Mar 26 '15 at 20:37
  • You can't hold `self` in a variable. It's only a shortcurt to the current class its in. Even if you would like to do this you would need PHP5.4+ and a proper instance of the class. [closure with $this support](http://stackoverflow.com/questions/5734011/php-5-4-closure-this-support) – DarkBee Mar 26 '15 at 20:41
  • @DarkBee That's sad; in javascript one can simply assign the parent scope to a variable, then reference that variable in infinitely nested child functions.. Thanks anyway – webketje Mar 27 '15 at 01:48