【问题标题】:Running Yii from subdir. Remove subdir with .htacces, while .css,.js and existing files and dirs still are available从子目录运行 Yii。使用 .htacces 删除子目录,而 .css、.js 和现有文件和目录仍然可用
【发布时间】:2013-05-02 01:17:18
【问题描述】:

到目前为止,我已经搜索了 4 个小时,但仍然无法正常工作。 我的 webroot 中有以下目录:

- application
    - assets
    - css
    - config
    - protected
        - .htaccess
    - ...
    - .htaccess
- framework
    - [Yii framework inside]
- .htaccess

只要请求的文件或目录不存在,我的 webroot 中的 .htaccess 应该重定向/“重写”所有对 xxx/xxx 的请求到 http://www.example.com/application/。 这样对 .css、.js 和其他文件的请求仍然可以工作。

在我的配置中,我确保 Yii 期望 SEO 友好的 URL,并且我不倾向于使用 index.php。所以它现在看起来像这样:

'urlManager'=>array(
        'urlFormat'=>'path',
        'showScriptName'=>false,
        'rules'=>array(
            '' => 'site/index',
            '<controller:\w+>/<id:\d+>'=>'<controller>/view',
            '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
            '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
        ),
    ),
    'request' => array(
        'baseUrl' => 'http://www.example.com',
    ),

“请求”是后来添加的,因为 Yii 生成链接为 example.com/application/site/login。 Yii 使用请求生成 example.com/site/login。

在我的 webroot 中的 .htaccess 中,我尝试了一切。

  • 首先,我能够从 URL 中“删除”子目录。已显示索引页。
  • 我尝试添加一条规则,以便将所有不存在的目录重定向到相同的 url。
  • 我的第一条规则被打破,“应用程序”再次出现在 URL 中,但没有加载任何 css 样式。
  • 此时我得到了带有 css 的索引页面,但现在一切都将我带到了索引页面。

我的 .htaccess 看起来像这样:

RewriteEngine on

RewriteCond $1 !^application/
# if a directory or a file exists, use it directly
RewriteCond %{DOCUMENT_ROOT}/application/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/application/$1 -d
RewriteRule ^(.*)$ application/$1 [L]

# otherwise forward it to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^.*$ application/index.php

Mod_rewrite 已启用(我知道是因为有些事情以前有效)。我查看了来自Yii docs 的示例。 我尝试了 Stack Overflow 上其他问题的解决方案,例如 one 和许多其他问题。 还是没有运气。

有人可以帮帮我吗?


编辑: 使用上面的 .htaccess 对 example.com 的请求以 example.com/application 结尾。但是我想再次使“应用程序”“不可见”(以前工作过,不知道为什么它坏了)


我确实更改了我的 .htaccess,如下所示:

RewriteEngine on

RewriteCond $1 !^application/
# if a directory or a file exists, use it directly
RewriteCond %{DOCUMENT_ROOT}/application/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/application/$1 -d
RewriteRule ^(.*)$ application/$1 [L]

# otherwise forward it to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ /application/
RewriteCond %{HTTP_HOST} ^(www.)?brainfeeder.be$
RewriteRule ^$ application/$1 [L,QSA]

但仍然像 www.brainfeeder.be/site/login 这样的网址将我带到默认控制器/操作,即站点/索引。 我想我的条件或规则还不完全正确。 请查看我的 small test application 我设置来解决这个问题。

会发生什么:brainfeeder.be 被重写为brainfeeder.be/application/ 我的Yii 应用程序在那里,所以它运行'bootstrap' index.php 文件并进入默认的控制器/动作,在这种情况下是站点/索引. 现在,当您单击“登录”按钮时,它应该会显示一个登录表单。但它停留在站点/索引视图中。


好的,我再次更新了我的 .htaccess 几次。现在我有以下情况:

  • www.example.com AND example.com 被重写为 www.example.com/application AND example.com/application。
  • (www.)?example.com/existingfolder 只显示“现有文件夹”的内容。
  • (www.)?example.com/var1/var2/../varn 被重定向到 (www.)?example.com/application/var1/var2/.../varn

现在我唯一希望发生的事情是后者被重写而不是重定向。所以访问者不知道他们在目录“应用程序”中。

所以 (www.)?example.com/var1/var2/.../varn 会将访问者直接带到正确的页面。

目前我的.htaccess的内容:

Options +FollowSymLinks
#IndexIgnore */*
RewriteEngine on

RewriteBase /

RewriteCond %{HTTP_HOST} ^(www.)?brainfeeder.be$
RewriteRule ^$ /application/ [L]

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule ^.*$ - [L]

