I want to disable non-pretty urls and let work just pretty urls on m page.
For ex.:
myexample.sk/all-posts.php – want to disable
myexample.sk/all-posts – want to allow
But actually I want to keep files inside /_process/ folder to works, bcs all data on web are processed via files inside _process folder.
I created router.php
<?php
// Include the Router class file from the src folder
require_once $_SERVER['DOCUMENT_ROOT'] . '/_process/router.php';
// Initialize the router
$router = new Router();
$router->add('GET', '/all-posts', function() {
require 'all-posts.php';
});
// Dispatch the current request URL
$router->matchRoute($_SERVER['REQUEST_URI']);
and this is my router class in the same _process/router.php:
<?php
declare(strict_types=1);
class Router {
private array $routes = [];
// Method to add routes with HTTP method, path, and callback (function or file)
public function add(string $method, string $path, callable $callback): void {
$path = $this->normalizePath($path);
// Convert dynamic segments to a regular expression (e.g., {doctor_name} becomes a regex group)
$pathRegex = preg_replace('/{([a-zA-Z0-9_]+)}/', '(?P<$1>[a-zA-Z0-9_-]+)', $path);
$this->routes[] = [
'path' => $pathRegex,
'method' => strtoupper($method),
'callback' => $callback,
];
}
// Normalize the path (removes extra slashes and ensures consistency)
private function normalizePath(string $path): string {
if ($path === '/') {
return '/';
}
$path = trim($path, '/');
return "/{$path}";
}
// Method to process the incoming request path
public function matchRoute(string $requestedPath): void {
$requestedPath = $this->normalizePath($requestedPath);
$method = strtoupper($_SERVER['REQUEST_METHOD']);
foreach ($this->routes as $route) {
// Check if method matches
if ($route['method'] === $method) {
// Check if the route pattern matches the requested path using regex
if (preg_match("#^{$route['path']}$#", $requestedPath, $matches)) {
// Extract any named parameters from the matches
$params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
// Call the callback and pass the parameters
call_user_func($route['callback'], $params);
return;
}
}
}
// If no matching route is found, return a 404 response
http_response_code(404);
echo "404 Not Found";
}
}
I tried for ex. this in htaccess but this option is working. And actually it even start to reoute my example.sk/index.php to example.sk/index.html from hosting provider.
# Zakázať priamy prístup k PHP súborom v tomto priečinku
<Files *.php>
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Files>
This is my htaccess file:
# Zapnutie RewriteEngine
RewriteEngine On
# Presmerovanie na 404 stranku, v pripade neexistujucej URL
ErrorDocument 404 /404.php
# Presmerovanie z www na non-www
RewriteCond %{HTTP_HOST} ^www.example.sk [NC]
RewriteRule ^(.*)$ http://example.sk/$1 [L,R=301,NC]
# Zabezpecenie HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Presmerovanie všetkých požiadaviek na router.php (okrem existujúcich súborov a priečinkov)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /router.php [L,QSA]
# Zabránenie zobrazeniu adresárov
Options -Indexes
# Zakázať priamy prístup k PHP súborom v tomto priečinku
<Files *.php>
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Files>
# Zabránenie prístupu k súborom .htaccess a .htpasswd
<Files ".ht*">
Require all denied
</Files>
# Komprimácia Obsahu
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
# Nastavenie Expire Headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
</IfModule>
Thanks for help.
2
Answers
i found this solution:
I added these parts:
Instead of:
To ensure pretty URLs work for your main routes, but still allow access to the files in the /process/ folder, you’ll need to adjust your .htaccess rules and router configuration. Here’s how you can achieve it:
1. Updating .htaccess
Your .htaccess is mostly correct, but we can tweak it to ensure that the files inside the _process folder remain accessible while routing everything else through router.php.
Key Changes:
1.Process Folder Exclusion: The line RewriteCond %{REQUEST_URI} ^/_process/ [NC] ensures that all requests to files inside the _process folder are allowed to bypass the router, so your scripts there work as expected.
2.Router Rule: The rest of the requests are routed to router.php if they aren’t a physical file or directory.
Your Router class seems fine for handling pretty URLs like /all-posts. Just ensure that all routes you want to support are properly added. For example:
3. Troubleshooting Hosting Rewrite Issues
If the .htaccess is causing issues like routing index.php to index.html, ensure that your hosting provider does not have additional rewrites or index priority settings that might interfere. You may want to check the hosting settings for "default document" or index priorities and ensure that .php files take precedence over .html.
This setup should enforce pretty URLs while allowing your scripts inside _process to work as expected.
hope this works 🙂