PHP ООП: создание глобального массива сообщений

Я пытаюсь отобразить массив сообщений в конце моего класса PHP. Мой обработчик сообщений работает, но только если я "add_message" из основного родительского класса, а не если я вызываю эту функцию из дочернего класса. Извините, если это расплывчато, но не знал, как сформулировать вопрос.

TL; DR; Как я могу добавить сообщение из класса Example?


ОСНОВНОЙ РОДИТЕЛЬСКИЙ КЛАСС

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();
    }

}

ОБРАБОТКА СООБЩЕНИЙ

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 );
    }

}

ПРИМЕР КЛАССА

class Example {
    public function fire_instance() {
        $this->messages = new Message_Handler();
        $this->messages->add_message( 'Hello Universe!' ); // This message is NOT being displayed...
    }
}

вы никогда не звоните display_messages() ... кстати: в вашем коде нет дочерний класс ...

B001ᛦ 03.08.2018 12:25

вы никогда нигде не сохраните переменную $messages. Попробуйте добавить protected $messages; в верхнюю часть вашего MessageHandlerВам действительно стоит подумать о чтении ООП, так как большая часть вашего кода недействительна.

Classified 03.08.2018 12:28
ideone.com/AmIihq
Nico 03.08.2018 12:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
121
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

Я бы использовал такую ​​статическую переменную:

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();

Большое спасибо, это помогло мне лучше понять статику!

James Husband 06.08.2018 16:37

Хотя глобальные переменные могут быть не лучшим дизайнерским решением, у вас есть как минимум два подхода для достижения желаемого:

  1. Используйте одиночка.

В настоящее время это считается антипаттерном, но это самый простой способ: сделать обработчик сообщений синглтоном:

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;
    }
}

Затем вместо создания нового экземпляра MessageHandler обращайтесь к нему с помощью статического метода MessageHandler::instance(). Вот демо.

  1. Используйте контейнер DI, чтобы внедрить один и тот же экземпляр (который создается один раз и хранится в контейнере) во все экземпляры, которым необходим доступ к нему. Этот подход более предпочтителен, но его сложнее реализовать в проекте, где изначально нет контейнера DI.

Другие вопросы по теме