Mod_rewrite заменяют символы нижнего подчеркивания тире (или дефисы) в Opencart

Я передаю сайт электронной коммерции новой корзине покупок. По некоторым причинам старый сайт использовал тире для категорий, но символы нижнего подчеркивания для продуктов.

Таким образом, полный URL продукта похож на это:

http://www.example.com/Engineering-Common-Bricks/65mm_Class_B__Solid_Engineering_Brick__Price_Each

Новая корзина использует тире для всего так, что я должен переписать входящие URL, такие как вышеупомянутое к следующему:

http://www.example.com/Engineering-Common-Bricks/65mm-Class-B--Solid-Engineering-Brick--Price-Each

Я знаю, что существует много материала по перезаписи символов нижнего подчеркивания к тире, но ни один из них, кажется, не работает на меня.

Я использую Opencart, который идет с существующим набором, переписывают правила поэтому, возможно, они вмешиваются в новые правила, которые я пытаюсь добавить.

Существующее .htaccess следующие:

Options +FollowSymlinks

# Prevent Directoy listing 
Options -Indexes

# Prevent Direct Access to files
<FilesMatch "\.(tpl|ini|log)">
 Order deny,allow
 Deny from all
</FilesMatch>

# SEO URL Settings
RewriteEngine On
# If your opencart installation does not run on the main web folder make sure you folder it does run in ie. / becomes /shop/ 

RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

Любая справка или направление были бы с благодарностью получены.


Обновление .htaccess согласно ответу ЕКА на следующее:

Options +FollowSymlinks
Options -Indexes

<FilesMatch "\.(tpl|ini|log)">
 Order deny,allow
 Deny from all
</FilesMatch>

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^_]*)_([^_]*_.*) $1-$2 [N]
RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301]

RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

Хорошо работает для:

http://example.com/this_is_a_category

Но Apache причин для катастрофического отказа на:

http://example.com/this_is_a_category/this_is_a_product
1
задан 23 September 2018 в 20:39
2 ответа

Так как RewriteRules предназначены для совпадения регулярных выражений, а не для их замены, то первая строка в

RewriteRule ^([^_]*)_([^_]*_.*) $1-$2 [N]
RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301]

не повторяется. Поэтому вам понадобится одна строка на каждое количество подчеркиваний, например,

RewriteRule ^(.*)_(.*)_(.*)_(.*)_(.*)_(.*)_(.*)$ /$1-$2-$3-$4-$5-$6-$7 [R=301,L]
RewriteRule ^(.*)_(.*)_(.*)_(.*)_(.*)_(.*)$ /$1-$2-$3-$4-$5-$6 [R=301,L]
RewriteRule ^(.*)_(.*)_(.*)_(.*)_(.*)$ /$1-$2-$3-$4-$5 [R=301,L]
RewriteRule ^(.*)_(.*)_(.*)_(.*)$ /$1-$2-$3-$4 [R=301,L]
RewriteRule ^(.*)_(.*)_(.*)$ /$1-$2-$3 [R=301,L]
RewriteRule ^(.*)_(.*)$ /$1-$2 [R=301,L]

заменяет 1-5, в результате чего

/Engineering_Common_Bricks/65mm_Class_B-Solid-Engineering-Brick-Price-Each

так что для 9 замен вам понадобится еще несколько строк сверху. Шаблон будет таким же, но в первую очередь необходимо использовать более длинные выражения.

Однако, при этом все подчеркивания заменяются тире (и перенаправляются после последнего), поэтому имена файлов, содержащих подчеркивания, не должны совпадать. Вы также можете предотвратить это, добавив директиву RewriteCond ДО этих правил:

RewriteCond %{REQUEST_FILENAME} !-f
1
ответ дан 4 December 2019 в 00:10
 RewriteRule ^ ([^ _] *) _ ([^ _] * _. *) $ 1- $ 2 [N]
RewriteRule ^ ([^ _] *) _ ([^ _] *) $ / $ 1- $ 2 [L, R = 301]
 

Прекрасно работает для:

 http://example.com/this_is_a_category
 

Но вызывает сбой Apache на:

 http://example.com/this_is_a_category/this_is_a_product
 

Чтобы решить эту проблему, вам просто нужно добавить флаг DPI (Discard Path Info) в первую директиву RewriteRule :

RewriteRule ^([^_]*)_([^_]*_.*) $1-$2 [N,DPI]
RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301]

«Сбой Apache» вызван ошибкой бесконечный цикл перезаписи. Флаг N заставляет набор правил зацикливаться (что требуется в этом сценарии для замены всей полосы одним из подчеркиваний), однако информация о пути из исходного запроса добавляется к перезаписанному URL-адресу на каждом итерация (по замыслу).

В первом примере с одним сегментом пути нет дополнительной информации о пути, поэтому ничего не добавляется. Однако второй пример содержит дополнительную информацию о пути, а именно / this_is_a_product (все, что находится после первого сегмента пути, который не соответствует пути физической файловой системы), который сам содержит символы подчеркивания. Это проблема. Каждая итерация цикла заменяет только одно подчеркивание, но каждая итерация цикла также добавляет еще 3 (в этом примере)! Таким образом, он никогда не сможет выполнить задачу по замене всех (первая линия) подчеркивания!

Если вы включите перезапись журнала, журнал ошибок будет сообщать что-то вроде:

/this_is_a_category/this_is_a_product
/this-is_a_category/this_is_a_product/this_is_a_product
/this-is-a_category/this_is_a_product/this_is_a_product/this_is_a_product
/this-is-a-category/this_is_a_product/this_is_a_product/this_is_a_product/this_is_a_product
/this-is-a-category/this-is_a_product/this_is_a_product/this_is_a_product/this_is_a_product/this_is_a_product
:

Как видите, это очень быстро выходит из строя контроля. По умолчанию он останавливается после 32 000 итераций (!), Но ваш сервер, вероятно, до этого времени исчерпает ресурсы; отсюда и авария. В Apache 2.4.8+ вы можете ограничить количество итераций, например. N = 10 - хотя это не решит вашу проблему, это предотвратит сбой вашего сервера!

AFAIK, флаг DPI (Apache 2.2.12+) был специально создан для решения этой проблемы. Он удаляет исходную информацию о пути из перезаписанного URL-адреса, поэтому он не добавляется каждый раз заново, что предотвращает бесконечный цикл перезаписи.

Ссылка:

0
ответ дан 4 December 2019 в 00:10

Теги

Похожие вопросы