php 5.6+ callback

Для удобности работы с callback функциями напишем небольшой класс.
  1. <?php
  2.  
  3. class Callback
  4. {
  5.  
  6.     /**
  7.      *  @var \Closure|array|string
  8.      */
  9.     private $callback;
  10.  
  11.     /**
  12.      *  @param \Closure|object|string $name
  13.      *  @param string $method
  14.      */
  15.     public function __construct($name, $method = false) {
  16.  
  17.         if ($name instanceof \Closure) {
  18.             $this->callback = $name;
  19.         } else if (is_object($name)) {
  20.             $this->callback = array($name,
  21.                 $method);
  22.         } else if ($method) {
  23.             $this->callback = $name . '::' . $method;
  24.         } else {
  25.             $this->callback = $name;
  26.         }
  27.  
  28.         if (!is_callable($this->callback)) {
  29.             throw new \InvalidArgumentException('...');
  30.         }
  31.  
  32.     }
  33.  
  34.     /**
  35.      *  @return mixed
  36.      */
  37.     public function __invoke() {
  38.         return call_user_func_array($this->callback, func_get_args());
  39.     }
  40.  
  41.     /**
  42.      *  @param array $args
  43.      * 
  44.      *  @return mixed
  45.      */
  46.     public function call(array $args = []) {
  47.  
  48.         $callback = [
  49.             $this, '__invoke'
  50.         ];
  51.  
  52.         return call_user_func_array($callback, $args);
  53.  
  54.     }
  55.  
  56.     /**
  57.      *  @return boolean
  58.      */
  59.     public function isClosure() {
  60.         return $this->callback instanceof \Closure;
  61.     }
  62.  
  63.     /**
  64.      *  @return boolean
  65.      */
  66.     public function isDynamicMethod() {
  67.         return is_array($this->callback);
  68.     }
  69.  
  70.     /**
  71.      *  @return boolean
  72.      */
  73.     public function isStaticMethod() {
  74.         return is_string($this->callback) && false !== strpos($this->callback, ':');
  75.     }
  76.  
  77.     /**
  78.      *  @return boolean
  79.      */
  80.     public function isFunction() {
  81.         return is_string($this->callback) && !$this->isStaticMethod();
  82.     }
  83.  
  84.     /**
  85.      *  @return boolean
  86.      */
  87.     public function toString() {
  88.         if ($this->isStaticMethod() || $this->isFunction()) {
  89.             return $this->callback;
  90.         }
  91.     }
  92.  
  93. }
Класс-помощник, который разрешит проблему.
  1. class CallbackResolver
  2. {
  3.  
  4.     public static function resolve($callback) {
  5.         if (is_string($callback) && false !== strpos($callback, ':')) {
  6.             list ($class, $method) = explode('::', $callback, 2);
  7.             return new Callback($class, $method);
  8.         } else if (is_array($callback) && 2 == count($callback) && is_object($callback[0]) && is_string($callback[1])) {
  9.             return new Callback($callback[0], $callback[1]);
  10.         } else {
  11.             return new Callback($callback);
  12.         }
  13.     }
  14.  
  15. }
Пример использования:
  1. <?php
  2.  
  3. //  Пример №1
  4. function test() {
  5.     return 'Привет, мир!';
  6. }
  7.  
  8. try {
  9.     $callback = CallbackResolver::resolve('test');
  10.     if ($callback instanceof Callback) {
  11.  
  12.         //  Функция?
  13.         if ($callback->isFunction()) {
  14.  
  15.             //  Вызов двумя способами:
  16.             $callback(/* arg, arg,.. */);
  17.  
  18.             // или
  19.  
  20.             $callback->call([
  21.                 //  args
  22.             ]);
  23.  
  24.         }
  25.  
  26.     }
  27. } catch (\InvalidArgumentException $e) {
  28.     // Обработка исключения
  29. }
  30.  
  31.  
  32. //  Пример №2
  33. try
  34. {
  35.  
  36.     $callback = CallbackResolver::resolve('test2');
  37.  
  38.     // 
  39.  
  40. } catch (\InvalidArgumentException $e) {
  41.     //  Обработка исключения
  42. }
  43.  
  44. //  В данном случае нужно будет обработать исключение т.к функции test2 не существует
  45.  
  46. //  Пример №3
  47.  
  48.  
  49. class test
  50. {
  51.  
  52.     public static function test($name) {
  53.         echo 'Привет, мир!';
  54.     }
  55.  
  56. }
  57.  
  58. try
  59. {
  60.  
  61.     $callback = CallbackResolver::resolve('test::test');
  62.     if ($callback instanceof Callback) {
  63.         if ($callback->isStaticMethod()) {
  64.             $callback();
  65.         }
  66.     }
  67. } catch (\InvalidArgumentException $e) {
  68.     //  Обработка исключения
  69. }
  70.  
  71. //  Пример №4
  72. try
  73. {
  74.  
  75.     $callback = CallbackResolver::resolve(function() {
  76.         echo 'Привет, мир!';
  77.     });
  78.     if ($callback instanceof Callback) {
  79.         if ($callback->isClosure()) {
  80.             $callback();
  81.         }
  82.     }
  83. } catch (\InvalidArgumentException $e) {
  84.     //  Обработка исключения
  85. }
  86.  
  87. //  Пример №5
  88.  
  89. class test
  90. {
  91.  
  92.     public function test() {
  93.         echo 'Привет, мир!';
  94.     }
  95.  
  96. }
  97.  
  98. try
  99. {
  100.  
  101.     $callback = CallbackResolver::resolve([new test(), 'test']);
  102.     if ($callback instanceof Callback) {
  103.         if ($callback->isDynamicMethod()) {
  104.             $callback();
  105.         }
  106.     }
  107. } catch (\InvalidArgumentException $e) {
  108.     //  Обработка исключения
  109. }

Реклама

Мы в соцсетях

tw tg yt gt