【问题标题】:Loading a file in PHP without knowing the underlying file system在不知道底层文件系统的情况下在 PHP 中加载文件
【发布时间】:2010-10-05 22:41:13
【问题描述】:

关于 PHP 的一个 ncie 事情是,如果您执行包含/要求,它会在文件所在的目录(或者更确切地说是请求的 URI)上工作。这意味着如果您想包含更多文件,您不需要知道原始脚本的运行位置。您只需要知道当前脚本在哪里。

现在我想加载一个文本文件并对其进行处理。 file_get_contents() 似乎是一种明显的加载方式。问题是我没有同样的奢侈。我要么需要绝对指定文件路径,我不想这样做,要么我必须知道相对于发起调用的文件的位置,这我也不喜欢。

Require/include 似乎不适用于非 PHP 文件,并且无论如何都会回显内容(是的,我知道我可以将其包装在 ob_start() 等中)。

建议?

【问题讨论】:

    标签: php


    【解决方案1】:

    您可以使用获取与当前文件关联的目录

    dirname(__FILE__)
    

    所以你可以这样做:

    file_get_contents(dirname(__FILE__) . '/foo.txt')
    

    【讨论】:

      【解决方案2】:

      使用您想要的文件路径定义一个常量,无论您通常将配置设置放在哪里。保持简单和可定制。

      【讨论】:

        【解决方案3】:

        首先,请注意“相对路径”将来自当前正在运行的第一个 php 脚本的路径(无论什么文件可能正在执行“包含”)。无法指定相对路径听起来很奇怪...

        【讨论】:

        • 这就是我所指的问题:要求/包含使用当前脚本的位置(有用)。 file_*() 方法使用原始脚本的位置。这就是我想要一个优雅的解决方案。
        【解决方案4】:

        如果我正确理解了file_get_contents 的文档,您可以将true 作为第二个参数传递,然后将使用include_path。所以,在我的系统上

        echo file_get_contents('doc/DB/doc/STATUS', true);
        

        将从我的 PEAR 模块中回显 STATUS 文档,因为 /usr/share/pear 在我的 include_path 中。虽然我们在这里,但我不相信 include() 或 require() 将在相对路径上工作,除非'.'是 include_path 的一部分。我会检查一下。

        更新:好的,我检查过了。事实证明,无论 include_path 说什么,include() 都会始终考虑当前目录。

        【讨论】:

        • 根据您链接到的文档,第二个参数是一堆常量(标志是 FILE_USE_INCLUDE_PATH、FILE_TEXT 和 FILE_BINARY)。当然,其中两个标志是互斥的......
        • 好吧,我简化了一点:第二个参数 will 在 PHP 6 中是“一堆常量”,但我假设 cletus 使用的是 PHP 5 max。第二个 arg 是/曾经是 PHP 5 的布尔值(包括 PHP 5)。
        【解决方案5】:

        必须知道事物的路径在网站世界中很常见。您可以存储路径的一部分,例如配置变量中的开头,例如 $config['include_dir'];指定文件的路径很简单 include($_SERVER['DOCUMENT_ROOT'] . '/includes/myinclude.inc.php');

        我不知道你怎么知道要包含什么文件。

        【讨论】:

        • 在 Java 中这不是问题,因为您可以通过类加载器加载资源,或者在 Web 应用程序中作为资源加载。我希望有一些比常量甚至文档根更优雅的东西(这似乎是迄今为止最好的)。例如,文件分隔符区分 Linux 和 Windows。
        【解决方案6】:

        您将需要绝对路径才能打开文件。您可以使用 realpath() 将相对 url 路径转换为绝对路径。

        【讨论】:

        • URL 和文件系统路径不相同。
        • 是的,我知道这一点。使用 realpath() 应该返回给定 URL 路径的绝对文件系统路径(除非我误解了文档......现在无法使用 php)。
        • URL 路径和文件系统路径不一样!它们可以相同(相对于 DOCUMENT_ROOT),但它们不必相同(请参阅 URL 重写)。并且 realpath() 只返回文件系统中有效路径的绝对路径,否则返回 false。
        • 好的。我很清楚 URL 路径和文件系统路径是不一样的。我的错误是误解了 realpath() fcn(我认为它等同于 Server.MapPath)。感谢您的澄清。
        【解决方案7】:

        查看 $_SERVER 属性。 http://us2.php.net/manual/en/reserved.variables.server.php

        你想要的

        $_SERVER['DOCUMENT_ROOT'];
        

        【讨论】:

          【解决方案8】:

          require/include 正在从两个路径中解析绝对路径,当前脚本文件和初始执行的脚本文件:

          首先在相对于当前工作目录的每个include_path 条目中查找要包含的文件,然后在当前脚本的目录中查找。例如。如果您的include_path 是库,则当前工作目录为/www/,您包含include/a.php 并且该文件中有include "b.php"b.php 首先在/www/libraries/ 中查找,然后在/www/include/ 中查找。如果filename./../ 开头,则仅在当前工作目录中查找。 ——http://docs.php.net/include

          但是使用绝对路径更好,所以 PHP 不需要“猜测”是指哪个文件。

          【讨论】:

            【解决方案9】:

            我不知道您是否可以控制要加载的文件的内容,但如果可以,您可以尝试使用 smarty 模板引擎 (http://www.smarty.net/)

            您需要将 '{include file="relative/file/path.ext"}' 放入您尝试加载的文件中,但 smarty 至少会处理所有相对路径让你感到困惑。

            PS:包含标签的文档在这里:http://www.smarty.net/manual/en/language.function.include.php

            【讨论】:

              【解决方案10】:

              要回答您的问题,在我看来,您需要编写自己的包含等效项,以从任意数量的可能路径返回文件内容。在数组中配置一系列路径并让你的函数循环遍历它,如果找到文件,则使用 file_exists() 并加载文件内容。

              文件系统功能: http://us2.php.net/manual/en/ref.filesystem.php#73954

              另请注意,文件系统路径分隔符有 php 常量,例如: DIRECTORY_SEPARATOR ,但是对于可移植文件路径,您并不需要它,因为正斜杠“/”适用于 Windows。

              Ps:Symfony 中常用的获取绝对路径的技巧是:

              $path = realpath(dirname(__FILE__)).'/whatever.txt';
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-04-26
                • 2017-10-13
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-08-10
                相关资源
                最近更新 更多