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

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.
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 在工控机(Ubuntu系统)上外接USB蓝牙硬件进行蓝牙通信
  • ¥15 关于PROCEDURE和FUNCTION的问题
  • ¥100 webapi的部署(标签-服务器)
  • ¥20 怎么加快手机软件内部计时的时间(关键词-日期时间)
  • ¥15 C语言除0问题的检测方法
  • ¥15 为什么四分管的内径有的是16mm有的15mm,四分不应该是12.7mm吗
  • ¥15 macos13下 ios交叉编译的问题
  • ¥15 bgz压缩文件怎么打开
  • ¥15 封装dll(引入了pcl的点云设计库)
  • ¥30 关于#开发语言#的问题:我需要在抄板的基础上再抄板抄程序,根据RDA8851CM基础上开发