DEV Community

Cover image for Artisan server for Lumen
Guilherme Nascimento
Guilherme Nascimento

Posted on • Updated on

Artisan server for Lumen

I came across many suggestions for implementing the php artisan serve command in Lumen, however sometimes in development, especially with the popularization of microservices, that is, there may be situations where different applications need to communicate, usually in a development environment using only ports as access.

So starting application by application with php -S host:port -t public can be a little tricky or just annoying.

Fortunately if we have the value of APP_URL in env we can facilitate part of the process.

First create a file called ServeCommand.php in the ./app/Console/Commands/ folder, after edit app/Console/Kernel.php and put ServerCommand, like this:

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Laravel\Lumen\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    protected $commands = [
        Commands\ServeCommand::class,
    ];
Enter fullscreen mode Exit fullscreen mode

The class Illuminate\Console\Command has a protected method called getOptions(), with it we can define default values for parameters in a command, or also inform if a parameter is optional (Symfony\Component\Console\Input\InputOption::VALUE_OPTIONAL) or required (Symfony\Component\Console\Input\InputArgument::REQUIRED).

More details in: https://symfony.com/doc/current/console/input.html

The proposal is to use as an option, that is, allow the user to change the host or port if desired when entering a command, or else use the value of APP_URL. To get the default host and port values I used parse_url, example usage:

protected function getOptions()
{
    $url = env('APP_URL');

    return [
        [
            'host', null, InputOption::VALUE_OPTIONAL, 'The host address to serve the application on.', parse_url($url, PHP_URL_HOST)
        ], [
            'port', null, InputOption::VALUE_OPTIONAL, 'The port to serve the application on.', parse_url($url, PHP_URL_PORT)
        ],
    ];
}
Enter fullscreen mode Exit fullscreen mode

to obtain the host and port (defined via command line or .env) use:

$host = $this->input->getOption('host');

$port = $this->input->getOption('port');
Enter fullscreen mode Exit fullscreen mode

However there is still a detail, it is possible for the user to start the artisan serve from a different folder level so we set the -t (php built in webserver) to start the public directory. To get the project directory use:

$base = $this->laravel->basePath();
Enter fullscreen mode Exit fullscreen mode

The command call should look like this:

passthru('"' . PHP_BINARY . '"' . " -S {$host}:{$port} -t \"{$base}/public\"");
Enter fullscreen mode Exit fullscreen mode

Source on gist: https://gist.github.com/brcontainer/44f47d35f47cd4e33f14023f8521bea1

Full source code:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;

class ServeCommand extends Command {

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'serve';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = "Serve the application on the PHP development server";

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        $host = $this->input->getOption('host');

        $port = $this->input->getOption('port');

        $base = $this->laravel->basePath();

        $this->info("Lumen development server started on http://{$host}:{$port}/");

        passthru('"' . PHP_BINARY . '"' . " -S {$host}:{$port} -t \"{$base}/public\"");
    }

    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        $url = env('APP_URL');

        return [
            [
                'host', null, InputOption::VALUE_OPTIONAL, 'The host address to serve the application on.', parse_url($url, PHP_URL_HOST)
            ], [
                'port', null, InputOption::VALUE_OPTIONAL, 'The port to serve the application on.', parse_url($url, PHP_URL_PORT)
            ],
        ];
    }

}

Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
bramasto17 profile image
Bramasto Wibisono • Edited

for me I just create a .sh file called serve.sh, inside the file is php -S host:port -t public, then to serve it just run sh serve.sh

Collapse
 
brcontainer profile image
Guilherme Nascimento

Thanks for commenting. Believe me, I use it too, but in projects with my own framework. I created a server.bat and a server.sh, I also find it more practical.