【问题标题】:php relative paths and directoriesphp相对路径和目录
【发布时间】:2011-12-11 23:26:10
【问题描述】:

我想知道一些事情,但我似乎找不到一个好的、明确的答案,甚至找不到这个问题的解决方案:

我的 PHP 网站结构如下:

root
   functions
   generators
   helpers
   scripts
   style
   index.php

这些都是文件夹和一个 php 文件。 Functions 包含一堆与数据库连接和各种其他数据库操作(如插入、删除、更新等)相关的 op php 文件。生成器包含自动生成网页的类,以使它们看起来都一样。助手是处理登录、注销、注册等的类。脚本是 javascript,样式是 CSS。

在我的 generators 文件夹中,有一个文件 mainGenerator.php,它会生成网站的各个部分:

 private function generateLogin()
    {
        if (!isLoggedIn()) {
            echo "
                <h2>Login</h2>
                <form method='post' action='../helpers/login.php' id='loginForm'>
                <p>
                Username:<br/>
                <input class='search' type='text' name='username'/>
                Password:<br/>
                <input class='search' type='password' name='password'/>
                <input name='login' type='image' style='border: 0; margin: 0 0 -9px 5px;' src='style/login.png' alt='Login' title='Login'/><br/>
                No account yet? <a href='../register.php'>Register</a>
                </p></form>";
        } else {
            echo "
                <h2>Welome, <a href='user.php' style='color: #1293EE;'>" .
                 $_SESSION['user_name'] .
                 "</a></h2>
                <a href='logout.php'>Log off</a>";
        }
    }

这段代码在每个页面上生成登录框,或者如果用户已经登录,则显示欢迎消息。如您所见,该操作引用“../helpers/login.php”,因为那是从这个生成器的角度来看 loginhelper 的相对位置。

现在,问题来了:如果我按下 index.php (http://example.com/ProjectName/index.php) 上的登录按钮,它会将我重定向到 http://example.com/helpers/login.php 并说找不到文件。

我知道问题出在哪里了,post 操作看到来自 index.php 的请求,然后上一个目录,然后查找 /helpers/login.php,这当然不存在。

解决方法可能是将操作更改为

action='/helpers/login.php'

但是,如果我需要从某个子目录中访问 generateLogin(),这会给我同样的问题... 如何解决这个特定问题,即:对 /helpers/login.php 的引用保持正确,无论我尝试从何处访问它。

【问题讨论】:

    标签: php relative-path directory


    【解决方案1】:
    action='/ProjectName/helpers/login.php'
    

    假设您的根是http://localhost,那么无论是从http://localhost/ProjectName/index.php 还是http://localhost/ProjectName/subdir/index.php 调用,上述链接都应始终解析为http://localhost/ProjectName/helpers/login.php

    如果您不想将“ProjectName”硬编码到许多不同的脚本中,您可以使用全局变量并在配置文件中定义它:

    helpers/ConfigOptions.php:

    <?php
    $ProjectName = "ProjectName";
    ?>
    

    然后在您的脚本中,包含配置文件并使用您定义的变量:

    index.php:

    include $_SERVER['DOCUMENT_ROOT'] . '/helpers/ConfigOptions.php';
    
    ...
    
    echo "
      <form action='/$ProjectName/helpers/login.php'>
      ....
    ";
    

    更多关于 DOCUMENT_ROOT:

    DOCUMENT_ROOT 在服务器配置文件中定义,是执行脚本的文件系统的根目录,不是您在浏览器中输入的网址.在上面的示例中,我假设文档根目录类似于 /home/user/www/ProjectName。如果 DOCUMENT_ROOT 只是 /home/user/www 那么您可以将包含路径更改为:

    include $_SERVER['DOCUMENT_ROOT'] . '/ProjectName/helpers/ConfigOptions.php';
    

    或使用相对路径。我的投票是后者,因为您不需要硬编码“ProjectName”。

    因此 include() 和 require() 将采用:

    1. 文件的绝对路径
    2. 相对于当前执行脚本的路径。如果 A 包含 B,B 包含 C,则当 B 包含 C 时,需要提供 相对于 A的路径。

    那么什么时候需要使用 DOCUMENT_ROOT?通常在模板中,像../helpers/file.php 这样的相对 路径可以解析为不同的绝对 路径,具体取决于包含文件的内容。在上面 index.php 包含 ConfigOptions.php 的示例中,您可能不需要使用 DOCUMENT_ROOT,因为 index.php 不是模板。为了安全起见,我还是使用了它,但也许我在这里打开了一整罐蠕虫。我希望我没有让你更加困惑。

    【讨论】:

    • 如果我错了,请纠正我,但这不适用于要求,对吧?像这样:包括 $_SERVER['DOCUMENT_ROOT'] 。 '/MyProject/helpers/ConfigOptions.php'; require_once($ProjectName . '/functions/account_fns.php')
    • 没关系,因为 include() 和 require() 都采用文件的相对或绝对路径。我用有关 DOCUMENT_ROOT 的更多信息更新了我的答案。
    【解决方案2】:

    如果您有一个以斜杠开头的链接,它总是会附加到根目录而不是当前目录...

    因此,如果您的页面是 www.example.com/mySite/foo.html 并且您有这样的链接:&lt;a href="/bar.html"&gt;Bar/&lt;a&gt; 用户将被重定向到 www.example.com/bar.html ...

    您应该将表单操作指向helpers/login.php

    【讨论】:

    • helpers/login.php 仅适用于顶级目录。
    • 感谢有关斜线的信息。为此点赞!
    猜你喜欢
    • 2012-12-06
    • 2011-04-29
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多