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

建立ODBC连接后PHP is_readable返回false问题求助

问题:ODBC连接后调用is_readable检测文件可读性失败

运行环境:Windows Server 2012 + IIS + PHP 5.4.45

两段仅调整odbc_connect与is_readable调用顺序的代码出现完全相反的执行结果:

代码1(先检测文件再连ODBC)

<?php
echo get_current_user();
$file_path = "templates\index.tpl";
$test = getcwd() . "\\" .        $file_path;
echo $test."\r\n";

if(is_readable($test)) {
echo ("Readable!\r\n");
} else {
echo ("Not readable!\r\n");
}

odbc_connect("kontaktdb", null, null);
?>

执行结果:返回Readable!

代码2(先连ODBC再检测文件)

<?php
echo get_current_user();
$file_path = "templates\index.tpl";
$test = getcwd() . "\\" .        $file_path;
echo $test."\r\n";

odbc_connect("kontaktdb", null, null);

if(is_readable($test)) {
echo ("Readable!\r\n");
} else {
echo ("Not readable!\r\n");
}
?>

执行结果:返回Not readable!

原因分析

在Windows IIS环境下,PHP默认以应用池身份运行。当调用odbc_connect使用Windows集成身份验证连接数据源时,会触发身份模拟切换——PHP进程的权限上下文会切换到ODBC数据源对应的身份(比如SQL Server服务账户或域账户),导致后续文件访问的权限与之前不一致,原本能读取的文件因新身份无权限而返回false。

解决方案

  • 提前缓存文件可读状态
    在建立ODBC连接前先执行is_readable并缓存结果,后续直接使用缓存值:

    <?php
    echo get_current_user();
    $file_path = "templates\index.tpl";
    $test = getcwd() . "\\" . $file_path;
    echo $test."\r\n";
    
    // 提前检测并存储结果
    $fileIsReadable = is_readable($test);
    
    odbc_connect("kontaktdb", null, null);
    
    if($fileIsReadable) {
        echo ("Readable!\r\n");
    } else {
        echo ("Not readable!\r\n");
    }
    ?>
    
  • 修改ODBC数据源的身份验证方式
    将kontaktdb数据源的身份验证从Windows集成身份改为SQL Server身份验证(指定独立的用户名和密码),避免连接时触发身份切换,保持PHP进程的原权限上下文。

  • 给切换后的身份添加文件读取权限
    找到ODBC连接切换到的目标身份(可通过get_current_user()在连接后输出确认),给templates目录及tpl文件添加该身份的读取权限,确保切换后仍能访问文件。

  • 调整PHP ODBC配置
    检查php.ini中的odbc.allow_persistent、odbc.default_user等配置项,或在odbc_connect调用时显式指定身份参数,强制保持原运行身份,避免自动模拟切换。

内容的提问来源于stack exchange,提问作者H3GE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 09:47:47