skip to Main Content

enter image description hereI have these files in my root, Inside pages i have php files for example projects.php, I tried writing in .htaccess rules to take the file for example xxx.com/projects to open the file from /pages/projects.php and it worked with the following

RewriteEngine On

RewriteCond %{ENV:REDIRECT_STATUS} . [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

# No file extension on request then append .php and rewrite to subdir
RewriteCond %{REQUEST_URI} /(.+)
RewriteRule !.[a-z0-4]{2,4}$ /pages/%1.php [NC,L]

# All remaining requests simply get rewritten to the subdir
RewriteRule (.*) /pages/$1 [L]

My problem here is when i go to the root xxx.com instead of opening index.php its opening pages directory but if i go explicitely to xxx.com/index.php it works.
I dont want index.php to be shown in the url i need to exclude the root from my rule and make it open index.php while the url stays xxx.com

2

Answers


  1. # All remaining requests simply get rewritten to the subdir
    RewriteRule (.*) /pages/$1 [L]
    

    To exclude "the root" being rewritten to /pages/ (and serve index.php from the root instead) you can simply change the quantifier in the last rule from * (0 or more) to + (1 or more) – so that it doesn’t match requests for the root (an empty URL-path in .htaccess).

    In other words:

    RewriteRule (.+) /pages/$1 [L]
    

    Incidentally, you have already done something similar in the preceding rule/condition by using + in the CondPattern, ie. RewriteCond %{REQUEST_URI} /(.+).

    Login or Signup to reply.
  2. I thought about this other solution:

    RewriteEngine On
    
    RewriteBase /
    
    # Hide the "pages" directory and all PHP files from direct access.
    RewriteRule ^pagesb|.php$ - [R=404]
    
    # Rewrite clean-URL pages to the PHP files inside the "pages" directory:
    # If the request isn't a file.
    RewriteCond %{REQUEST_FILENAME} !-f
    # If the request isn't a folder.
    RewriteCond %{REQUEST_FILENAME} !-d
    # If the PHP page file exists.
    RewriteCond %{DOCUMENT_ROOT}/pages/$0.php -f
    # /your-page?param=foo is rewritten to /pages/your-page.php?param=foo
    # The L flag isn't suffisient because the rewrite rule to protect PHP files
    # above will take over in the second loop over all the rewrite rules. To stop
    # here we can use the newly END flag which stops completely the rewrite engine.
    RewriteRule ^.*$ pages/$0.php [END,QSA]
    

    You wanted to hide index.php. This can be done with a 404 error.
    So you could just do:

    RewriteRule ^index.php - [R=404]
    

    But you’ll probably want to avoid also someone requesting /pages to list all the PHP files or to directly access /pages/your-page.php. So I used a regex that matches both the directory and PHP file extensions (only lowercase here, but you could use .(?i)php where (?i) enables the case insensitive flag).

    Then, for the rewrite itself, I would capture the URL with ^.*$ which will be available in the $0 backreference which can then be used in the rewrite rule itself and in the rewrite conditions.

    If the request is not a directory or an existing file then we have to check that the resulting rewritten URL is effectively an existing PHP file in the pages directory.

    I used the QSA flag so that you keep the query parameters in the resulting URL. The PHP script can then access them easily via $_GET. I expect you could also get them by checking some other environment variables if you don’t use this flag. I also had to use the END flag which is similar to the L for Last flag but completely stops the rewrite rules to execute. If you use the L flag instead the problem is that you’ll get the 404 error due to the fact that /pages/your-page.php will match the rewrite rule to hide PHP files since the whole process of rewrite rules is run a second time. The rewrite engine loop only stops when the input URL doesn’t get changed anymore by rewrite rules. Yes, this took me ages to understand that rewrite rules are not just run once like they are displayed in the config file!

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