mod_rewrite .htaccess che causa 500 errori del server se URl non esiste

Ho appena iniziato a utilizzare mod_rewrite, questo è quello che uso per un sito web strutturato abbastanza semplice con supporto per più lingue:

RewriteEngine on ErrorDocument 404 /error404.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([a-zA-Z]{2})/([^/]+)$ $2.php?lang=$1 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([a-zA-Z]{2})/$ index.php?lang=$1 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([a-zA-Z]{2})$ index.php?lang=$1 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]+)$ $1.php [L] 

La mia idea era che le lingue fossero indicate all'inizio dell'URL e wheressero essere due caratteri (az o AZ). Dopodiché ci sarà una string che si riferisce ad un file php che ha lo stesso nome di file della string, solo .php allegato. La lingua verrà aggiunta come variabile GET ( ?lang=en ).

Quindi, un URL potrebbe essere simile a questo: /en/index e dovrebbe quindi essere reindirizzato a index.php?lang=en .

Se URl non inizia con una lingua, ma direttamente con la string, quindi nessuna variabile GET verrà allegata alla string. Ad esempio /index dovrebbe fare riferimento a index.php . Se non c'è una string, l'indice dovrebbe essere usato come predefinito.

Fin qui tutto bene. Funziona bene. Solo se inserisco una string (non import se uso 2 caratteri per la lingua o less), il sito mostra sempre un errore interno di 500 server, invece di andare a error404.php . Inoltre, se cancello questa row (404) in .htaccess, è sempre lo stesso errore.

Quindi, presumo che ci sia qualcosa di sbagliato nelle altre righe nel .htaccess che causa questo errore, qualcuno ha un'idea di cosa potrebbe essere?

Qualsiasi aiuto è molto apprezzato!

Le tue regole sono in loop. A colpo d'occhio, sembra il tuo ultimo:

 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]+)$ $1.php [L] 

Diciamo che ho questo URL, http://your.domain.com/blah , e il file blah.php non esiste. Questo è quello che sta succedendo.

  1. URI = blah -f è vero, non è un file
  2. URI = blah ,! -d è vero, non è una directory
  3. URI = blah , riscrittura interna a blah.php
  4. blah ! = blah.php , riscrivi il ciclo delle regole
  5. URI = blah.php ! -f è vero, non è un file
  6. URI = blah.php ! -d è vero, non è una directory
  7. URI = blah.php , riscrittura interna a blah.php.php
  8. blah.php ! = blah.php.php , riscrive il ciclo delle regole

Questo va avanti fino a quando il motore di riscrittura ha avuto abbastanza e restituisce un errore di 500 server.

Puoi fare una delle 2 cose qui:

  1. Aggiungi una direttiva per fare in modo che tutto il ciclo si fermi a prescindere da cosa , ed è facile aggirare questo tipo di cose. Ma romperà le regole che richiedono il looping. Non vedo nulla di simile nelle tue regole quindi è sicuro (alless per ora) farlo. Basta aggiungere questo in cima alle tue regole:

     RewriteCond %{ENV:REDIRECT_STATUS} 200 RewriteRule ^ - [L] 
  2. Fai un controllo preventsvo per vedere se il file php esiste realmente:

     RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^([^/]+)$ $1.php [L] 

Helmut, prova questo (l'ultima regola è il motivo dell'errore interno 500, e questo include anche il suggerimento di @DaveRandom di unire le regole 2 e 3):

 RewriteEngine on ErrorDocument 404 /error404.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([a-zA-Z]{2})/([^/]+)$ $2.php?lang=$1 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([a-zA-Z]{2})/?$ index.php?lang=$1 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([a-zA-Z0-9]+)$ $1.php [L]