dte66654
2018-08-03 10:15
浏览 23
已采纳

PHP OOP:创建全局消息数组

I am trying to display an array of messages at the end of my PHP class. My message handler is working, but only if I "add_message" from within the main parent class and not if I call this function from within a child class. Sorry if this is vague but was not sure how to word the question.

TLDR; How can I add a message from within class Example?


MAIN PARENT CLASS

class Init {

    public function __construct() {
        $this->load_dependencies();
        $this->add_messages();
        $this->add_msg_from_instance();
    }

    private function load_dependencies() {
        require_once ROOT . 'classes/class-messages.php';
        require_once ROOT . 'classes/class-example.php';
    }

    public function add_messages() {
        $this->messages = new Message_Handler();
        $this->messages->add_message( 'hello world' );
    }

    // I Would like to add a message from within this instance....
    public function add_msg_from_instance() {
        $example = new Example();
        $example->fire_instance();
    }

    public function run() {
        $this->messages->display_messages();
    }

}

MESSAGE HANDLER

class Message_Handler {

    public function __construct() {
        $this->messages = array();
    }

    public function add_message( $msg ) {
        $this->messages = $this->add( $this->messages, $msg );
    }

    private function add( $messages, $msg ) {
        $messages[] = $msg;
        return $messages;
    }


    // Final Function - Should display array of all messages
    public function display_messages() {
        var_dump( $this->messages );
    }

}

EXAMPLE CLASS

class Example {
    public function fire_instance() {
        $this->messages = new Message_Handler();
        $this->messages->add_message( 'Hello Universe!' ); // This message is NOT being displayed...
    }
}
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dou448172583 2018-08-03 13:18
    已采纳

    Because you want to keep the messages around different object, you should pass the object or use a static variable.

    I would use a static variable like so:

    class Init {
        public function __construct() {
            $this->load_dependencies();
            $this->add_messages();
            $this->add_msg_from_instance();
        }
    
        private function load_dependencies() {
            require_once ROOT . 'classes/class-messages.php';
            require_once ROOT . 'classes/class-example.php';
        }
    
        public function add_messages() {
            // renamed the message handler variable for clarity
            $this->message_handler = new Message_Handler();
            $this->message_handler->add_message( 'hello world' );
        }
    
        // I Would like to add a message from within this instance....
        public function add_msg_from_instance() {
            $example = new Example();
            $example->fire_instance();
        }
    
        public function run() {
            $this->message_handler->display_messages();
        }
    }
    
    class Message_Handler {
        // use a static var to remember the messages over all objects
        public static $_messages = array();
    
        // add message to static
        public function add_message( $msg ) {
            self::$_messages[] = $msg;
        }
    
        // Final Function - Should display array of all messages
        public function display_messages() {
            var_dump( self::$_messages );
        }
    }
    
    class Example {
        public function fire_instance() {
            // new object, same static array
            $message_handler = new Message_Handler();
            $message_handler->add_message( 'Hello Universe!' );
        }
    }
    
    // testing...
    new Init();
    new Init();
    $init = new Init();
    $init->add_msg_from_instance();
    $init->add_msg_from_instance();
    $init->add_msg_from_instance();
    $init->run();
    
    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • dongsaohu6429 2018-08-03 14:17

    Although global variables might not be the best design decision, you have at least two approaches to achieve what you want:

    1. Use singleton.

    Nowadays it is considered anti-pattern, but it is the simplest way: make message handler a singleton:

    class MessageHandler
    {
        private static $instance;
    
        private $messages = [];
    
        public static function instance(): self
        {
            if (null === self::$instance) {
                self::$instance = new self();
            }
    
            return self::$instance;
        }
    
        private function __construct()
        {
        }
    
        public function addMessage($message): self
        {
            $this->messages[] = $message;
    
            return $this;
        }
    
        public function messages(): array
        {
            return $this->messages;
        }
    }
    

    Then instead of creating a new instance of MessageHandler access it via the static method MessageHandler::instance(). Here is a demo.

    1. Use DI container to inject the same instance (that is created once and held in the container) into all instances that need to access it. This approach is more preferable, but harder to implement in the project where there is no DI container available in the first place.
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题