📜 ⬆️ ⬇️

PHP: Parameters in context

Problem:

It is required that several objects interacting with each other can control the logic of certain methods.

For example: each of the objects has a Data () method, which returns the data needed to display the object on the page (data for the template engine). For example, the $ news object of the News class should return 5 latest news in a form acceptable to the template engine, for example, in the form of an array. In turn, News :: Data () refers in turn to $ newsPost-> Data () objects (to nested objects) to obtain data relating to a particular news item (title, date, etc.). However, in some cases it is required that NewsPosé :: Data () return not complete data, but only a title (for example, on the main page of the site), and in another case it is required that all data be returned, including links to “news on the topic”.

Using several Data () methods (DataShort (), DataFull ()) would solve the problem, but I would like a more elegant solution.
')
The control script (say, the page constructor) “knows” in what form NewsPost :: Data () should return data, but it cannot directly interact with objects of the NewsPost class, because this is the “concern” of the News class. Consequently, all that the script can do is “ask” $ news “ask” $ newsPost to return the “abbreviated” data.

Copy Source | Copy HTML $ data = $news-> Data ( 'ask newsPost: return short data' );
  1. Copy Source | Copy HTML $ data = $news-> Data ( 'ask newsPost: return short data' );


then inside News :: Data () there will be something:

Copy Source | Copy HTML
  1. public function Data ( $ askWhat )
  2. {
  3. ...
  4. $ dataNews = $ this -> newsPost-> Data ( 'return short data' );
  5. ...
  6. }


perhaps NewsPost :: Data () is still accessing some objects, say NewsPostBody :: Data () for getting the article itself. Then, having received the “short data” request on NewsPost :: Data (), you need to make a request with the “body short” parameter to the NewsPostBody :: Data () method. It is not necessary for the “managing script” to be aware of this, but it is impossible to block the ability to directly “instruct” the object of the NewsPostBody class to return the “short version” of the article. That is something like:

Copy Source | Copy HTML
  1. $ data = $ news-> Data ( 'ask NewsPostBody: return short article' );


However, it is possible that you need to access the NewsPostBody :: Data () method with different parameters, and in one request. For example, when News contains a “site news”, where NewsPostBody :: Data () should always return a “uncircumcised” version. That is something like:

Copy Source | Copy HTML
  1. $ data = $ news-> Data ( 'ask NewsPostBody (main news only): return short article' );


or:

Copy Source | Copy HTML
  1. $ data = $ news-> Data ( 'return main news short body' );


but then News :: Data () should do something like this:

image

or even more difficult when other parameters are passed to SiteNewsBody :: Data (), for example, 'return SEO friendly body'.

Some technical requirements emerge:



Context :: Class :: Command

Class, in principle, is also in the first place in the context of "context", so that you can use "nesting contexts":

ContextInContextInContex :: Command

You should also think about the extended use of the command control component and provide for the possibility of separating the argument from the actual “command”, for example, “body_short = 250”, which may mean “limit the article to 250 characters”. We have:

ContextInContext :: Command [= Argument (s)];

Copy Source | Copy HTML
  1. $ data = $ news-> Data ( new Parameters ( 'NewsBodyInMainNews: short = 250; NewsBodyInSiteNews: seo_frendly; short = 500; NewsBody: keepHtml' ));


Let's try to sketch the interface "live":

Copy Source | Copy HTML
  1. function News :: Data ( $ params )
  2. {
  3. $ newsData = new NewsData ();
  4. // add the necessary data with parameters in the context of 'SiteNews'
  5. // parameter short = 500 and seo_freindly and keepHtml should be used
  6. $ params -> useContext ( 'SiteNews' );
  7. $ newsData -> add ( $ this -> getSiteNewsData ( $ params ));
  8. $ params -> dontUseContext ( 'SiteNews' );
  9. // add the necessary data with parameters in the context of 'MainNews'
  10. // only short = 250 and keepHtml parameters should be used
  11. $ params -> useContext ( 'MainNews' );
  12. $ newsData -> add ( $ this -> getMainNewsData ( $ params ));
  13. $ params -> dontUseContext ( 'MainNews' );
  14. return $ newsData ;
  15. }
  16. ...
  17. function NewsBody :: Data ( $ params )
  18. {
  19. $ newsBodyData = new NewsBodyData ();
  20. $ params -> useContext ( 'NewsBody' );
  21. $ bodyLimit = $ params -> get ( 'short' );
  22. $ newsBodyData -> add ( 'body' , $ this -> getBody ( $ bodyLimit ));
  23. $ params -> dontUseContext ( 'NewsBody' );
  24. ...
  25. return $ newsBodyData ;
  26. }


Almost everything is ready to start developing the class. To summarize and highlight the main points in the future class:



image

You can begin to implement.

Ps. The topic was once published by me. I have been using this pattern since then, without thinking whether it is a new “bicycle” or not. Perhaps someone will be useful. I would be happy to discuss konno.

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


All Articles