PAYATHON 2026

为什么 VS Code 中的 Intelephense 无法识别被包含文件中的 PHP 变量?

排障赵师傅

Intelephense 的提示说明,它未能确认当前作用域中 $con 的定义。只要 sqlcon.php 成功执行,并在包含它的作用域中创建了 $con,PHP 运行时就能使用这个变量。

遇到这类问题,先检查包含路径和项目索引。代码使用了 $_SERVER['DOCUMENT_ROOT'],因此还要检查 Intelephense 的 intelephense.environment.documentRoot 设置。缺少路径配置时,清除缓存也无法解决。

为什么运行正常,编辑器却提示未定义?

PHP 会执行被包含文件,其中的代码继承 include 所在位置的变量作用域。在脚本顶层包含文件,就能使用该文件在顶层定义的变量;在函数内部包含,变量则属于该函数的作用域。参见 PHP 的 include 文档。

Intelephense 依靠静态分析理解代码,不会执行 PHP 请求来获取 Web 服务器的实际配置。原代码分两步计算包含路径:

$root = $_SERVER['DOCUMENT_ROOT'];
include($root . '/sqlcon.php');

如果扩展无法确定文档根目录,或无法完整追踪这段路径表达式,就可能无法识别当前文件使用的变量来自 sqlcon.php。

“以前正常,最近才出现”也可能与扩展更新后的诊断行为有关。不过,要判断是否为某个版本的缺陷,还需要更新前后的版本号和最小复现。

先配置文档根目录,再检查索引

在项目的 .vscode/settings.json 中设置文档根目录。假设站点根目录是 /Users/you/Sites/example:

{
  "intelephense.environment.documentRoot": "/Users/you/Sites/example"
}

将示例路径替换为实际目录,不要填成 index.php 或 sqlcon.php 的文件路径。使用 SSH、容器等远程开发环境时,要填写语言服务器所在环境能访问的路径。这个设置用于解析脚本包含路径,具体定义见 Intelephense 配置说明。

接着检查项目索引:

  • 在 VS Code 中打开完整项目文件夹,确保 sqlcon.php 位于可索引的项目范围内。
  • 检查 intelephense.files.exclude 是否排除了连接文件所在目录。
  • 如果文件位于工作区外,可按需配置 intelephense.environment.includePaths。这个设置不会让所有文件中的变量自动变成全局变量,参见 Intelephense 文档。

配置完成后,重新加载 VS Code 窗口,等待索引完成,再查看提示是否仍然存在。

路径固定时,可以改用 __DIR__

如果当前脚本与 sqlcon.php 位于同一目录,可以写成:

require __DIR__ . '/sqlcon.php';

$gettextquery = mysqli_query(
    $con,
    "SELECT * FROM `pics` WHERE ai_cats = ''"
);

__DIR__ 表示当前 PHP 文件所在目录,能更明确地表达路径关系,也不依赖 Web 服务器提供 DOCUMENT_ROOT。

两个文件不在同一目录时,需要按实际目录结构调整路径。这里改用 require,是因为数据库连接文件缺失时通常应停止执行。单纯将 include 换成 require,并不能保证消除静态分析提示。

需要更明确的变量来源时,使用带返回类型的函数

如果项目中多处依赖连接文件创建 $con,可以将创建连接的代码放进函数,再在调用处显式赋值。

sqlcon.php:

<?php

function createDatabaseConnection(): \mysqli
{
    return new \mysqli(
        'DB_HOST',
        'DB_USER',
        'DB_PASSWORD',
        'DB_NAME'
    );
}

调用文件:

<?php

require_once __DIR__ . '/sqlcon.php';

$con = createDatabaseConnection();

$gettextquery = mysqli_query(
    $con,
    "SELECT * FROM `pics` WHERE ai_cats = ''"
);

连接参数都是占位值,需要替换为项目配置。原有的连接错误处理、字符集设置等逻辑也应保留在函数中。

这样,编辑器可以通过当前文件中的赋值语句和函数的返回类型分析 $con。

确认是误报后,才调整诊断设置

部分版本支持仅检查局部作用域中的未定义变量:

{
  "intelephense.diagnostics.undefinedVariables": "local"
}

在支持该枚举配置的版本中,"on" 检查全局和局部作用域,"local" 只检查局部作用域,"off" 关闭这项检查。旧版本的配置类型可能不同,请以已安装扩展的设置提示为准。相关行为和配置变化见 项目维护者的说明。

设为 "local" 也会隐藏脚本顶层真正的未定义变量问题。调整前,应先确认包含路径正确、连接文件确实执行,且 $con 已在查询前创建。

不要仅为消除提示而添加 global $con;。它用于在函数内访问全局变量,不能代替文件加载或数据库连接初始化。

备注:内容仅供参考。