PHP 内置服务器和 .htaccess mod 重写

Posted

技术标签:

【中文标题】PHP 内置服务器和 .htaccess mod 重写【英文标题】:PHP built in server and .htaccess mod rewrites 【发布时间】:2015-02-07 11:56:00 【问题描述】:

php 的内置服务器不使用 .htaccess 吗?我想这是有道理的,因为它不依赖于 Apache(?)。无论如何,是否可以告诉服务器使用这些文件 - 它可以处理 URL 重写吗?我在依赖这些文件的框架中有一些项目。

APPLICATION_ENV=development php -S localhost:8000 -t public/

【问题讨论】:

php -S 不是 apache,为什么要读取任何 apache 配置文件? 你可以说通过php -S ... public/index.php服务你的front controller 是的,但是 .htaccess 文件在应用程序中很常用,所以我想知道 PHP 服务器是否确实处理了它们。我猜不会。指向前端控制器很好,但是当我想重写 /news/view/205 之类的 url 目前我不能。 我不太清楚你的问题。如果你想你不必使用 .htaccess 但你可以在 apache httpd.conf;在那里你可以在你的虚拟主机配置指令之间设置 url 重写规则。因此;如果你想在某个目录上使用规则,你可以在那里定义它。如果要这样做,则需要在这样做时重新加载 httpd.conf 文件。 我不知道。 【参考方案1】:

这是我用于内置 php 网络服务器的路由器,它为文件系统中的资产(如果存在)提供服务,否则会重写 index.php 文件。

运行使用:

php -S localhost:8080 router.php

router.php:

<?php

chdir(__DIR__);
$filePath = realpath(ltrim($_SERVER["REQUEST_URI"], '/'));
if ($filePath && is_dir($filePath))
    // attempt to find an index file
    foreach (['index.php', 'index.html'] as $indexFile)
        if ($filePath = realpath($filePath . DIRECTORY_SEPARATOR . $indexFile))
            break;
        
    

if ($filePath && is_file($filePath)) 
    // 1. check that file is not outside of this directory for security
    // 2. check for circular reference to router.php
    // 3. don't serve dotfiles
    if (strpos($filePath, __DIR__ . DIRECTORY_SEPARATOR) === 0 &&
        $filePath != __DIR__ . DIRECTORY_SEPARATOR . 'router.php' &&
        substr(basename($filePath), 0, 1) != '.'
    ) 
        if (strtolower(substr($filePath, -4)) == '.php') 
            // php file; serve through interpreter
            include $filePath;
         else 
            // asset file; serve from filesystem
            return false;
        
     else 
        // disallowed file
        header("HTTP/1.1 404 Not Found");
        echo "404 Not Found";
    
 else 
    // rewrite to our index file
    include __DIR__ . DIRECTORY_SEPARATOR . 'index.php';

【讨论】:

我在测试时使用它而不是创建一个全新的 Apache 虚拟主机。非常有用的sn-p。 (请注意,您可以在index.php 中使用$_SERVER['REQUEST_URI'] 来获取实际的请求URL。)【参考方案2】:

使用 PHP 的内置网络服务器无法处理 .htaccess(它不依赖于 apache,它完全在 PHP 的核心中实现)。但是,您可以使用路由器脚本(此处描述:http://php.net/manual/en/features.commandline.webserver.php)。

例如php -S localhost -S localhost:8080 router.php

【讨论】:

那你需要使用.htaccess 您不能将 .htaccess 与 PHP 的内置服务器一起使用。不支持。如果您想使用 .htaccess 而不是其他方式来配置您的网络服务器,那么您要么必须使用 Apache,要么自己在 PHP 中解析 .htaccess(这可能会很困难) 啊,有道理。是的,我同意。【参考方案3】:

我们目前正在处理遗留项目,我遇到了同样的问题。根据@Caleb 的回答,我们设法添加了更多控件:

    将请求路由到旧的 htaccess 路由器(在下面的示例中为url.php); 使用查询字符串; 更改当前目录以使用 PHP 包含; 另外:命名为 server.php 以匹配 Laravel 的 PHP 内置路由器。

只需输入 cmd:php -S localhost:8888 server.php

chdir(__DIR__);
$queryString = $_SERVER['QUERY_STRING'];
$filePath = realpath(ltrim(($queryString ? $_SERVER["SCRIPT_NAME"] : $_SERVER["REQUEST_URI"]), '/'));
if ($filePath && is_dir($filePath))
    // attempt to find an index file
    foreach (['index.php', 'index.html'] as $indexFile)
        if ($filePath = realpath($filePath . DIRECTORY_SEPARATOR . $indexFile))
            break;
        
    

if ($filePath && is_file($filePath)) 
    // 1. check that file is not outside (behind) of this directory for security
    // 2. check for circular reference to server.php
    // 3. don't serve dotfiles
    if (strpos($filePath, __DIR__ . DIRECTORY_SEPARATOR) === 0
        && $filePath != __DIR__ . DIRECTORY_SEPARATOR . 'server.php' 
        && substr(basename($filePath), 0, 1) != '.'
    ) 
        if (strtolower(substr($filePath, -4)) == '.php') 
            // change directory for php includes
            chdir(dirname($filePath));

            // php file; serve through interpreter
            include $filePath;
         else 
            // asset file; serve from filesystem
            return false;
        
     else 
        // disallowed file
        header("HTTP/1.1 404 Not Found");
        echo "404 Not Found";
    
 else 
    // rewrite to our router file
    // this portion should be customized to your needs
    $_REQUEST['valor'] = ltrim($_SERVER['REQUEST_URI'], '/');
    include __DIR__ . DIRECTORY_SEPARATOR . 'url.php';

【讨论】:

以上是关于PHP 内置服务器和 .htaccess mod 重写的主要内容,如果未能解决你的问题,请参考以下文章

htaccess - mod_rewrite 将虚拟目录或文件作为参数传回 index.php?

.htaccess mod rewrite 适用于 WAMPP 但不适用于 XAMPP

如果我使用.htaccess mod重写规则,PHP Cookie不可用

.htaccess 和 mod_rewrite 出错

使用 .htaccess 和 mod_rewrite 强制 SSL/https

如何使用子域链接子目录? (虚拟主机、mod_rewrite、htaccess、DNS)