从Windows迁移至Linux(SQL Server)PHP类与PDO空属性访问致命错误
解决PHP访问SQL Server时的"Cannot access empty property"错误
先直接搞定触发错误的核心问题,再聊聊迁移到Linux后的其他注意事项:
1. 语法错误导致的属性访问失败
你在exereq函数里写的$this->$db是错误写法!这里的$db是你的类属性,正确访问类属性应该用$this->db(不需要额外加$符号),$this->$db是PHP里的「变量变量」语法,会把$db的值当作属性名去访问,而此时$db在这个函数作用域里是空的,所以才会报“Cannot access empty property”。
修改后的exereq函数应该是这样:
function exereq($requete) { // 修正属性访问语法,同时把Exec改成小写的exec(符合规范写法) // 另外errorInfo()返回数组,用implode转成可读字符串 $resultat = $this->db->exec($requete) or die("Erreur lors de l'execution de la requête : <br>".$requete."<br>".implode(", ", $this->db->errorInfo())); if(!$resultat) { $this->message("Problème lors de l'execution de la requête : <br>".$requete."<br>".implode(", ", $this->db->errorInfo())); } return $resultat; }
2. 迁移到Linux后的额外注意事项
从Windows迁到Linux,还有几个容易踩的坑:
- 确认dblib驱动已安装:
Linux下PHP连接SQL Server需要依赖dblib驱动,你得确保服务器上装了对应的扩展(比如Debian/Ubuntu是php-sybase,CentOS/RHEL是php-mssql),并且freetds配置正确。可以通过执行php -m | grep dblib检查驱动是否加载成功。 - 紧急修复SQL注入漏洞:
你现在直接把$_GET['ORDER_ID']拼进SQL语句里,这是严重的安全问题!必须改用PDO的预处理语句,既安全又能避免SQL语法错误:// 调用处改成这样 if(isset($_GET['ORDER_ID']) && $_GET['ORDER_ID'] != '') { $select_order = "SELECT ORDER_NUMBER FROM EP_ORDER WHERE EP_ORDER.ORDER_ID = ?"; $stmt = $bd->db->prepare($select_order); $stmt->execute([$_GET['ORDER_ID']]); // 如果只取一条结果用fetch(),多条用fetchAll() $res_select_order = $stmt->fetch(PDO::FETCH_ASSOC); } - 升级类的写法到现代PHP标准:
你的类用了PHP4的老写法(var声明属性、以类名作为构造函数),建议改成PHP5+的标准写法,兼容性和可读性更好:class BD { // 用访问修饰符代替var,比如private private $connexion, $connectBase, $db; // 用__construct作为构造函数 public function __construct() { if(file_exists("config/config.inc.php")) include("config/config.inc.php"); elseif(file_exists("../config/config.inc.php")) include("../config/config.inc.php"); // 加上异常捕获,方便排查连接问题 try { $db=new PDO("dblib:host=servername;dbname=dbname", 'login', 'pass'); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->db = $db; } catch(PDOException $e) { die("数据库连接失败:".$e->getMessage()); } } }
3. 调试小技巧
如果修改后还是有问题,建议在构造函数里开启PDO的异常模式(上面代码里已经加了),这样连接或者执行SQL出错时会抛出具体的异常信息,比errorInfo()更直观,方便你定位Linux环境下的连接问题。
内容的提问来源于stack exchange,提问作者talou
相关产品推荐
相关产品推荐

