Is it possible to declare a method static and nonstatic in PHP?

Can I declare a method in an object as both a static and non-static method with the same name that calls the static method?

I want to create a class that has a static method "send" and a non-static method that calls the static function. For example:

class test {
    private $text;
    public static function instance() {
        return new test();
    }

    public function setText($text) {
        $this->text = $text;
        return $this;
    }

    public function send() {
        self::send($this->text);
    }

    public static function send($text) {
        // send something
    }
}

I want to be able to call the function on these two was

test::send("Hello World!");

and

test::instance()->setText("Hello World")->send();

is it possible?


You can do this, but it's a bit tricky. You have to do it with overloading: the __call and __callStatic magic methods.

class test {
    private $text;
    public static function instance() {
        return new test();
    }

    public function setText($text) {
        $this->text = $text;
        return $this;
    }

    public function sendObject() {
        self::send($this->text);
    }

    public static function sendText($text) {
        // send something
    }

    public function __call($name, $arguments) {
        if ($name === 'send') {
            call_user_func(array($this, 'sendObject'));
        }
    }

    public static function __callStatic($name, $arguments) {
        if ($name === 'send') {
            call_user_func(array('test', 'sendText'), $arguments[0]);
        }
    }
}

This isn't an ideal solution, as it makes your code harder to follow, but it will work, provided you have PHP >= 5.3.


I would make a hidden class as the constructor and return that hidden class inside the parent class that has static methods equal to the hidden class methods:

// Parent class

class Hook {

    protected static $hooks = [];

    public function __construct() {
        return new __Hook();
    }

    public static function on($event, $fn) {
        self::$hooks[$event][] = $fn;
    }

}


// Hidden class

class __Hook {

    protected $hooks = [];

    public function on($event, $fn) {
        $this->hooks[$event][] = $fn;
    }

}

To call it statically:

Hook::on("click", function() {});

To call it dynamically:

$hook = new Hook;
$hook->on("click", function() {});

No you can't have two methods with the same name. You could do basicly the same thing by renaming one of the methods. Renaming test::send("Hello World!"); to test::sendMessage("Hello World!"); would work. I would just create the a single send method with an optional text argument that changes how the method functions.

public function send($text = false) {
    if (!$text) {
        $text = $this -> text;
    }

    // Send something
}

I courious as to why you need the static function at all.