Custom Herd/Valet Drivers for Resolving URL Paths in Vanilla PHP Projects

I encountered an issue where paths couldn’t be resolved properly in my vanilla PHP projects using Laravel Herd. The system would only recognize index.php files. For example, when accessing http://x.test/case-studies, it wouldn’t resolve to http://x.test/case-studies.php, even though that was the expected behavior.

To address this, I implemented a custom driver that fixed the issue, allowing the system to correctly resolve paths without requiring the .php extension. However, now when accessing http://x.test/services/, it should automatically route to http://x.test/services/index.php. Instead, I’m encountering a 404 error.

Error 1

2025/03/05 10:45:18 [error] 90478#1248117: *34 “Users/jack-brogan/Herd/x/html/services//index.html” is not found (2: No such file or directory), client: 127.0.0.1, server: , request: “GET /services/ HTTP/1.1”, upstream: “fastcgi://unix:/Users/jack-brogan/Library/Application Support/Herd/herd.sock”, host: “x.test”, referrer: “

I’m unsure as to why its being resolved with two forward slashes at the end of Users/jack-brogan/Herd/x/html/services// and also why its looking for the index.html and not index.php.

Error 2

2025/03/05 10:45:18 [error] 90478#1248117: *34 FastCGI sent in stderr: “PHP message: Servers is truePHP message: Current site path: /Users/jack-brogan/Herd/x/htmlPHP message: Current URI: /favicon.icoPHP message: Raw URI: /favicon.icoPHP message: sitepath 1: /Users/jack-brogan/Herd/x/html/favicon.ico.phpPHP message: sitepath 2: /Users/jack-brogan/Herd/x/html/favicon.ico/index.php” while reading response header from upstream, client: 127.0.0.1, server: , request: “GET /favicon.ico HTTP/1.1”, upstream: “fastcgi://unix:/Users/jack-brogan/Library/Application Support/Herd/herd.sock:”, host: “x.test”, referrer: “http://x.test/services/”

Driver

// namespace ValetDrivers;

use ValetDriversValetDriver;

class LocalValetDriver extends ValetDriver
{
    /**
     * Determine if the driver serves the request.
     */
    public function serves(string $sitePath, string $siteName, string $uri): bool
    {
        if (file_exists($sitePath . '/index.php')) {
            return true;
        }
        return true;
        // return file_exists($sitePath . $uri . '.php');
    }

    /**
     * Resolve the incoming request to a valid PHP script.
     */
    public function isStaticFile($sitePath, $siteName, $uri)
    {
        if (file_exists($staticFilePath = $sitePath . $uri)) {
            return $staticFilePath;
        }

        return false;
    }

    /**
     * Directs Nginx to the correct file.
     */
    public function frontControllerPath(string $sitePath, string $siteName, string $uri): string
    {

        error_log("Current site path: " . $sitePath);
        error_log("Current URI: " . $uri);
        error_log("Raw URI: " . $_SERVER['REQUEST_URI']);
        
        // Check if request is for a PHP file
        if (file_exists($sitePath . $uri . '.php')) {
            return $sitePath . $uri . '.php';
        }

        // Default to index.php if no other match is found
        return $sitePath . $uri . '/index.php'; // Ensure correct path to index.php
    }
}

It seems to be correctly going through the serves method but the issue is with the frontControllerPath.