Search code examples
php.htaccesspdfurl-rewritingtrailing-slash

Is there a way to automatically add a trailing slash to all URLs except for URLs ending with a file extension (i.e. .pdf, .html, ...)?


Here is my .htaccess file:

RewriteEngine On

RewriteCond %{HTTP_HOST} ^mywebsite\.com [NC]
RewriteRule ^(.*)$ https://www.mywebsite.com/$1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?$1 [L,QSA]

And here is my index.php file:

<?php

$GLOBALS["DEBUG"] = true;

$GLOBALS["DEBUG_MODE"] = "file";
// $GLOBALS["DEBUG_MODE"] = "stdout";
// $GLOBALS["DEBUG_MODE"] = "global";

$GLOBALS["DEBUG_REGEX"] = "^[^b]";
$GLOBALS["ERROR_LOG"]   = true;
// $GLOBALS["DEBUG_SQL"] = true;
// $GLOBALS["PROFILER_SQL"] = true;

// $GLOBALS["DEBUG_CLASS_WALK"]  = true;
// $GLOBALS["DEBUG_CLASS_FOUND"] = true;
// $GLOBALS["DEBUG_CLASS_MATCH"] = "c_";

define("DIR_WEBROOT", realpath(dirname(__FILE__)));

include DIR_WEBROOT . "/xfw/app/startup.php";

d();





// pr(db0()->oQueryFetchArray("SELECT * FROM core_contact"));


pr(r::parseUrl());



if ($a = x_Route::path("^/JSON/(JSON|RAW|DIRECT)/([^/]*)/([^/]*)")) {
    $class  = $a[2];
    $method = $a[3];
    
    $a_params = json_decode(trim(file_get_contents("php://input")), true);
    // $a_params = array_map('sql_escape_string', $a_params);

    try {
        $data = [
            "message" => "ok",
            "data"    => call_user_func_array("$class::$method", [$a_params]),
        ];
    } catch (Exception $e) {
        $data = [
            "message" => "Erreur",
            "data"    => $e->getMessage() . "\n\n" . getExceptionTraceAsString($e),
        ];

        h("err");

        pr(getExceptionTraceAsString($e));
        h("$class::$method");
        pr($a_params);
    }
    
    if ($a[1] == "JSON") {
        echo json_encode($data);
    } elseif ($a[1] == "DIRECT") {
        echo json_encode($data["data"]);
    } else {
        echo $data;
    }

    exit;
}


if ($a = r::path("^/$")) {
    header("Location: /fr/ ");

    exit;
}


if (!r::path("/$")) {
    header("Location: ".ROUTE_PATH."/");

    exit;
}


if ($a = r::path("^/fr/$")) {
    echo View::renderTemplatePublic("public/fr/home.html");

    exit;
}


if ($a = r::path("^/fr/contact/$")) {
    echo View::renderTemplatePublic("public/fr/contact.html", [
        "message" => c_Page::message()
    ]);

    exit;
}


if ($a = r::path("^/fr/(.*)/")) {
    echo View::renderTemplatePublic("public/fr/$a[1].html");

    exit;
}

I want a rule that would add a trailing slash to all URLs except for URLs with an extension (.pdf, .html, ...). Could anyone help me achieve this so that when I have a URL like mywebsite.com/example.pdf it does not redirect me to mywebsite.com/example.pdf/ with a trailing slash at the end?


Solution

  • Looks like

    if (!r::path("/$")) {
        header("Location: ".ROUTE_PATH."/");
    
        exit;
    }
    

    is the part that needs to be modified here. This appears to be using regular expressions; /$ only checks if the value ends with a slash, and the condition is negated, to redirect when it doesn’t.

    Instead of trying to come up with a more complex regular expression, I’d probably use pathinfo here. Try and replace that section with

    if (!r::path("/$") && pathinfo(ROUTE_PATH, PATHINFO_EXTENSION) === '') {
      header("Location: ".ROUTE_PATH."/");
    
      exit;
    }
    

    The PATHINFO_EXTENSION flag makes pathinfo return the extension only, and if the path didn’t actually have any, it will just return an empty string.