Lowercase URL-s for accessing web applications are important for usage statistics and web metrics. They are good for communication styling and purity and are highly recommended by web experts.
If you do not have access to the Apache httpd.conf file (e.g. under shared hosting) or would not like to mess with or burden your .htaccess file, you can apply redirecting within the routing rules of your PHP/Laravel application code.
The idea here is to:
- generally keep your routes lowecased, and
- capture and redirect requests not captured by the regular rules because they have uppercase characters, and then
- redirect to a lowercase URL as a fallback route.
Supposed you keep your routes in the /routes/web.php file like this:
Auth::routes();
Route::get('/', 'HomeController@index')->name('root');
Route::get('/home', 'HomeController@index')->name('home');
Route::get('products', 'ProductsController@index')->name('products');
Route::get('product/{id}', 'ProductsController@details')->name('productDetails');
Route::get('product_edit/{id}', 'ProductsController@edit_get')->name('getEditProduct');
Route::post('product_edit', 'ProductsController@edit_post')->name('postEditProduct');
// and so on ...
// and so on ...
Put following example code AFTER all your regular routes:
Route::any('{req}', function($req) {
$uri = $_SERVER['REQUEST_URI'];
$path = strtok($uri, '?');
$query = '';
if(strpos($uri, '?') !== false){
$after = substr($uri, strpos($uri, '?') + 1);
if($after !== false){
$query = $after;
}
}
if(strtolower($path) !== $path){
$redirectUri = strtolower($path);
if(strlen($query) > 0)
$redirectUri .= '?' . $query;
return redirect(trim($redirectUri, '/'));
}
return response()->view('shared.error_404', [], 404);
})->where('req', '^.*');
The uppercase characters containing requests will be redirected to the equivalent lowercase URL.
Note that static file download requests will remain untouched (keeping their case sensitivity) if the request URL is correct.
Note that if a regular route has dynamic parts, like when using string ID-s for handling resources .../{id}..., and only they have capital characters, they will not cause redirection as the request will be captured by the regular route. You would normally return '404 Not Found' in that regular route processing, if the ID is not found, and the fallback route will not be invoked.
Note that the 'query string' parameters (after the '?' sign) are not switched to lowercase with the redirects and preserve their case sensibility.
Keep clean code!