skip to Main Content

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


  1. Chosen as BEST ANSWER

    i found this solution:

    # Enable RewriteEngine
    RewriteEngine On
    
    # Custom 404 page
    ErrorDocument 404 /404.php
    
    # Redirect www to non-www
    RewriteCond %{HTTP_HOST} ^www.example.sk [NC]
    RewriteRule ^(.*)$ https://example.sk/$1 [L,R=301]
    
    # Ensure HTTPS for all requests
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    
    # Disable directory browsing
    Options -Indexes
    
    # Prevent direct access to PHP files in _process folder
    RewriteRule ^_process /.*.php$ - [F,L]
    
    # Route all requests to router.php (except existing files and directories)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /router.php [L,QSA]
    
    # Restrict direct access to PHP files from the browser, except specific cases
    <FilesMatch ".php$">
        # Allow access to specific PHP files or directories
        RewriteCond %{REQUEST_URI} !^/router.php$ [NC]
        RewriteCond %{REQUEST_URI} !^/ajax/ [NC]  # Allow AJAX calls to PHP files
        RewriteRule ^(.*)$ - [F,L]
    </FilesMatch>
    
    # Prevent access to .htaccess and .htpasswd files
    <FilesMatch "^.ht">
        Require all denied
    </FilesMatch>
    
    # Enable compression for various content types
    <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>
    
    # Enable expiration headers for caching
    <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>
    

    I added these parts:

    1. Prevent direct access to PHP files in _process folder
    2. Restrict direct access to PHP files from the browser, except specific cases
    # Prevent direct access to PHP files in _process folder
    RewriteRule ^_process /.*.php$ - [F,L]
    
    # Restrict direct access to PHP files from the browser, except specific cases
    <FilesMatch ".php$">
        # Allow access to specific PHP files or directories
        RewriteCond %{REQUEST_URI} !^/router.php$ [NC]
        RewriteCond %{REQUEST_URI} !^/ajax/ [NC]  # Allow AJAX calls to PHP files
        RewriteRule ^(.*)$ - [F,L]
    </FilesMatch>
    

    Instead of:

    # Restrict direct access to PHP files, except from localhost
    <Files *.php>
        Order Deny,Allow
        Deny from all
        Allow from 127.0.0.1
    </Files>
    

  2. 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.

    # Enable RewriteEngine
    RewriteEngine On
    
    # Custom 404 page
    ErrorDocument 404 /404.php
    
    # Redirect www to non-www
    RewriteCond %{HTTP_HOST} ^www.example.sk [NC]
    RewriteRule ^(.*)$ http://example.sk/$1 [L,R=301,NC]
    
    # Ensure HTTPS
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    
    # Allow access to files inside /_process/ folder
    RewriteCond %{REQUEST_URI} ^/_process/ [NC]
    RewriteRule ^(.*)$ - [L]
    
    # Route all other requests to router.php (except existing files and directories)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /router.php [L,QSA]
    
    # Disable directory browsing
    Options -Indexes
    
    # Restrict direct access to PHP files, except from localhost
    <Files *.php>
        Order Deny,Allow
        Deny from all
        Allow from 127.0.0.1
    </Files>
    
    # Prevent access to .htaccess and .htpasswd
    <Files ".ht*">
        Require all denied
    </Files>
    
    # Enable compression for various content types
    <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>
    
    # Enable expiration headers for caching
    <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>
    

    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.

    1. Ensuring Router Setup
      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:
    $router->add('GET', '/all-posts', function() {
       require 'all-posts.php';
    });
    
    // You can add more routes like this:
    $router->add('GET', '/about', function() {
       require 'about.php';
    });
    

    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 🙂

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