Zend Framework — Ошибка, когда URL содержит $ $ $ или ~ на контроллере / сегменте действия

#zend-framework #url

#zend-framework #url

Вопрос:

На нашем сайте на базе ZF, если URL-адрес содержит $$$ or ~ в сегменте контроллера / действия, он не был перехвачен как ошибка 404, вместо этого они попали на контроллер / действие без символа, но когда он пытается загрузить сценарий просмотра, файл сценария просмотра все еще содержит эти символы, что приводит к ошибке.

Например:

 site.com/index$$$
script 'index$$$/index.phtml' not found in path

site.com/index-$$$
script 'index-$$$/index.phtml' not found in path

site.com/index~
script 'index~/index.phtml' not found in path 

site.com/index/index~
script 'index/index~.phtml' not found in path 
  

Они должны быть перехвачены как ошибка 404, и наш сайт может перехватить ошибки 404, если контроллер / действие не существует.

 ex: /badurl$$$, /non/existing~
  

Пример:http://framework.zend.com/index .$$$/index~

Существуют ли какие-либо существующие проблемы / решения для этого?

Заранее спасибо!

PS: мы все еще используем ZF 1.0.3, но это также влияет на другие сайты, которые находятся в 1.8.2.

Обновление: Это содержимое .htaccess

 RewriteEngine on
RewriteBase /

RewriteCond %{REQUEST_URI} ^/search$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule . /search/?%1 [R=301,L]

# Redirect all https urls to http
# These are the pages excluded on the redirection
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^/minify/.*
RewriteCond %{REQUEST_URI} !^/myaccount/.*
RewriteCond %{REQUEST_URI} !^/akamai/.*
RewriteCond %{REQUEST_URI} !^/navigation/.*
RewriteCond %{REQUEST_URI} !^/cache/.*
RewriteCond %{REQUEST_URI} !^/includes/.*
RewriteCond %{REQUEST_URI} !^/images/.*
RewriteCond %{REQUEST_URI} !^/pdf/.*
RewriteCond %{REQUEST_URI} !^/index.php
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]

######################################################

# if non-PHP file is requested, display the file #
RewriteRule .(js|ico|txt|gif|jpg|png|css|xml|swf|zip|pdf|gz)$ - [L,NC]

# if PHP file is requested and it exists, display the file #
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .php$ - [L]

# redirect everything else to controller #
RewriteCond %{REQUEST_URI} !^/server-status.*
RewriteRule . $ index.php [L]

# Disable Etags
    FileETag none
  

Комментарии:

1. Каковы ваши правила перезаписи? ZF 1.0.3? Черт.

2. Обновлено сообщение, чтобы включить правила перезаписи.

3. Я перечитал ваш пост. Если контроллер вызывается правильно, а сценарий просмотра — нет, похоже, что ваш PHP на самом деле неверен. Как вы настраиваете путь к сценарию просмотра?

Ответ №1:

Проблема не в вашем файле .htaccess.

Ваша проблема возникает в диспетчере, см. защищенный метод в 1.0.3 Zend_Controller_Dispatcher_Abstract::_formatName() . Этот метод также не изменился с версии 1.0.3. Таким образом, обновление не поможет.

Фактически это удаление всех специальных символов из URI с использованием preg_replace('/[^a-z0-9 ]/', '', $segment) и возврат допустимого имени класса.

Без написания собственного пользовательского диспетчера вам придется использовать другое наименование с буквенно-цифровыми символами, например / xxx или / 000

Смотрите метод ниже:

  /**
 * Formats a string from a URI into a PHP-friendly name.
 *
 * By default, replaces words separated by the word separator character(s)
 * with camelCaps. If $isAction is false, it also preserves replaces words
 * separated by the path separation character with an underscore, making
 * the following word Title cased. All non-alphanumeric characters are
 * removed.
 *
 * @param string $unformatted
 * @param boolean $isAction Defaults to false
 * @return string
 */
protected function _formatName($unformatted, $isAction = false)
{
    // preserve directories
    if (!$isAction) {
        $segments = explode($this->getPathDelimiter(), $unformatted);
    } else {
        $segments = (array) $unformatted;
    }

    foreach ($segments as $key => $segment) {
        $segment        = str_replace($this->getWordDelimiter(), ' ', strtolower($segment));
        $segment        = preg_replace('/[^a-z0-9 ]/', '', $segment);
        $segments[$key] = str_replace(' ', '', ucwords($segment));
    }

    return implode('_', $segments);
}
  

Комментарии:

1. Спасибо за очень хорошую находку. Попытаемся посмотреть, можно ли исправить наши коды для этого.

2. Было бы сохранить его, если бы я просто ввел некоторые правила перенаправления, подобные этому? 80 # Запретить странные фрагменты URL, чтобы вызвать ошибку app in 500 из-за странного форматирования имени ZF 81 RewriteRule ^. [^-a-zA-Z0-9_/] $ /404.html [R =301,L] 82 RewriteRule ^. [^-a-zA-Z0-9_]/. $ /404.html [ R=301,L]

3. Я думаю, что ваша идея использовать правило перезаписи для перехвата недопустимых запросов просто прекрасна. Просто будьте осторожны с другими именами файлов, такими как изображения, js, css и т.д.