请协助mod重写应用程序/视图目录到Kohana的“视图”

时间:2013-07-15 17:22:18

标签: .htaccess kohana-3

由于我选择模板化网站的方式,我需要将“应用程序/视图”重写为“视图”。我选择这样做(1)缩短我将在链接样式表等时使用的URL,以及掩盖我的文件系统的结构。

目前,如果删除重写规则,我可以直接在application / views / template / file.css访问媒体文件。当我启用重写规则时,我被重定向到views / template / file.css但Kohana返回: Kohana_HTTP_Exception [404]:无法找到匹配URI的路由:template / u_crossbrowser / css / bootstrap.css

我想我可以深入研究脚本并提出一个条件,说明如果url正在调用views dir,请不要尝试控制路由。但我想有一个更好的解决方案。

我的.htaccess文件:

RewriteEngine on

# Installation directory
RewriteBase /

# Protect hidden files from being viewed
<Files .*>
    Order Deny,Allow
    Deny From All
</Files>


#We needed direct file access for our media files (css, js, images) but the rewrite below was breaking it. So, we replaced it with rule 2 below.
    # Protect application and system files from being viewed
    # RewriteRule ^(?:application|modules|system)\b - [F,L]

# Rule 2: Disable directory listings
IndexIgnore *

# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php [PT]


RewriteCond %{THE_REQUEST} ^GET\ /application/views/
RewriteRule ^application/views/(.*) /views/$1 [L,R=301]

1 个答案:

答案 0 :(得分:0)

这里有两个问题:

  1. 在将所有内容重写为/application/views/...的规则之后,将/views/...重写为index.php的规则是。你需要在之前进行更具体的重写更一般的重写,以防止更一般的重写停止处理。

  2. 您的重写规则不完整。您有一条规则,以便对/application/views/...的请求进行重写,就像文件实际位于/views/...一样。但是,因为您实际上仍然将文件存储在application/views/文件夹中,所以您缺少允许您访问的规则,就好像它们位于/views/... < / EM>

  3. 以下是制作重写规则以使其正常工作的一种方法。 (我省略了将/application/views/...重定向到/views/...的规则,因为我不明白为什么你需要它 - 只是让/application无法访问并只使用/views/...然后赢了无论如何都要重要。)

    RewriteEngine on
    
    # Installation directory
    RewriteBase /
    
    # Protect hidden files from being viewed
    <Files .*>
        Order Deny,Allow
        Deny From All
    </Files>
    
    # Pretend that views are one directory above where they actually are
    RewriteRule ^views/(.*) application/views/$1 [L]
    
    # Protect application and system files from being viewed,
    # UNLESS we are redirecting to them from another rule
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^(?:application|modules|system)\b - [F,L]
    
    
    # Allow any files or directories that exist to be displayed directly
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    
    # Rewrite all other URLs to index.php/URL
    RewriteRule .* index.php [PT]
    

    (感谢@ CDuv对ENV:REDIRECT_STATUS诀窍mod_rewrite: allow redirect but prevent direct access的回答。)


    事实上,您可能会发现创建此内容的路径更有意义。这是因为它允许您将applicationmodulessystem目录移出Web根目录。这样做的一个好处是,如果您开发了另一个Kohana应用程序,则可以在多个Kohana应用程序之间共享modulessystem。另一个是它意味着你不需要依赖htaccess来保护对这些目录的访问。

    这是一个基于Kohana Userguide模块可用于提供这些文件的简单方法。

    bootstrap.php中添加此路线:

    // Static file serving (CSS, JS, images) - ADD MORE EXTENSIONS IF NEEDED
    Route::set('media', 'views(/<file>)', array('file' => '.+\.(css|js|jpg|png)'))
        ->defaults(array(
            'controller' => 'media',
            'action'     => 'media',
            'file'       => NULL,
        ));
    

    添加控制器Controller_Media

    class Controller_Media extends Controller
    {
        public function action_media()
        {
            // Get the file path from the request
            $file = $this->request->param('file');
    
            // Find the file extension
            $ext = pathinfo($file, PATHINFO_EXTENSION);
    
            // Remove the extension from the filename
            $file = substr($file, 0, -(strlen($ext) + 1));
    
            if ($file = Kohana::find_file('views', $file, $ext))
            {
                // Check if the browser sent an "if-none-match: <etag>" header, and tell if the file hasn't changed
                $this->check_cache(sha1($this->request->uri()).filemtime($file));
    
                // Send the file content as the response
                $this->response->body(file_get_contents($file));
    
                // Set the proper headers to allow caching
                $this->response->headers('content-type',  File::mime_by_ext($ext));
                $this->response->headers('last-modified', date('r', filemtime($file)));
            }
            else
            {
                // Return a 404 status
                $this->response->status(404);
            }
        }
    }