Hi people! I am writing an application in PHP, and I need to declare external classes, while writing a flexible connection mechanism. I stopped at the overloading of properties and methods + inheritance, but I got so confused that now I don’t even know if this is possible?

I have the following:

Parent class - Bootstrap.php:

class Bootstrap implements Gateway { protected $object = []; protected $data = []; public function init() { $this->config = new Config(); $this->log = new Logging('Logging initialized'); $this->debug = new Debug(); $this->router = new Router($_SERVER['REQUEST_URI']); $this->lang = new Lang( $this->router->get('language'); ); $this->db = new DB( $this->config->get('db_host'), $this->config->get('db_user'), $this->config->get('db_password'), $this->config->get('db_name') ); } public function __set($name, $value) { $this->object[$name] = $value; } public function __get($name) { if (array_key_exists($name, $this->object)) { return $this->object[$name]; } return null; } } 

And the heir class - Router.php:

 class Router extends Bootstrap { protected $url; public function __construct($url) { parent::init(); $this->url = urldecode(ltrim($url, '/')); $languages = $this->config->get('languages'); $routes = $this->config->get('routes'); ... } } 

And the problem is that when calling parent :: init (), the classes are "redeclared." And what to do with it - I do not know. Is it possible to simply take the properties of the call without calling the classes themselves (or rather, their constructors)? Thank you in advance.

  • What does the class mean when it is called parent :: init ()? Theoretically, if the class Router has the init () method, then when calling parent :: init () from the Router, the init () method from the parent Bootstrap class is simply called. - Jean-Claude
  • the "redeclare" method then if inside the Router class you create the init () method that already exists in the parent Bottstrap class. - Jean-Claude
  • This means that class constructors are recursively called if I write parent::init() . So far this is the only way to get properties from the parent class, which I know. - Mistress Denna
  • this is not a recursion, just a call from the parent / base class. - Jean-Claude
  • But we did not understand - what's the problem? - u_mulder

3 answers 3

I am writing an application in PHP, and I need to declare external classes, while writing a flexible connection mechanism. I stopped at the overloading of properties and methods + inheritance, but I got so confused that now I don’t even know if this is possible?

I advise you to see how such things are implemented in modern frameworks (and it would be better to take one of these frameworks as a framework for your PHP application). Your implementation can not be called either flexible or convenient (or working). From what I see, you are trying to implement some kind of build application with dependency injection. Therefore, I also advise you to google Dependency Injection and how to build an application using the dependency injection container.

Also I recommend to understand the basic theory of OOP. Why did you decide that Router is Bootstrap heir? What is the area of ​​responsibility of each of your classes? Why should Router ', which in theory should deal with the routing of incoming requests in your application, also be a collector of your application (and if you inherited Router from Bootstrap , then you have it as Bootstrap ' om)? If you want the Router have access to the behavior that you previously described in Bootstrap , and you do not want to copy pieces of code from one class to another, then inheritance is just one of the ways to reuse code, often often used by developers absolutely out of place (as in your case). If you need access to protected Bootstrap data from Router , this is also no reason to build an inheritance hierarchy between these guys. Are you trying to break encapsulation in this way? Wouldn't it be better to describe the normal public interface of Bootstrap , using which class clients would be able to interrogate it normally and get the information they need to work. If you only need Config from Bootstrap , why not pass it directly to the Router constructor?

At the same time, do not forget that, inheriting Router from Bootstrap , you are firmly tied to a specific implementation of Bootstrap , i.e. Changes to the picker class can disrupt your router.

See the last two lines in the Router class: they will cause an error that the overloaded $ config property was not found in the $ object [] array of the Bootstrap class

An error with you (judging by the code that you showed) will not come out because of this. The application will take you into an infinite loop: in the Bootstrap::init() method you create a new instance of Router , which within its constructor calls the parent init() method, inside which a new Router is created, which within its constructor calls the parent init() method init() inside which a new Router is created, which within its constructor calls the parent init() method, inside which a new Router is created ... You understand that if Router inherited from Bootstrap , then any particular $router will not be the heir of any particular exe plyara $bootstrap ? Those. when you call $bootstrap->init() , then $bootstrap will not be the "dad" of the $router instance that will be created inside its method through the new operator. $bootstrap not a prototype for you to create $router .

