能否在mysqli bind_result中绑定类属性?传引用报错原因排查
错误根源说明
你触发的Fatal error: Cannot pass parameter 1 by reference,完全来自bind_result的API用法错误,和你猜测的“bind_param无法处理->解引用”没有关系。
具体错误点拆解
- 你在构造函数里写的
bind_param调用是合规的:$stmt->bind_param('i', $mitgliedsnr)传入的$mitgliedsnr是构造函数形参,属于可引用的实际变量,满足引用传参要求,这部分不会触发报错。 - 报错的直接触发点是这行代码:
MySQLi预处理的$stmt->bind_result('iifiss', $this->id,$this->mitgliedsnr,$this->preis,$this->abbuchungstag,$this->abbuchung_ab,$this->abbuchung_bis);bind_result方法根本不需要传入类型标识字符串:预处理阶段数据库已经完成了结果列的类型校验和解析,调用bind_result时只需要按SELECT语句的列顺序,传入要接收返回值的变量引用即可。你在这里传的第一个参数'iifiss'是字符串字面量,而PHP对需要引用传参的位置强制要求传入可修改的实际变量,不允许传入不可修改的字面量,直接触发了致命错误。 - 修正方式非常简单,删掉多余的类型字符串参数即可:
类属性$stmt->bind_result($this->id, $this->mitgliedsnr, $this->preis, $this->abbuchungstag, $this->abbuchung_ab, $this->abbuchung_bis);$this->xxx本身是满足引用传参要求的,只要传参位置不是字面量就不会触发引用错误,你之前担心的“->解引用的属性无法作为引用传递”的问题实际不存在。
代码中其他会导致逻辑异常的问题
就算修正了上述报错,代码里还有几处会直接影响功能的问题需要处理:
- 魔术方法
__set的低级语法错误- 处理
preis赋值的分支写了$this->preis == floatval($value);,误用了比较运算符==,实际仅做了一次无意义的值比较,完全没有执行赋值操作,应改为赋值运算符=。 - 处理
abbuchung_ab/abbuchung_bis赋值的分支写了$this->key = $value;,这里的key是字符串字面量不是动态变量,实际会把值存到名为key的属性上,根本不会给目标业务属性赋值,应改为$this->$key = $value;。
- 处理
- 保存逻辑没有贯彻预处理的安全初衷
你最初的目标是尽可能使用预处理语句降低安全风险,但save方法还是用sprintf拼接SQL后调用普通query执行,不仅没用到预处理的能力,还会因为拼接时没有对字符串类值做转义引入SQL注入风险,建议替换为预处理的REPLACE语句实现。 - 结果集的边界处理缺失
构造函数直接调用fetch()但没有判断返回值,如果传入的mitgliedsnr没有对应的数据库记录,fetch()会返回false,此时绑定的属性不会被赋值,类属性会保持初始默认值,容易引发后续业务逻辑异常,建议在fetch失败时抛出明确的业务异常。
内容的提问来源于stack exchange,提问作者Alexander Behling
相关产品推荐
相关产品推荐

