How to properly extend the Laravel 5.7 Router?












1















This question has been discussed many times here, here or here but no elegant solutions were mentioned.



One particular use case would be to allow to load and route old PHP files with Laravel. I am for instance migrating a very old (> 20 years) code base into Laravel and most pages are regular PHP files that I would like to render into a particular Blade template.



To do this it would be elegant to do:



Router::php('/some/route/{id}', base_path('legacy/some/page.php'));


Behind the scenes all I need is to pass the captured variables to the PHP page, evaluate and grab the content of it and eventually return a view instance.



As Laravel claims itself to be a SOLID framework, I thought extending the Router is trivial so I wrote this:



namespace AppServices;



class Router extends IlluminateRoutingRouter
{
public function php($uri, $filename, $template='default') {
...
return view(...
}
}


Then I tried to extend my Http Kernel with this:



namespace AppHttp;

use IlluminateContractsFoundationApplication;
use IlluminateFoundationHttpKernel as HttpKernel;

use AppServicesRouter;

class Kernel extends HttpKernel
{
public function __construct(Application $app, Router $router) {
return parent::__construct($app, $router);
}
}


But it is not working it seems the Application is building the Kernel with the wrong dependency. In Application@registerCoreContainerAliases I see the core alias router is hard coded and since this method is called in the Application's constructor, I am doomed.



The only solution that remains is to override the router before loading the Kernel as follow:



$app = new Application($_ENV['APP_BASE_PATH'] ?? dirname(__DIR__));

$app->singleton('router', AppServicesRouter::class);

$app->singleton(
IlluminateContractsHttpKernel::class,
AppHttpKernel::class
);


But this looks a bit ugly. Is there a better way to achieve this?










share|improve this question



























    1















    This question has been discussed many times here, here or here but no elegant solutions were mentioned.



    One particular use case would be to allow to load and route old PHP files with Laravel. I am for instance migrating a very old (> 20 years) code base into Laravel and most pages are regular PHP files that I would like to render into a particular Blade template.



    To do this it would be elegant to do:



    Router::php('/some/route/{id}', base_path('legacy/some/page.php'));


    Behind the scenes all I need is to pass the captured variables to the PHP page, evaluate and grab the content of it and eventually return a view instance.



    As Laravel claims itself to be a SOLID framework, I thought extending the Router is trivial so I wrote this:



    namespace AppServices;



    class Router extends IlluminateRoutingRouter
    {
    public function php($uri, $filename, $template='default') {
    ...
    return view(...
    }
    }


    Then I tried to extend my Http Kernel with this:



    namespace AppHttp;

    use IlluminateContractsFoundationApplication;
    use IlluminateFoundationHttpKernel as HttpKernel;

    use AppServicesRouter;

    class Kernel extends HttpKernel
    {
    public function __construct(Application $app, Router $router) {
    return parent::__construct($app, $router);
    }
    }


    But it is not working it seems the Application is building the Kernel with the wrong dependency. In Application@registerCoreContainerAliases I see the core alias router is hard coded and since this method is called in the Application's constructor, I am doomed.



    The only solution that remains is to override the router before loading the Kernel as follow:



    $app = new Application($_ENV['APP_BASE_PATH'] ?? dirname(__DIR__));

    $app->singleton('router', AppServicesRouter::class);

    $app->singleton(
    IlluminateContractsHttpKernel::class,
    AppHttpKernel::class
    );


    But this looks a bit ugly. Is there a better way to achieve this?










    share|improve this question

























      1












      1








      1








      This question has been discussed many times here, here or here but no elegant solutions were mentioned.



      One particular use case would be to allow to load and route old PHP files with Laravel. I am for instance migrating a very old (> 20 years) code base into Laravel and most pages are regular PHP files that I would like to render into a particular Blade template.



      To do this it would be elegant to do:



      Router::php('/some/route/{id}', base_path('legacy/some/page.php'));


      Behind the scenes all I need is to pass the captured variables to the PHP page, evaluate and grab the content of it and eventually return a view instance.



      As Laravel claims itself to be a SOLID framework, I thought extending the Router is trivial so I wrote this:



      namespace AppServices;



      class Router extends IlluminateRoutingRouter
      {
      public function php($uri, $filename, $template='default') {
      ...
      return view(...
      }
      }


      Then I tried to extend my Http Kernel with this:



      namespace AppHttp;

      use IlluminateContractsFoundationApplication;
      use IlluminateFoundationHttpKernel as HttpKernel;

      use AppServicesRouter;

      class Kernel extends HttpKernel
      {
      public function __construct(Application $app, Router $router) {
      return parent::__construct($app, $router);
      }
      }


      But it is not working it seems the Application is building the Kernel with the wrong dependency. In Application@registerCoreContainerAliases I see the core alias router is hard coded and since this method is called in the Application's constructor, I am doomed.



      The only solution that remains is to override the router before loading the Kernel as follow:



      $app = new Application($_ENV['APP_BASE_PATH'] ?? dirname(__DIR__));

      $app->singleton('router', AppServicesRouter::class);

