skip to Main Content

I’m trying to create a custom Laravel Valet driver for a Symfony project as I need to handle asset files in a specific way. I’ve created the following ProjectValetDriver class in /.config/valet/Drivers

<?php

namespace ValetDriversCustom;

use ValetDriversLaravelValetDriver;

class ProjectValetDriver extends LaravelValetDriver
{
    public function serves(string $sitePath, string $siteName, string $uri): bool
    {
        return $siteName === '[project-name]';
    }

    public function isStaticFile(string $sitePath, string $siteName, string $uri): string|false
    {
        if (file_exists($staticFilePath = $sitePath.'/public/'.$uri)) {
            return $staticFilePath;
        }

        return false;
    }

    public function frontControllerPath(string $sitePath, string $siteName, string $uri): string
    {
        return $sitePath.'/public/index.php';
    }
}

The custom driver is correctly registered, however when I visit the site I get the following error;

Warning: require_once(./cli/includes/require-drivers.php): Failed to open stream: No such file or directory in /Users/[user]/.composer/vendor/laravel/valet/server.php on line 3

The public/index.php file is called correctly as well, but that file calling require_once dirname(__DIR__) . '/vendor/autoload_runtime.php'; seems to break everything. Without the custom driver the site loads fine. Any idea what’s going on?

2

Answers


  1. Chosen as BEST ANSWER

    The issue was ultimately solved by extending ValetDriversSpecificSymfonyValetDriver instead of LaravelValetDriver. In doing so, I can also ommit the frontControllerPath method from the custom driver.


  2. I’ve ran into this issue recently as well when trying to run a Symfony application with Laravel Herd.

    The issue is that Symfony 5.3+ introduced a new runtime that detects the front controller to begin execution. The front controller should be the public/index.php file, but since you are running this through Laravel Valet, the front controller is Valet’s server.php, which causes the issues you are facing.

    The solution is to override a few of the $_SERVER globals to change the front controller and allow Symfony’s runtime to take over.

    <?php
    
    namespace ValetDriversCustom;
    
    use ValetDriversLaravelValetDriver;
    
    class ProjectValetDriver extends LaravelValetDriver
    {
        public function serves(string $sitePath, string $siteName, string $uri): bool
        {
            return $siteName === '[project-name]';
        }
    
        public function isStaticFile(string $sitePath, string $siteName, string $uri): string|false
        {
            if (file_exists($staticFilePath = $sitePath.'/public/'.$uri)) {
                return $staticFilePath;
            }
    
            return false;
        }
    
        public function frontControllerPath($sitePath, $siteName, $uri)
        {
            $_SERVER['SCRIPT_FILENAME'] = $sitePath.'/public/index.php';
            $_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST'];
            $_SERVER['SCRIPT_NAME'] = '/index.php';
    
            return $sitePath.'/public/index.php';
        }
    }
    

    Lastly, run valet restart to reload your driver.

    Now, when Valet serves your Symfony project, it should properly delegate control to your app’s public/index.php, and the application should run as expected.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search