简体   繁体   English

Phalcon,IIS 7.5和URL重写问题

[英]Phalcon, IIS 7.5 and URL Rewrite problems

So, I'm following the Phalcon php tutorial at this link http://docs.phalconphp.com/en/latest/reference/tutorial.html , but I'm trying to recreate the process using IIS 7.5 (as opposed to apache) and I'm having the following add/erroneous behavior. 因此,我在此链接http://docs.phalconphp.com/en/latest/reference/tutorial.html上关注Phalcon php教程,但是我试图使用IIS 7.5(而不是apache)来重新创建该过程。 ),并且出现以下添加/错误行为。

NOTE: The server name and port is something I created locally via IIS 7.5 so it won't do anything meaningful if you click on it or copy and paste into the browser address bar. 注意:服务器名称和端口是我通过IIS 7.5在本地创建的,因此如果您单击它或将其复制并粘贴到浏览器地址栏中,它不会做任何有意义的事情。

SCENARIO 1: 场景1:
Browser Address Bar Input: http://Phalcon:8181/ 浏览器地址栏输入: http://Phalcon:8181/
Browser Address Bar Result: http://Phalcon:8181/public/public/public/public/public/...[ad_nauseaum]../public/ (not the expected result. It should have been http://Phalcon:8181/index/index since they are set as defaults in the "bootstrap" index.php file) 浏览器地址栏结果: http://Phalcon:8181/public/public/public/public/public/...[ad_nauseaum]../public/ (不是预期的结果。应该是http://Phalcon:8181/index/index因为它们在“ bootstrap” index.php文件中设置为默认值)
Browser Page Result: THE EXPECTED PAGE (/public/index.php which then routes to /public/controllers/index.php and uses action "index" by default) 浏览器页面结果:预期页面(/public/index.php,然后路由到/public/controllers/index.php并默认使用操作“ index”)

SCENARIO 2: 场景2:
Browser Address Bar Input: http://Phalcon:8181/index.php 浏览器地址栏输入: http://Phalcon:8181/index.php
Browser Address Bar Result: http://Phalcon:8181/index.php (not the expected result. It should have been http://Phalcon:8181/index/index since they are set as defaults in the "bootstrap" index.php file) 浏览器地址栏结果: http://Phalcon:8181/index.php (不是预期的结果。它应该是http://Phalcon:8181/index/index因为它们在“ bootstrap”索引中设置为默认值。 php文件)
Browser Page Result: THE EXPECTED PAGE (/public/index.php which routes to the correct controller and action) 浏览器页面结果:预期页面(/public/index.php,它路由到正确的控制器和操作)

SCENARIO 3: 场景3:
Browser Address Bar Input: NONE 浏览器地址栏输入: NONE
Action By User: Click on link generated by Phalcon and pointing to "singup/index" 用户采取的行动:单击Phalcon生成的链接并指向“ singup / index”
Browser Address Result: http://Phalcon:8181/public/signup/index (not the expected result, I was expecting http://Phalcon:8181/signup/index since they were both proviced in the Phalcon-generated link) 浏览器地址结果: http://Phalcon:8181/public/signup/index (不是预期的结果,我期望http://Phalcon:8181/signup/index因为它们均在Phalcon生成的链接中提供)

I've tried messing with the web.configs, or the bootstrap php, but every other change I make, results in a 404 - page not found error from IIS 我尝试弄乱web.configs或bootstrap php,但是我所做的所有其他更改都导致404-IIS中找不到页面错误

Based on their "Creating a project->File structure" section, I created my site folder structure as follows: 基于他们的“创建项目->文件结构”部分,我如下创建了我的站点文件夹结构:

tutorial/
  app/
    controllers/
    models/
    views/
  public/
    css/
    img/
    js/

With the folder "tutorial" being the root of the website I've created in IIS 7.5 文件夹“ tutorial”是我在IIS 7.5中创建的网站的根目录

In the "Beautiful URLs" section it describes how to redirect the requests so that they work with the MVC pattern Phalcon offers. 在“漂亮的URL”部分中,它描述了如何重定向请求,以便它们与Phalcon提供的MVC模式一起使用。

So this rewrite mod 所以这个改mod

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule  ^$ public/    [L]
    RewriteRule  (.*) public/$1 [L]
</IfModule>  

Converts to this for IIS as is placed just inside the "tutorial" folder in a web.config file: 将IIS转换为web.config文件中“ tutorial”文件夹中的内容:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1" stopProcessing="true">
                    <match url="^$" ignoreCase="false" />
                    <action type="Rewrite" url="public/" />
                </rule>
                <rule name="Imported Rule 2" stopProcessing="true">
                    <match url="(.*)" ignoreCase="false" />
                    <action type="Rewrite" url="public/{R:1}" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
    <location path="public">
    </location>
</configuration>  

