Ваше правило
RewriteRule ([0-9]*)$ index.php/listing/$1
бесполезен, потому что он не меняет REQUEST_URI
, поэтому PHP не увидит переписанный index.php/listing/123
, он увидит оригинал /listing/foo-123
. Если вы добавите флаг [L]
, он будет зациклен, потому что соответствующий ReqeuestCond
останется истинным.
Обычно вы передаете биты URL скрипту в качестве параметров, например
RewriteRule ([0-9]*)$ index.php?listing=$1 [L]
Однако, в этой форме это не будет работать, потому что ([0-9]*)$
соответствует пустой строке в конце любого пути, поэтому это приведет к двум перезаписям:
listing/foo-(123) → index.php?listing=123 # this is what you want ...
index.php() → index.php?listing= # ... but it gets rewritten
index.php() → index.php?listing= # no change so this is final
Это происходит потому, что все правила перезаписи оцениваются с начала после каждого перезаписи (независимо от флага [L]
).
Таким образом, вам нужно более конкретное правило
RewriteRule ^listing/[^/]*-([0-9]*)$ index.php?listing=$1 [L]
Это работает само по себе, но оно будет взаимодействовать с вашим последним правилом, поэтому добавьте к нему условие, чтобы оно не зацикливалось
RewriteCond $0 !^/index.php($|/) # $0 is what the RewriteRule matched
RewriteRule .* index.php/$0 [L]