【问题标题】:Problem with require() when using a fully qualified URL使用完全限定 URL 时出现 require() 的问题
【发布时间】:2011-05-08 20:22:41
【问题描述】:

所以,我的代码使用了相对路径,但遇到了一些常见文件的问题,这些文件可能被不同目录级别包含/需要。

无论如何,绝对路径更有效,对吧?因此,我使用require_once('http://' . $_SERVER['HTTP_HOST'] . 'file_name.php'); 将所有包含/要求更改为绝对路径

$_SERVER['HTTP_HOST'] 是正确的,不是吗?当我用谷歌搜索时,似乎是这样。

这需要我在 php.ini 中设置“allow_url_include=on”并重新启动 Apache。

所以,现在我的情况看起来像这样(简化示例):

File2.php 包含

<?php
   function hello()
   {
     echo 'hello<br>';
   }
?>

如果 file1.php 包含

<?php
   require_once('file2.php');    
   hello();
?>

然后我会看到预期的输出“hello”,但是如果我将该行更改为

   require_once('http://' . $_SERVER['HTTP_HOST'] . '/file2.php');

然后我得到“致命错误:调用 C:\xampp\htdocs\file1.php 中未定义的函数 hello()”

(我猜c:\xammp\httdos的引用来自Xdebug,因为PhpInfo显示HTTP_HOST localhost)

无论如何,这是一个很长的帖子,说我遗漏了一些简单的点并询问它是什么。

【问题讨论】:

  • 我什至没有阅读整个问题,但要求远程文件总是一个坏主意。
  • 顺便说一句,echo file_get_contents('http://' . $_SERVER['HTTP_HOST'] . '/file2.php'); 得到什么?
  • @Mawg:用 FQU 包含文件而不是本地路径的原因是什么?
  • @Mawg:实际上并非如此。通常的做法是定义一个具有应用程序根目录绝对路径的常量,并根据该基本常量组合路径。即: require_once BASE_PATH 。 'path/to/concrete/file.php;`
  • @Mawg:该常量应该在某种“config”/“bootstrap”/“index”文件中只定义一次,无论您拥有并在其他所有文件中使用。

标签: php


【解决方案1】:

当您require 一个完整的 URL 时,PHP 向服务器发出请求并取回 PHP 脚本的 输出 - 这不会包含任何实际的 PHP 代码(除非脚本本身输出PHP 代码)。

此外,您不会看到使用相对路径和绝对路径之间的性能有任何明显差异,因此不必太担心。实际上,您的路径不是绝对路径而是绝对 URI,而获取 URI 实际上会比使用本地路径慢方式

【讨论】:

  • +1 你是对的。所以。包含使用绝对路径的正确方法是什么?谢谢
  • @Mawg:正确的方法是include你的文件,而不是require
  • @Mawg:使用$_SERVER['DOCUMENT_ROOT'] . '/path/to/file'
  • @casablanca:嗯?您从哪里得到“需要库等很好,但包含模板或其他可以在同一页面中重复的内容”?
  • @zerkms 不同之处在于它们处理错误的方式。失败的require 将引发致命错误,停止所有其他执行。失败的include 将引发警告,但会继续执行。
【解决方案2】:

require_once 需要服务器上的路径而不是 URL。例如,你不能通过http://www.foo.com/test.php,但你可以通过/var/www/foo/test.php。如果你输入 http:// 路径,那么它只会包含输出而不包含 php 函数。

【讨论】:

  • +1 那么,你说的是 $_SERVER['DOCUMENT_ROOT'],而不是 $_SERVER['HTTP_HOST'] ?或者是其他东西?你如何包括使用绝对路径?谢谢
  • 正确,您可以使用 DOCUMENT_ROOT。但是,如果您的文件位于 www/test.php 中并且您想要包含 other.php,那么只需执行 require_once(other.php)。这条路径作为相对路径比绝对路径更好。
  • 请注意它的相对位置。 PHP 中的所有相对路径都相对于include_path。这可能包括也可能不包括 CWD .
  • 因确认 $_SERVER['DOCUMENT_ROOT'] 而获得的答案
【解决方案3】:

绝对意味着相对于文件系统。当您使用 http://... 时,您正在使用 url 包含,但当您使用 file2.php 时,您正在使用普通包含。要使用真正的绝对路径,请使用require_once('/xampp/htdocs/file2.php');

【讨论】:

  • +1 小屋我不想使用 /xampp/htdocs/ (可能是 $_SERVER['DOCUMENT_ROOT'] ?)
  • 使用set_include_path()设置一个已知的绝对路径。您可以通过配置进行设置,也可以使用realpath(dirname(__FILE__)) 之类的方式进行设置
  • +1 我想这会起作用,但它的效率有点低(并且从代码中不再清楚在开发时在哪里查找包含文件)
  • 一种常见的模式是使用require_once(dirname(__FILE__).'/relative/path/to/file1.php')。这样可以确保无论您从何处包含文件,其包含仍然有效。
  • @theazureshadow 很棒的简短解决方案!
【解决方案4】:

当您在 PHP 中 requireinclude 文件时,该文件会从本地文件系统合并到当前脚本中,除非文件路径包含诸如 HTTP 之类的架构,那么它将被 fopen 之一包含包装纸。见http://www.php.net/manual/en/function.include.php

PHP 根据某些因素确定文件的完整路径。

绝对路径(一个以DIRECTORY_SEPARATOR 开头(例如/)或标识的驱动器号(例如C:\)对于Windows 服务器)是最快的,因为无需进行转换。该文件只是从给定位置合并进来的。

然而,相对路径比大多数人想象的要复杂得多。

PHP 将在 include_path 堆栈 (FIFO) 中搜索相对路径。这是一个以PATH_SEPARATOR (;) 分隔的字符串,包含一个或多个“基本”路径。

一个示例包含路径是

/usr/share/pear;.

这包含两个路径,/usr/share/pear.,当前工作目录 (CWD)。

如果您专门设置包含路径并删除任何不相关的内容,您将在应用程序中获得最佳性能。例如,假设您所有的“可包含”文件都驻留在/home/me/www/appname/includes 中,最好的办法是在您的引导程序/通用脚本中设置它,例如

set_include_path('/home/me/www/appname/includes');

现在任何相关的包含调用都只会从这个位置获取。

如果您需要设置多个路径,我发现这样的方法效果很好

set_include_path(implode(PATH_SEPARATOR, array(
    '/include/path/one',
    '/include/path/two'
)));

如果你想修改服务器包含路径,我建议以相同的方式添加它,但将它放在堆栈的底部,例如

set_include_path(implode(PATH_SEPARATOR, array(
    '/include/path/one',
    '/include/path/two',
    get_include_path()
)));

恕我直言,您可以做的最好的事情之一就是从包含路径中删除 CWD,因为它往往是“包含路径地狱”的最大来源之一。如果您确实需要包含与当前文件相关的文件,请使用

require_once realpath(dirname(__FILE__)) . '/relative/path/to/file.php';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 2015-12-16
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 2016-01-26
    • 2020-07-20
    • 1970-01-01
    相关资源
    最近更新 更多