简体   繁体   中英

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.

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.

SCENARIO 1:
Browser Address Bar Input: 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)
Browser Page Result: THE EXPECTED PAGE (/public/index.php which then routes to /public/controllers/index.php and uses action "index" by default)

SCENARIO 2:
Browser Address Bar Input: 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)
Browser Page Result: THE EXPECTED PAGE (/public/index.php which routes to the correct controller and action)

SCENARIO 3:
Browser Address Bar Input: NONE
Action By User: Click on link generated by Phalcon and pointing to "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)

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

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

In the "Beautiful URLs" section it describes how to redirect the requests so that they work with the MVC pattern Phalcon offers.

So this rewrite 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:

<?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:

<?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
    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> . Only one web.config is needed instead of two.

Note: <projectpath> is not a variable!
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 ).

Comment:
web.config is quite powerful indeed, but I found it arguably harder to grasp than the more concise .htaccess equivalent. 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. However, there appears to be an inconsistency in the instructions where it first defines $url->setBaseUri('/'); , then shows a screenshot of a browser visiting localhost/tutorial/ . Clearly, it should be $url->setBaseUri('/tutorial/'); for a project reachable at localhost/tutorial/ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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