【问题标题】:What is php's include order?什么是 php 的包含顺序?
【发布时间】:2019-03-07 15:09:13
【问题描述】:

根据 PHP 的文档,我预计以下文件层次结构

.
├── autoload.php
└── etc
    └── php-lib
        ├── autoload.php
        └── common.php

2 directories, 3 files

及以下内容:

cat autoload.php 
<?php
echo "I am the wrong autoloader";

cat etc/php-lib/autoload.php 
<?php
echo "This is the right one!";

cat etc/php-lib/common.php  
<?php

include_once('autoload.php');

当我跑步时

$ php etc/php-lib/common.php

我会得到以下输出:

This is the right one!

我希望这是因为手册指出:

Files are included based on the file path given or, if none is given, the
include_path specified. If the file isn't found in the include_path, 
include will finally check in the calling script's own directory and the 
current working directory before failing. The include construct will emit 
a warning if it cannot find a file; this is different behavior from 
require, which will emit a fatal error. 

但是,我明白了:

I am the wrong autoloader

那么为什么加载的是autoload.php 而不是etc/php-lib/autoload.php

事实上,当我 strace 时,包含顺序似乎比手册预期的更奇怪:

第一种情况,上面描述的所有文件都存在

getcwd("/home/hvdb/temp2", 4096)        = 17
lstat("/home/hvdb/temp2/./autoload.php", {st_mode=S_IFREG|0644, st_size=40, ...}) = 0
lstat("/home/hvdb/temp2/autoload.php", {st_mode=S_IFREG|0644, st_size=40, ...}) = 0
openat(AT_FDCWD, "/home/hvdb/temp2/autoload.php", O_RDONLY) = 3

我们看到 PHP 首先在 cwd 中查找 autoload.php

如果我删除该文件,即./autoload.php,我会得到以下信息:

getcwd("/home/hvdb/temp2", 4096)        = 17
lstat("/home/hvdb/temp2/./autoload.php", 0x7fff7f04e880) = -1 ENOENT (No such file or directory)
lstat("/usr/share/php/autoload.php", 0x7fff7f04e880) = -1 ENOENT (No such file or directory)
lstat("/home/hvdb/temp2/etc/php-lib/autoload.php", {st_mode=S_IFREG|0644, st_size=38, ...}) = 0

只有这样我才能看到 PHP(仍然首先检查 cwd 中的 autoload.php)在 include_directories 中设置的目录,然后在调用脚本的目录中看到 autoloader.php

那么,是文档有误,还是我误解了手册?

【问题讨论】:

  • 我猜你的 include_path 以. 开头
  • echo get_include_path() 显示什么?
  • php -d include_path='' etc/php-lib/common.php
  • 文档的相关部分是Files are included based on [...] the include_path specified
  • @ChrisLear 是对的。很可能您已经在 php.ini 文件中设置了 include_path。我自己在这里测试了你的代码,我得到了正确的代码,没有任何问题。

标签: php include


【解决方案1】:

从 cmets 来看,问题在于您已将 php.ini 文件中的 include_path 设置为默认设置。在你的情况下.

这就是为什么最好在你的脚本中有一个配置文件,你可以在其中创建一个像这样的常量:

PHP >= 5.3.0

define("PATH", __DIR__);

PHP

define("PATH", dirname(__FILE__));

这将使您能够控制要从当前工作目录中包含的文件,并确保您的脚本仍然可以在您可能无法控制 PHP 配置的不同环境中工作。

【讨论】:

  • 您的最后一段并不是 OP 的 cmets 中讨论的真正替代方案。请删除,以便我接受这个答案。
  • @hbogert 已将其删除。尽管我确实相信这对于将来访问此问题的其他用户来说会是很好的信息:)
  • 假设所有的 include/require 语句都应该由 composer 或 PSR-4 之类的东西来完成。这要么是相当固执,要么根本不适用。
猜你喜欢
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
  • 1970-01-01
  • 2019-06-28
  • 1970-01-01
  • 2012-12-15
  • 2012-01-11
相关资源
最近更新 更多