      $app->singleton(
      IlluminateContractsHttpKernel::class,
      AppHttpKernel::class
      );


      But this looks a bit ugly. Is there a better way to achieve this?










      share|improve this question














      This question has been discussed many times here, here or here but no elegant solutions were mentioned.



      One particular use case would be to allow to load and route old PHP files with Laravel. I am for instance migrating a very old (> 20 years) code base into Laravel and most pages are regular PHP files that I would like to render into a particular Blade template.



      To do this it would be elegant to do:



      Router::php('/some/route/{id}', base_path('legacy/some/page.php'));


      Behind the scenes all I need is to pass the captured variables to the PHP page, evaluate and grab the content of it and eventually return a view instance.



      As Laravel claims itself to be a SOLID framework, I thought extending the Router is trivial so I wrote this:



      namespace AppServices;



      class Router extends IlluminateRoutingRouter
      {
      public function php($uri, $filename, $template='default') {
      ...
      return view(...
      }
      }


      Then I tried to extend my Http Kernel with this:



      namespace AppHttp;

      use IlluminateContractsFoundationApplication;
      use IlluminateFoundationHttpKernel as HttpKernel;

      use AppServicesRouter;

      class Kernel extends HttpKernel
      {
      public function __construct(Application $app, Router $router) {
      return parent::__construct($app, $router);
      }
      }


      But it is not working it seems the Application is building the Kernel with the wrong dependency. In Application@registerCoreContainerAliases I see the core alias router is hard coded and since this method is called in the Application's constructor, I am doomed.



      The only solution that remains is to override the router before loading the Kernel as follow:



      $app = new Application($_ENV['APP_BASE_PATH'] ?? dirname(__DIR__));

      $app->singleton('router', AppServicesRouter::class);

      $app->singleton(
      IlluminateContractsHttpKernel::class,
      AppHttpKernel::class
      );


      But this looks a bit ugly. Is there a better way to achieve this?







      php laravel






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 31 '18 at 20:54









      nowoxnowox

      6,344933102




      6,344933102
























          1 Answer
          1






          active

          oldest

          votes


















          1














          Since the Router class is macroable, you may be able to do something like:



          Router::macro('php', function ($uri, $filepath) {
          return $this->addRoute(['GET', 'POST', etc...], $uri, function () use ($filepath) {
          // here you might use the blade compiler to render the raw php along with any variables.
          //
          // See: https://laravel.com/api/5.7/Illuminate/View/Compilers/Concerns/CompilesRawPhp.html
          //

          $contents = file_get_contents($filepath);

          // return compiled $contents...
          });
          });





          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53991345%2fhow-to-properly-extend-the-laravel-5-7-router%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            Since the Router class is macroable, you may be able to do something like:



            Router::macro('php', function ($uri, $filepath) {
            return $this->addRoute(['GET', 'POST', etc...], $uri, function () use ($filepath) {
            // here you might use the blade compiler to render the raw php along with any variables.
            //
            // See: https://laravel.com/api/5.7/Illuminate/View/Compilers/Concerns/CompilesRawPhp.html
            //

            $contents = file_get_contents($filepath);

            // return compiled $contents...
            });
            });





            share|improve this answer






























              1














              Since the Router class is macroable, you may be able to do something like:



              Router::macro('php', function ($uri, $filepath) {
              return $this->addRoute(['GET', 'POST', etc...], $uri, function () use ($filepath) {
              // here you might use the blade compiler to render the raw php along with any variables.
              //
              // See: https://laravel.com/api/5.7/Illuminate/View/Compilers/Concerns/CompilesRawPhp.html
              //

              $contents = file_get_contents($filepath);

              // return compiled $contents...
              });
              });





              share|improve this answer




























                1












                1








                1







                Since the Router class is macroable, you may be able to do something like:



                Router::macro('php', function ($uri, $filepath) {
                return $this->addRoute(['GET', 'POST', etc...], $uri, function () use ($filepath) {
                // here you might use the blade compiler to render the raw php along with any variables.
                //
                // See: https://laravel.com/api/5.7/Illuminate/View/Compilers/Concerns/CompilesRawPhp.html
                //

                $contents = file_get_contents($filepath);

                // return compiled $contents...
                });
                });





                share|improve this answer















                Since the Router class is macroable, you may be able to do something like:



                Router::macro('php', function ($uri, $filepath) {
                return $this->addRoute(['GET', 'POST', etc...], $uri, function () use ($filepath) {
                // here you might use the blade compiler to render the raw php along with any variables.
                //
                // See: https://laravel.com/api/5.7/Illuminate/View/Compilers/Concerns/CompilesRawPhp.html
                //

                $contents = file_get_contents($filepath);

                // return compiled $contents...
                });
                });






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 1 at 4:09

























                answered Jan 1 at 3:46









                DigitalDrifterDigitalDrifter

                8,3912624




                8,3912624
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53991345%2fhow-to-properly-extend-the-laravel-5-7-router%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Monofisismo

                    Angular Downloading a file using contenturl with Basic Authentication

                    Olmecas