Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:94765 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 66223 invoked from network); 31 Jul 2016 14:37:52 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 31 Jul 2016 14:37:52 -0000 Authentication-Results: pb1.pair.com smtp.mail=danack@basereality.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=danack@basereality.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain basereality.com from 209.85.161.179 cause and error) X-PHP-List-Original-Sender: danack@basereality.com X-Host-Fingerprint: 209.85.161.179 mail-yw0-f179.google.com Received: from [209.85.161.179] ([209.85.161.179:35672] helo=mail-yw0-f179.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id E0/19-22978-F3D0E975 for ; Sun, 31 Jul 2016 10:37:51 -0400 Received: by mail-yw0-f179.google.com with SMTP id j12so152414667ywb.2 for ; Sun, 31 Jul 2016 07:37:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=basereality-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=FHuddw2BZ5t8x5kx7rxI8hOhdYxK3EUe8ZW67asMZRo=; b=t6gJj7OxmyucMF8ZhBVaktuDZFFl0qYgxxNbBe9HRWN9mLgkE2XkjPCqp/dXiTod0J /6zTd/75prwvMsWbqHU02+bjwYvMxDiS9yVP7QyR1uN6lI+/w4bBF5PwYXnctse0vHEF HiW4uhDUhef3VBtvchfwpNW1/xciQXKD8VA9ceaSFPYwn3S/H78sXMaRMKBZrwkosnOK iKPPqWpMzNIv5fmMiKh7fPMvdBxfLQDHO0uJeOiwyd9MV9c37rg7AVBWPojKrzBr6Sg3 8qyyYvjtN00QZYL9Sby/+BBf1K9bvlMd/1yx7ZRegjqQn56AtDaf3W9NsYqzZM0Gvu1L Tk9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=FHuddw2BZ5t8x5kx7rxI8hOhdYxK3EUe8ZW67asMZRo=; b=CtfI6SAzqB3Wy0TfEad0GCYqgGIIfDErzMMoScH0DTpuKhLmyUMl0H7JTvstvLXWSH MU9bz3oUutMrllaGcaMTcDAlF5EDi3zYBQeEq0jT1/DArJ4JX2d99KlFcaRy1HMNojDK zw0gulaGS4uWRLegmK/DY4tlMJ+gAQO0jQZasioH9kIoJt2fmR+8mvZCWL3rNli8Nhou ZCpxV+tj/heHrkTfsyqPldxc6xyiV5Art+SRmZ2rIMxa8SS0caYb9NnPhXYqu/rDi+80 7DVDtvlRFQGMZ5suiyhB5Pt346Sx56JlpUhlQcJOj+w1Au74IyuRqiOpapTAGxzyzO6x KY6g== X-Gm-Message-State: AEkoousKZpPZLqJuyGps0fSWGqpJyINRzslNjMujfxaNR39KQ4K/8hgOaqBrghOdcp4uNVrcBSxTE6CBrWLCMA== X-Received: by 10.13.200.5 with SMTP id k5mr41631881ywd.23.1469975868579; Sun, 31 Jul 2016 07:37:48 -0700 (PDT) MIME-Version: 1.0 Received: by 10.37.230.83 with HTTP; Sun, 31 Jul 2016 07:37:47 -0700 (PDT) X-Originating-IP: [2.99.229.95] In-Reply-To: References: Date: Sun, 31 Jul 2016 15:37:47 +0100 Message-ID: To: =?UTF-8?Q?Midori_Ko=C3=A7ak?= Cc: PHP Internals Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] Structured Object Notation From: danack@basereality.com (Dan Ackroyd) Hi Midori, On 31 July 2016 at 10:00, Midori Ko=C3=A7ak 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 =E2=80=9Cclass=E2=80=9D 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 =3D $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 =3D $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 =3D [ '/hello/{name}' =3D> 'helloName' ]; return new Routes($getRoutes) } class Application extends App { public function __construct(Routes $routes) { foreach ($routes->listGetRoutes() as $pattern =3D> $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 =3D $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