-1

UPDATE: I added a 404 error document:

<IfModule mod_rewrite.c>
RewriteEngine on
ErrorDocument 404 /new404.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
</IfModule>

But nothing has changed.

I have a problem with an apache snippet:

RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]

in

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
</IfModule>

I created to obtain an URL like this:

http://localhost:8888/en
http://localhost:8888/en/team
http://localhost:8888/en/anything

And I called my PHP file like this:

team-en.html.php
anything-en.html.php

This because I have different languages.

now, that's my PHP file to display them:

$path = isset($_GET['path']) ? $_GET['path'] : false;
$path = strtolower($path);
$path = preg_replace("/[^a-z-\/]/", '', $path);
$parts = explode("/", $path);


if (is_array($parts) && isset($parts[1])) {
    if (file_exists(__DIR__ . '/processors/' . $parts[1] . '.php')) {
        $processor = $parts[1];
    }
    if (file_exists(__DIR__ . '/pages/' . $parts[1] . '-'. $language .'.html.php')) {
        
        $page = $parts[1];
    }
}

Where languages variable is:

$language = 'en';

$languages = [];
$languages[] = 'en';
$languages[] = 'nl';
$languages[] = 'fr';

Now, this won't return a 404 page for some reason and will return only a 200 header response.

I'm wondering if anyone has experience in setting up a 404-page system, I read a lot of tutorials but none of them gave me a satisfying answer.

Thank you in advance

Rob
  • 14,746
  • 28
  • 47
  • 65
  • 1
    The given code does not contain any information to throw 404 errors - is there anything missing which you haven't shared, or do you expect such an error to be thrown by any other component? – Nico Haase Jan 11 '21 at 08:36
  • I thought that the 404 would have handled by the server itself, I'm an apache beginner. I added before: ErrorDocument 404 /404.php but it wasn't used so I added a 404 snippet in my php code something like: http_response_code(404); but it was used on every page – Italianspiderman80 Jan 11 '21 at 08:41
  • 1
    What Nico said. Think it through - you told Apache to forward all requests to `index.php`. Currently no matter what you request, that will happen, and your PHP code happily processes them all. `http://localhost:8888/stackoverflow.com` will work. If you delegate your PHP to handle the routing, it needs to decide what is a 200 vs a 404, etc. – Don't Panic Jan 11 '21 at 09:55
  • Yes it is true and now it is actually working, but what about keeping the redirection and change only this re-write rule instead: RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA] I tried a bunch of different solution but I wasn't able to fix it – Italianspiderman80 Jan 11 '21 at 13:09
  • @Don'tPanic and what about the best practice in those cases? Let php dealing with a 404 page or apache? – Italianspiderman80 Jan 11 '21 at 13:12
  • 1
    It depends on what you are trying to achieve. Most frameworks ([eg Laravel](https://laravel.com/docs/5.0/configuration#pretty-urls), etc) do pretty much exactly as you are doing, and it is then up to the framework to return a 404 where appropriate. If you only want PHP to handle certain URLs, update your `RewriteRule` regex to only match them. But if, eg, the available languages are only available in PHP (maybe in DB), then you *have* to use PHP to work out if it is a 404 or not, and return one if so. – Don't Panic Jan 11 '21 at 13:25
  • PS - [don't forget to upvote](https://stackoverflow.com/help/someone-answers) Nico's answer, if it helped. – Don't Panic Jan 11 '21 at 13:26

1 Answers1

1

The rewrite rule matches on all routes. There's no way that Apache can throw a 404 error, as it does not know what your application is doing.

You need to check whether such an error should be thrown in your application itself, within PHP code. If the files within the subfolders are the proper condition for this, you could write:

if (is_array($parts) && isset($parts[1])) {
    if (file_exists(__DIR__ . '/processors/' . $parts[1] . '.php')) {
        $processor = $parts[1];
    }
    if (file_exists(__DIR__ . '/pages/' . $parts[1] . '-'. $language .'.html.php')) {
        $page = $parts[1];
    } else {
        http_response_code(404);
        die();
    }       
}
Nico Haase
  • 11,420
  • 35
  • 43
  • 69