📜 ⬆️ ⬇️

Implementing the Composite pattern in php

Introduction


At a certain stage of studying server programming, I wanted to write my own simple framework. I expected that this would help to more deeply understand the ideology of MVC and the Zend Framework in particular. When it came to the presentation and html generation part, I remembered the Composite pattern . Perhaps I have somewhat distorted its application, but the thought went from there.

To the point


Any page consists of objects that can also consist of objects. A sort of nesting suggests the idea of ​​recursive html-code generation. You also want to be able to supplement the contents of any part of the page at any time when the application logic is executed and generate the entire html code at once.

To business


Any object may contain another object, etc. Each object has a draw () method that displays the html code of its object and calls the draw () method for all children. Objects can be of different types (for example: article, list, post, photo album, header in the end). Of course, the implementation of the draw () method for each type of object will be different. I would like to express the above written code.

abstract class AbstractView { public $fillings; abstract public function draw(); protected function insert($filling_name){ if(isset($this->fillings[$filling_name])){ $this->fillings[$filling_name]->draw(); } } } 

The insert () method is the method by which the draw () methods of the child objects will be called in the draw () method. All child objects are contained in the $ fillings associative array. It is often necessary not to generate html-code, but simply to write a text or a number. Of course, you can Of course, for such purposes, inherit the View object, whose draw () method will simply output the necessary value specified, for example, in a constructor or an additional property. But it is not very convenient and will complicate the process of forming the page. Therefore, we will create a second associative array for storing such values ​​and a method for their output.
')
 abstract class AbstractView { public $fillings; public $values; abstract public function draw(); protected function insert($filling_name){ if(isset($this->fillings[$filling_name])){ $this->fillings[$filling_name]->draw(); } } protected function write($value_name){ if(isset($this->values[$value_name])){ echo $this->values[$value_name]; } } } 

Now we will write two simplest heirs for demonstration. One will represent the cap, and the second greeting.

 class LayoutView extends AbstractView { public function draw(){ include '/layout.phtml'; } } class IndexView extends AbstractView{ public function draw(){ include '/index.phtml'; } } 

What are the files layout.phtml and index.phtml?
layout.phtml:
 <!DOCTYPE html> <html> <head> <title><?php $this->write('title')?></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <?php $this->insert('content'); ?> </body> </html> 

index.phtml:
 <div>Hello, Habrahabr!</div> 

Connect everything and generate the page:

 $page = new LayoutView(); $page->values['title'] = "greating"; $page->fillings['content'] = new IndexView(); $page->draw(); 

Result:

 <!DOCTYPE html> <html> <head> <title>greating</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <div>Hello, Habrahabr!</div> </body> </html> 

At the moment, this implementation seems convenient to me, but it is possible that I will soon change my mind.

As Voltaire said:
“I may not agree with your opinion, but I am ready to give my life for your right to express it.”

PS: Please pay attention to the sdevalex comments about the VariableView class and arturgspb about typical security.

Source: https://habr.com/ru/post/149570/


All Articles