NotionCommotion Posted June 14, 2018 Share Posted June 14, 2018 Doing the following is concise and allows a common constructor to be inherited, but I think I am doing it too much. Should it ever be done? Should an object never be included in the associated array data? Obviously, this isn't applicable for form data, but I've used this same approach where one class creates some objects and injects them in another class. How does one get around constructors needing different signatures? public function __construct(array $formData, \PDO $pdo) { $this->validate($properties); foreach($formData as $key=>$value) { $this->$key=$value; } $this->pdo=$pdo; } Quote Link to comment Share on other sites More sharing options...
requinix Posted June 14, 2018 Share Posted June 14, 2018 Ever? Sure. Include an object? I don't see a reason why one should "never" do that. It's not about the type of value but about what it represents (and passing a database thing is very normal). Constructor signatures? You override them in child classes with whatever signature you want. Constructors aren't like normal methods. Quote Link to comment Share on other sites More sharing options...
gizmola Posted June 14, 2018 Share Posted June 14, 2018 I think you have to be careful with the terminology you are employing. An argument is by definition "injecting" variables into a function or method. In general the important distinction is how an argument is passed. Passed by Value: Changes to the argument don't change the original variable Passed by Reference: Changes to the argument change the original variable A fundamental change in PHP from version 4 to 5 was that all objects get passed by reference. In PHP 4 you frequently had to employ the 'reference' operator. So when the word "injection" gets used, it's in reference to "Dependency Injection". Obviously that is large topic, but it's predicated on the idea that you will inject objects that a class might depend on via the constructor. Since code in the class will reference this dependency, it should be a parameter and not passed in via an array. Now in terms of your specific example having to do with form data, it is hard for me to see the value of what you are doing when form data exists within PHP in a super global ($_POST). If you look at most of the frameworks, all of which have some support or solution for form building, validation and error handling, doing what you are doing is an anti-pattern. What you see more of is the use of a Request object that gets the raw form data from the request, then applies validations and updating of model objects as required. Just mapping an array of variables into an object seems of limited value. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted June 14, 2018 Author Share Posted June 14, 2018 Thanks guys, I either never knew or knew once and forgot that constructors do not need the same signature. The implications are huge, and passing objects in an array just to get around PHP complaining was difficult to read and troubleshoot. @gizmola regarding request objects and anti-patterns, showing the $_POST super global was just an example, and I actually do something like the following. I do feel passing data in an array to the constructor is okay as one might be creating an entity from form data or from values obtained from the database. The part I didn't like was sneaking a couple of objects in the array who's purpose was DI, and now know that I don't need to do so. Does it still look like I am doing an anti-pattern? My old way of doing this is as follows: $app->get('/sources', function (Request $request, Response $response) { $rs=$this->get('SourcesIndex')->read($request->getQueryParams()); //returns [data, status code] return $response->withJson($rs[0],$rs[1]); }); $app->post('/charts/{chartId:[0-9]+}', function (Request $request, Response $response, $args) { $rs=$this->get('ChartFactory')->getByID($args['chartId'])->addPoint($request->getParsedBody()); //returns [data, status code] return $response->withJson($rs[0],$rs[1]); }); My new way of doing this is as follows: $app->get('/sources', function (Request $request, Response $response) { return $this->sourceResponder->detail($response, $this->sourceService->read($request->getQueryParams())); }); $app->post('/charts/{chartId:[0-9]+}', function (Request $request, Response $response, $args) { $factory=$this->chartFactory->init($args['chartId']); $rs=$factory->getService()->addPoint($request->getParsedBody()); //returns an object return $factory->getResponder()->update($response, $rs); }); Quote Link to comment Share on other sites More sharing options...
gizmola Posted June 15, 2018 Share Posted June 15, 2018 I'm glad you got the main point of my comments, being, don't try and hide dependencies inside an array you pass to the constructor. Your examples look similar to the type of code often associate with micro frameworks like Lumen, slim or silex. Looks fairly kosher to me given the limited context. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.