You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PHP程序判断文件位于本地还是网络文件系统?

判断文件所在文件系统类型(本地/网络)的PHP实现

针对你的需求(检测SQLite3数据库文件是否位于网络文件系统并发出警告),可以通过调用系统原生命令的方式实现,因为PHP没有直接封装statfs这类系统调用。以下是分平台的简洁实现:

一、类Unix系统(Linux、macOS、FreeBSD)

这类系统可以通过stat命令直接获取文件系统类型,再判断是否属于网络文件系统范畴(如nfs、smb/cifs、smbfs等)。

实现代码

function isNetworkFilesystem(string $filePath): bool {
    // 先检查文件是否存在
    if (!file_exists($filePath)) {
        throw new \InvalidArgumentException("文件不存在:$filePath");
    }

    // 转为绝对路径避免相对路径问题
    $absPath = realpath($filePath);
    if (!$absPath) {
        return false;
    }

    $os = strtolower(PHP_OS);
    $fsType = '';

    // 执行对应系统的stat命令
    if (str_contains($os, 'linux')) {
        // Linux: stat -f -c %T 返回文件系统类型(如ext4、nfs、cifs)
        exec("stat -f -c %T '$absPath'", $output, $exitCode);
    } elseif (str_contains($os, 'darwin') || str_contains($os, 'freebsd')) {
        // macOS/FreeBSD: stat -f %T 返回文件系统类型(如apfs、smbfs、nfs)
        exec("stat -f %T '$absPath'", $output, $exitCode);
    } else {
        // 未支持的类Unix系统默认返回false
        return false;
    }

    if ($exitCode !== 0 || empty($output)) {
        return false;
    }

    $fsType = trim($output[0]);
    // 定义常见网络文件系统类型列表
    $networkFsTypes = ['nfs', 'cifs', 'smbfs', 'nfs4', 'cifs4', 'smb'];
    return in_array(strtolower($fsType), $networkFsTypes);
}

二、Windows系统

Windows可以通过fsutil命令获取卷信息,判断文件所在驱动器是否为网络共享卷。

实现代码

function isNetworkFilesystemWindows(string $filePath): bool {
    if (!file_exists($filePath)) {
        throw new \InvalidArgumentException("文件不存在:$filePath");
    }

    $absPath = realpath($filePath);
    if (!$absPath) {
        return false;
    }

    // 提取驱动器盘符(如C:\ -> C:)
    $drive = substr($absPath, 0, 2);
    // 执行fsutil命令获取卷信息
    exec("fsutil fsinfo volumeinfo $drive", $output, $exitCode);

    if ($exitCode !== 0 || empty($output)) {
        return false;
    }

    // 检查输出中是否包含"Remote Volume"标识
    foreach ($output as $line) {
        if (stripos($line, 'Remote Volume') !== false) {
            return true;
        }
    }

    return false;
}

三、跨平台整合函数

将两类系统的逻辑合并,自动识别操作系统:

function isNetworkFilesystem(string $filePath): bool {
    if (!file_exists($filePath)) {
        throw new \InvalidArgumentException("文件不存在:$filePath");
    }

    $absPath = realpath($filePath);
    if (!$absPath) {
        return false;
    }

    $os = strtolower(PHP_OS);
    if (str_contains($os, 'win')) {
        return isNetworkFilesystemWindows($absPath);
    } else {
        // 类Unix系统逻辑
        $fsType = '';
        if (str_contains($os, 'linux')) {
            exec("stat -f -c %T '$absPath'", $output, $exitCode);
        } elseif (str_contains($os, 'darwin') || str_contains($os, 'freebsd')) {
            exec("stat -f %T '$absPath'", $output, $exitCode);
        } else {
            return false;
        }

        if ($exitCode !== 0 || empty($output)) {
            return false;
        }

        $fsType = trim($output[0]);
        $networkFsTypes = ['nfs', 'cifs', 'smbfs', 'nfs4', 'cifs4', 'smb'];
        return in_array(strtolower($fsType), $networkFsTypes);
    }
}

四、SQLite3场景使用示例

$dbPath = '/path/to/your/database.sqlite';

if (isNetworkFilesystem($dbPath)) {
    trigger_error('警告:SQLite3数据库位于网络文件系统上,可能会出现性能或稳定性问题!', E_USER_WARNING);
}

// 继续初始化SQLite3连接
$db = new SQLite3($dbPath);

注意事项

  1. 权限要求:PHP进程需要具备执行exec命令的权限,确保disable_functions中未禁用相关函数。
  2. 命令兼容性:不同发行版的stat参数可能略有差异,可根据实际环境调整。
  3. 误判风险:小众网络文件系统可能不在预设列表中,可按需扩展$networkFsTypes数组。

内容的提问来源于stack exchange,提问作者O. Jones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:05:43