Создание метода в PHP автоматически запускает некоторый код после вызова.Возможный? - PullRequest
1 голос
/ 11 марта 2012

Я не совсем уверен, имеет ли имя то, что я ищу, поэтому мне было немного трудно его искать, поэтому я прошу прощения, если на то, что я спрашиваю, уже был дан ответ здесь.

Ситуация такова, что у меня есть абстрактный класс, который, конечно, имеет много других классов, расширяющих его.

Абстрактный метод в абстрактном классе называется run(), и все расширяющие классы определяютэтот метод.

Моя проблема в том, что я хочу вызвать некоторый общий код после вызова метода run(), но я хочу знать, есть ли лучший способ сделать это.

Конечно, я мог бы просто вставить свой общий код в метод run() каждого расширяющего класса, но если я сделаю это, мне будет очень сложно внести простые изменения с этого момента.

Я мог бы также поместить свой общий код в метод родительского класса и затем вызвать метод из run() расширяющего класса с помощью $this.

Но мой вопрос в том, есть ли лучшийспособ сделать это, или мне нужно либо использовать ключевое слово $this, либо вставить код в код каждого класса?

Вот небольшой пример того, что я хочу сделать с моей текущей идеей:

abstract class Parent_Class {
    public abstract function run();

    protected function common_code() {
        // Common code here
    }
}

class Child_Class {
    public function run() {
        // Code here
        // I want some common code to run after the run method has been called

        $this->common_code(); // Is this the best way to do it?
    }
}

Или можно как-то сказать классу, что при вызове метода run() для автоматического запуска метода common_code()?

Ответы [ 3 ]

2 голосов
/ 11 марта 2012

Гораздо более простой способ сделать это - просто использовать третий метод, который вызывает run(), а затем вызывает common_code(). Подклассы могут затем переопределить run() все, что они хотят.

abstract class Parent_Class {
    public abstract function run();

    protected function common_code() {
        // Common code here
    }

    protected function start() {
        $this->run();
        $this->common_code();
    }

}

class Child_Class {
    public function run() {
        // Code here
    }
}
1 голос
/ 12 декабря 2015

Основываясь на ответе Брэдли Форстера, вы можете определить метод как защищенный, поэтому, когда он вызывается извне класса, вы можете перехватить событие с помощью php magic __ call метод, потому что

__ call () срабатывает при вызове недоступных методов в контексте объекта.

и затем вы можете выполнить этот метод из функции __call

class A {

  public function __call($method, $args){

     if(!method_exists($this, $method))
       throw new Exception("Call to undefined method ".__CLASS__."::$method()");

     echo "doing something BEFORE function 'run' execution\n";

     $retval = call_user_func_array(array($this, $method), $args);

     echo "doing something AFTER function 'run' execution\n";

     return $retval;
  }

  protected function run() {
      echo "function 'run' executed\n" ;
  }
}

$a = new A;
$a->run();
1 голос
/ 11 марта 2012

Ответ от Amber хорош и прост. Но требует, чтобы вы поместили свои данные в run(), но позвоните start() Вот альтернатива, которая позволяет вам иметь код $a->run() во всех ваших сценариях и $a->run() с вашим общим кодом, но инкапсулированным в пространстве имен.

Файл hooks.php

<?php
// File: hooks.php
namespace hook;

class processHooks {
    public function __construct() { /* Fatal Error without constructor */ }

    protected function processHooks($_c, $method, $args) {
        /* Swap the next two callbacks to run your custom code after */
        call_user_func_array("\hook\\{$_c}::{$method}", $args);
        return call_user_func_array(array($_c,$method), $args);
    }
}

class A {
    public function foo() {
        echo 'Doing code stuff BEFORE calling child function....<br>';
    }
}

Файл normal_file.php

<?php
// File: regular_file.php
include "hooks.php";

class A extends \hook\processHooks {

    /* All that is required is this function
     * and the function with common code to be protected
     */
    public function __call($method, $args) {
        self::processHooks(__CLASS__, $method, $args);
    }

    protected function foo() {
        echo 'Method is called....<br>';
    }
}

$a = new A();
$a->foo();

Это работает, потому что метод foo класса A в регулярный_файл.php защищен, поэтому он не может вызываться вне класса, поэтому его вызов вызывает магию PHP метод __ call

__ call () запускается при вызове недоступных методов в контексте объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...