# The directory or file does not exist
RewriteCond %{REQUEST_FILENAME} !-s [OR]
RewriteCond %{REQUEST_FILENAME} !-l [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /application/$1 [L,R]

问题是,当在最后一个 RewriteRule 中丢失 R 标志时,会将我带到“应用程序”内的 index.php 文件,但是当我访问 example.com/ 时,它会显示主页而不是登录表单网站/登录。

我猜,脚本看不到变量。 (如果它确实会触发站点/错误)因此它会将其作为对 example.com/application 的请求而不是作为 example.com/application/var1/var2 的请求来处理

我希望这次我确实更好地解释了这个问题。 感谢您迄今为止的大力帮助。

【问题讨论】:

    标签: php apache .htaccess mod-rewrite yii


    【解决方案1】:

    您不需要编辑 .htaccess。您只需将 Yii 入口脚本 (index.php) 和默认的 .htaccess 从子目录向上移动到 webroot(以便它们直接位于 public_html 下)。将 index.php 和 .htaccess 移到根目录后,所有的 web 请求都会直接路由到 webroot 下的 index.php(而不是子目录),从而去掉了 url 的 /subdirectory 部分。

    移动文件后,您需要编辑 index.php 以更新对 yii.php 文件(在 Y​​ii 框架目录下)以及 Yii 配置文件(main.php)的引用。最后,您需要将 assets 目录直接移动到 webroot,因为默认情况下,Yii 期望 assets 目录与入口脚本位于同一位置。

    这应该是您需要做的所有事情,但如果您需要更多详细信息,我会在此处更全面地描述该方法:

    http://muhammadatt.tumblr.com/post/83149364519/modifying-a-yii-application-to-run-from-a-subdirectory

    【讨论】:

    • 不错的解决方案。但是我希望子目录是可移植的(以非常简单的复制/粘贴方式)。这就是为什么我喜欢将条目脚本放在它原来的位置。到目前为止,我有 6 个子目录从同一个框架目录运行 Yii。
    【解决方案2】:

    如果您只想将所有不存在的 /$var1/$var2 重写为 /,请尝试检查这些配置指令应用程序/

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]+)/([^/]+)$ /application/
    

    现在,如果您希望重定向那些不存在的文件,而不是重写它们?然后只需在 RewriteRule 指令的末尾添加一个 [R] 标志,只是不要忘记标志前的单个 " " 空格。


    现在,如果您想将 /application 重定向到 /,然后将 /index.php 重写为 /application em> 并将不存在的 /$var1/$var2 重写为 /application/$var1/$var2 那么这很难(并且需要一些确切的细节)但是你仍然可以尝试这些配置指令:

    RewriteEngine on
    
    # rewrite index.php
    RewriteRule ^index.php$ /application
    
    # rewrite unexisting files
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]+)/([^/]+)/?$ /application/$1/$2
    
    # try to remove this if it causes redirection loop
    RewriteRule ^application/?$ / [R]
    

    您也可以尝试在这些指令的最顶部使用DirectoryIndex application/index.php 来更改您网站的索引,如果导致错误,请删除RewriteRule ^index.php$ /application 行。

    其实我看不懂你的问题。。你说:

    我的 webroot 中的 .htaccess 应该重定向/“重写”所有请求 无论 xxx/xxx 到 http://www.example.com/application/,只要 请求的文件或目录不存在。这种方式要求 .css、.js 等文件仍然可以使用。

    现在,你对你的评论说:

    所以应该显示任何到 brainfeeder.be/application/$var1/$var2 的链接 作为brainfeeder.be/$var1/$var2

    如果您还想将现有的 /application/$var1/$var2 重定向到 /$var1 /$var2 那么请尝试添加这些指令,如果它导致您的系统出错,只需将其删除:

    # the condition is important as mentioned above
    RewriteCond %{REQUEST_URI} !\.css$
    RewriteRule ^application/([^/]+)/([^/]+)/?$ /$1/$2 [R]
    

    您可以在RewriteRule 的顶部添加另一个条件(任意数量),如果您是程序员,请使用您的想法。如果您不想使用 .jpg 之类的扩展名重定向文件,或者您想要这样的扩展名,则可以添加另一个条件,例如 RewriteCond %{REQUEST_URI} !\.jpg$

    RewriteCond %{REQUEST_URI} !\.css$
    RewriteCond %{REQUEST_URI} !\.jpg$
    RewriteCond %{REQUEST_URI} !\.png$
    RewriteRule ^application/([^/]+)/([^/]+)/?$ /$1/$2 [R]
    

    请尝试使用以下代码更改 .htaccess 文件的来源:

    Options +FollowSymlinks
    RewriteEngine on
    RewriteBase /
    
    RewriteCond %{HTTP_HOST} ^(www\.)?brainfeeder\.be$
    RewriteRule ^/?$ /application/ [L]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)$ /application/$1 [L]
    

    【讨论】:

    • 这对我不起作用。请注意,我也想将 (www.)?example.com/application 重写为 example.com。
    • @Brainfeeder 实际上,我无法理解你的问题.. 你在线吗?或者你可以让自己上网吗?
    • 是的,索引是一个 .php 文件,但是在我的应用程序文件夹中,我有另一个 .htaccess 来处理 Yii 本身的 index.php 文件。内容正是另一个答案;)。
    • 有什么想法吗?你会是我的英雄!
    • 没有保留样式。我看到了错误的页面,因为索引没有看到 var1/var2 中的页面。我只是得到了当 var1 和 var2 没有设置时你应该看到的默认页面
    【解决方案3】:

    不知道你的问题是什么......

    但是这里有一个 .htaccess 应该可以完成你想要的:

    RewriteEngine on
    
    # if a directory or a file exists, use it directly
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    
    # otherwise forward it to index.php
    RewriteRule . index.php
    

    【讨论】:

    • 这只会从 url 中删除 index.php。我的 Yii 应用程序位于我的 webroot 的子目录中。我想将访问者从 webroot 重定向到该子目录,并且 URL 应保持为 www.example.com。因此不是 www.example.com/subdirectory。在this 问题中也提出了同样的问题。
    • 好的,现在我明白你想要做什么了。我不得不承认,我对 Apache 的了解太有限,无法真正帮助到您。
    猜你喜欢
    • 2013-01-07
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    相关资源
    最近更新 更多