Your code will work if you rewrite Bootstrap::init() :

 public function init(Router $router = null) { //... if (!$router) { $router = new Router($_SERVER['REQUEST_URI']); } $this->router = $router; //... } 

And the init call from the Router : parent::init($this) constructor.

Or if the Router constructor is rewritten so that it Bootstrap ; or Config , if you only need it from the collector; or immediately $languages and $routes .

Nakostilyt and start the whole thing can be, but just do not need to, because for good you need to rewrite everything completely.

Want to make an application in PHP? Take literally any framework and cut it on it, reading manuals, and studying the hardware.

Is it possible to simply take the properties of the call without calling the classes themselves (or rather, their constructors)?

You can take the static properties of the class, to access them you do not need to create instances of the class. Your properties are not declared as static, so it is impossible to get them specifically without creating an instance of the class.

In general, it seems that when you wrote this code, you thought with static classes, not classes and their specific instances. And that's bad.

  • Thanks for the clarification, Igor. In general, so far, I do not want to use frameworks, I need to understand them, and here I was advised to write a couple of my applications (similarity to frameworks) in order to understand their component basis. - Mistress Denna
  • Earlier, I had the following construction: the application class (App) is static, it included the getRouter method, which was the creation of the $router = new Router(); object $router = new Router(); . So, routing was called at the right time, without filling the Router class with the extra: App::getRouter->getUrl(); . But then I realized that in order to do this with the other classes, I had to write a get method every time ... it was necessary to create a mechanism that would spin the methods on the fly. But overload works only with non-static methods and properties, so I had to resort to inheriting such perversions - Mistress Denna

In that I need access to the overloaded properties of the Bootstrap class, not a method call with these properties. See the last two lines in the Router class: they will cause an error that the overloaded $ config property was not found in the $ object [] array of the Bootstrap class. - Mistress Denna December 13 at 19:08

not playing: sandbox.onlinephpfunctions.com

    And the problem is that when calling parent :: init (), the classes are "redeclared."

    you have an error here: every time a new Router or Bootstrap object is created, your code will create properties to which the newly created class objects will be assigned by value: Config, Logging, Debug, Router, Lang. If it is assumed that your application must once initiate an object of the Config class and continue to use only this object, then you will have an error and it will not work very economically. On good, instead of new ClassName; make ClassName :: getInstance (); and the function returns a reference to the already created instance (object) and creates an Instance only if the reference does not exist.

    There is no overload in PHP - this is a fact! OOP support in php is implemented with a restriction, there is an implementation option PhpManual Overload . but this is far from the classic understanding of overload. The overloading of methods in the classical sense implies a different implementation in the class of the method method () and method (arg1), and the compiler must understand that in one case one method is called, in another case another method, there is no such reload implementation in php, as well as not possibility to write the implementation of the method for different data types, I would like to be able to do this:

     function method( $arg1 as BootStrap){...} function method( $arg1 as Router){...} 

    but php has no such capabilities, so ... for good php is a functional language - a language of sequentially executed scripts, no need to expect anything more from it.

    • What's the problem with calling the function($arg){ if($arg instanceof BootStrap){...}} method? - SLy_huh
    • mmm, does your question relate to the "reboot" topic? you can just implement anything, you can write a lot of if-else and everything seems to be good. this has nothing to do with the PLO alone - Ravshan Abdulaev
    • Well, citation By rebooting methods in the classical sense means a different implementation in the class of the method method () and method (arg1), and the compiler must understand that in one case one method is called, in another case another method is solved in php. And if this is done differently from your usual method, this does not mean that it is wrong. - SLy_huh
    • in the sense of? where did you read that I assess the situation from the position correctly or incorrectly? I say that this is not and should not expect more from php ... - Ravshan Abdulaev
    • By rebooting methods in the classical sense, they mean a different implementation in the class of the method method () and method (arg1) ; there is no such implementation of reset in php . Yes, there is another implementation that works great. Which will work as it is written in your answer, which, obviously, you do not see the right one. By OOP form of recording generally has little to do. - SLy_huh