And this rewrite mod 而这个重写国防部

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</IfModule>  

Converts to this for IIS and is placed just inside the "tutorial/public" folder in a web.config file: 转换为IIS,并放置在web.config文件中的“ tutorial / public”文件夹中:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 3" enabled="true" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                    </conditions>
                    <serverVariables />
                    <action type="Rewrite" url="index.php?_url=/{R:1}" appendQueryString="true"    />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>  

As for the PHP bootstrap file that is supposed to handle the routing, it has the code below (and it's located just inside the "public" folder as index.php: 至于应该用来处理路由的PHP引导文件,它具有下面的代码(它位于index.php的“ public”文件夹中:

<?php
    try{

        // create a router
        $router = new \Phalcon\Mvc\Router();
        $router->setDefaultController("index");
        $router->setDefaultAction("index");
        $router->add("/public", array(
                "controller" => "index",
                "action" => "index"
            ));
        $router->notFound(array(
                "controller" => "index",
                "action" => "route404"
            ));

        // Register an autoloader
        $loader = new \Phalcon\Loader();
        $loader->registerDirs(array(
                '../app/controllers/',
                '../app/models/'
            ))->register();

        // Create a DI
        $di = new \Phalcon\DI\FactoryDefault();

        // Setup the view component
        $di->set('view', function(){
            $view = new \Phalcon\Mvc\View();
            $view->setViewsDir('../app/views/');
            return $view;
        });

        // Setup a basic URI so that all generated URIs includ the tutorial folder
        $di->set('url', function(){
            $url = new \Phalcon\Mvc\Url();
            $url->setBaseUri('/public/');
            return $url;
        });

        // Handle the request
        $application = new \Phalcon\Mvc\Application($di);

        echo $application->handle()->getContent();

    } 
    catch (\Phalcon\Exception $e)
    {
        echo "PhalconException: " , $e->getMessage();
    }

?>

Any thoughts on how to make this work seamlessly? 关于如何使这项工作无缝进行的任何想法?

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1" stopProcessing="true">
                    <match url="^$" ignoreCase="false" />
                    <action type="Rewrite" url="public/" />
                </rule>
                <rule name="Imported Rule 2" stopProcessing="true">
                    <match url="^(public/)?([^/]+)$" ignoreCase="false" />
                    <conditions>
                        <add input="C:\inetpub\wwwroot\<projectpath>\public\{R:2}" matchType="IsFile" />
                    </conditions>
                    <action type="Rewrite" url="public/{R:2}" appendQueryString="true" />
                </rule>
                <rule name="Imported Rule 3" stopProcessing="true">
                    <match url="(.*)" ignoreCase="false" />
                    <action type="Rewrite" url="public/index.php?_url={R:1}" appendQueryString="true" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

Put in the project root directory, this replicates the effect of the two .htaccess files generated by phalcon create-project <projectname> . 放在项目根目录中,这将复制phalcon create-project <projectname>生成的两个.htaccess文件的效果。 Only one web.config is needed instead of two. 只需要一个web.config ,而不是两个。

Note: <projectpath> is not a variable! 注意: <projectpath>不是变量!
I could not find an elegant way to refer to the current path, so while C:\\inetpub\\wwwroot could be written as {DOCUMENT_ROOT} , <projectpath> still needs to be explicitly typed in (eg projects/my_phalcon_project ). 我找不到一种引用当前路径的优雅方法,因此尽管C:\\inetpub\\wwwroot可以写为{DOCUMENT_ROOT}<projectpath>仍需要显式键入<projectpath> (例如, projects/my_phalcon_project )。

Comment: 评论:
web.config is quite powerful indeed, but I found it arguably harder to grasp than the more concise .htaccess equivalent. web.config确实确实非常强大,但是我发现它比更简洁的.htaccess更加难以理解。 I could not just take yours and modify it without first reading online documentation and examples . 如果不先阅读在线文档和示例,我不能只接受您的内容并进行修改。 Trial and error was also involved because some behaviours are neither documented nor intuitive. 由于某些行为既没有记录也没有直观性,因此还涉及反复试验。


With a similar web.config to the one above, I was able to complete the Phalcon tutorial on IIS 8.5. 使用与上面类似的web.config ,我能够完成IIS 8.5上的Phalcon 教程 However, there appears to be an inconsistency in the instructions where it first defines $url->setBaseUri('/'); 但是,在其首先定义$url->setBaseUri('/');的指令中似乎存在不一致$url->setBaseUri('/'); , then shows a screenshot of a browser visiting localhost/tutorial/ . ,然后显示浏览器访问localhost/tutorial/的屏幕截图。 Clearly, it should be $url->setBaseUri('/tutorial/'); 显然,它应该是$url->setBaseUri('/tutorial/'); for a project reachable at localhost/tutorial/ . 对于可通过localhost/tutorial/访问的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM