Hi Midori, On 31 July 2016 at 10:00, Midori Koçak <mtko...@gmail.com> wrote: > even though we have classes included in our program, the > only way to create an object from a class, is to instantiate it in > unstructured code.
That is the true nature of reality. All PHP programs start in procedural code, and then require some bootstrapping before we can enter the lovely world of OO code. > Most of the programs we write, end up to have some piece of > spaghetti code somewhere. To prevent this, one should write a god object and run once but classes are not and should not be code blocks wrapped around “class” keyword. All applications start in 'procedural' land. And all applications require some procedural code to setup the OO environment. You don't need to create a god object. What you need to do is be able to bootstrap the OO environment nicely from procedural code. There is no possible way to escape this. If you try to, what you find is that you're hiding the 'yucky' procedural stuff away somewhere. It will still be present, just not in as obvious a location. > Instead of instantiating objects on the fly, here I propose a structured > definition of an object using this syntax: I think what you've done is moved the procedural code into the object instantiation block. It is still there as procedural code, it just isn't as obvious. So it doesn't really solve the "problem" of PHP programs starting of in procedural code, it just makes it harder to see, which bits are procedural and which bits are OO. > Consider this piece of code: > $app->get('/hello/{name}', function (Request $request, Response $response) { > $name = $request->getAttribute('name'); > $response->getBody()->write("Hello, $name"); > > return $response; > }); I think quite a few frameworks show examples that look cool, but aren't necessarily the best practice. I've been using the Auryn DIC (https://github.com/rdlowrey/auryn) to do this bootstrapping required before we can use OO code. For the example code you showed, I would refactor it to use Auryn with something like this: // In an appropriate functions file function helloName(Request $request, Response $response) { $name = $request->getAttribute('name'); $response->getBody()->write("Hello, $name"); return $response; } //This is a procedural function that returns an object. i.e. it forms the boundary between the OO code in our application, and the procedural code. function createRoutes() { // We could read the routes from a data file, or even from annotations // Both of those would be just as procedural as this is. $getRoutes = [ '/hello/{name}' => 'helloName' ]; return new Routes($getRoutes) } class Application extends App { public function __construct(Routes $routes) { foreach ($routes->listGetRoutes() as $pattern => $callable) { $this->get($pattern, $callable); } } public function dispatch(Request $request) { // Do the dispatching of the request against the routes. } } // In bootstrap.php $injector->delegate('Routes', 'createRoutes'); // Another function to create a request object, from the $_REQUEST and other global vars. $injector->delegate('Request', 'createRequest'); $app = $injector->execute(['Application', 'dispatch']); The 'delegate' method is the bit where we creating the link between the lovely OO code, and the 'yucky' procedural code. The delegate method tells the injector, "whenever an some code we're running requires an object of types 'Route' call this function to create it". When the injector creates the Application object, it will see that the constructor needs a Routes object, and will call the delegate function to create it. Although we still have some lines of procedural code, it is reduced to the bare minimum, and none of the procedural code in the 'createRoutes' function needs to be cluttering up the bootstrap file. cheers Dan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php