Puis-je déclarer une méthode dans un objet en tant que méthode statique et non statique avec le même nom que celui qui appelle la méthode statique?
Je veux créer une classe qui a une méthode statique "send" et une méthode non statique qui appelle la fonction statique. Par exemple:
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
}
}
Je veux pouvoir appeler la fonction sur ces deux était
test::send("Hello World!");
et
test::instance()->setText("Hello World")->send();
c'est possible?
Vous pouvez le faire, mais c'est un peu compliqué. Vous devez le faire en surchargeant: les méthodes __call
et __callStatic
magic.
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 function __callStatic($name, $arguments) {
if ($name === 'send') {
call_user_func(array('test', 'sendText'), $arguments[0]);
}
}
}
Ce n'est pas une solution idéale, cela rend votre code plus difficile à suivre, mais cela fonctionnera si vous avez PHP> = 5.3.
Il y a un moyen beaucoup plus simple.
class MyClass {
private $r = "I'm regular!";
private static $s = "I'm static!";
public function method() {
if (isset($this) && $this instanceof self) {
// Regular call
echo $this->r;
} else {
// Static call
echo static::$s;
}
}
}
Maintenant, vous pouvez facilement faire:
(new MyClass())->method();
// I'm regular!
ou
MyClass::method();
// I'm static!
Vous pouvez utiliser ce cadre pour réaliser tout ce que vous décrivez dans la question.
Note: Seul inconvénient, cela ne fonctionnera qu'avec PHP> = 5.4
Non, vous ne pouvez pas avoir deux méthodes avec le même nom. Vous pouvez fondamentalement faire la même chose en renommant l’une des méthodes. Renommer test::send("Hello World!");
en test::sendMessage("Hello World!");
fonctionnerait. Je créerais simplement la méthode d'envoi unique avec un argument texte facultatif qui modifie le fonctionnement de la méthode.
public function send($text = false) {
if (!$text) {
$text = $this -> text;
}
// Send something
}
Je suis curieux de savoir pourquoi vous avez besoin de la fonction statique.
Je créerais une classe cachée en tant que constructeur et renverrais cette classe cachée à l'intérieur de la classe parent qui a des méthodes statiques égales à celles de la classe cachée:
// 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;
}
}
Pour l'appeler statiquement:
Hook::on("click", function() {});
Pour l'appeler dynamiquement:
$hook = new Hook;
$hook->on("click", function() {});