PHP中无法从非静态Book类调用Comment类静态函数问题
问题:静态方法调用失败,实例化调用成功的原因
我尝试解决这个问题超过12小时仍未成功,十分困扰。我有Book和Comment两个类,一个Book对应多条Comment,想要获取指定Book及其关联的Comment。在Book类的非静态方法中调用Comment类的GetCommentByBookId静态函数时失败,但将该函数改为非静态并实例化Comment类调用却能成功,相关代码如下:
Book类
<?php require_once ("class/DBController.php"); require_once ("class/Comment.php"); class Book { private $db_handle; function __construct() { $this->db_handle = new DBController(); } function GetBookById($id) { $query = "SELECT * FROM book WHERE id = ?"; $paramType = "i"; $paramValue = array( $id ); $c = new comment; $result = $c->getCommentByBookId(1); //$result = Comment::GetCommentByBookId($id); return $result; } function GetAllBooks() { $query = "SELECT * FROM book"; $result = $this->db_handle->runBaseQuery($query); return $result; } } ?>
Comment类
<?php require_once ("class/DBController.php"); class Comment { private $db_handle; function __construct() { $this->db_handle = new DBController(); } static function GetCommentByBookId($id) { echo "Entered 'GetCommentByBookId'<br>"; $query = "SELECT * FROM comment WHERE book_id = ?"; $paramType = "i"; $paramValue = array( $id ); echo "Pre-Ex 'GetCommentByBookId'<br>"; $result = $this->db_handle->runQuery($query, $paramType, $paramValue); echo "Executed successfully 'GetCommentByBookId'<br>"; return $result; } } ?>
原因分析与解决方法
核心原因
静态方法属于类本身,不属于任何具体的实例对象,因此静态方法内不能使用$this关键字访问类的非静态成员变量。
在你的Comment类静态方法GetCommentByBookId中,尝试用$this->db_handle调用数据库操作,但$db_handle是类的非静态私有成员,仅在实例化对象时由构造函数初始化。静态方法执行时没有实例上下文,$this不存在,自然无法访问$db_handle,导致调用失败。
而当你实例化Comment类后调用非静态方法时,$this指向当前创建的实例,此时构造函数已经完成$db_handle的初始化,所以能正常执行数据库操作。
解决方法
方法1:将数据库连接改为静态成员
把db_handle改为静态变量,在静态方法中通过self::$db_handle访问,同时确保只初始化一次:
class Comment { private static $db_handle; function __construct() { // 仅在静态连接未初始化时创建实例 if (!self::$db_handle) { self::$db_handle = new DBController(); } } static function GetCommentByBookId($id) { echo "Entered 'GetCommentByBookId'<br>"; $query = "SELECT * FROM comment WHERE book_id = ?"; $paramType = "i"; $paramValue = array( $id ); echo "Pre-Ex 'GetCommentByBookId'<br>"; // 使用self访问静态成员 $result = self::$db_handle->runQuery($query, $paramType, $paramValue); echo "Executed successfully 'GetCommentByBookId'<br>"; return $result; } }
方法2:保持方法为非静态(已验证可行)
继续使用实例化对象调用非静态方法的方式,也就是你当前成功的写法:
$c = new Comment; $result = $c->getCommentByBookId($id);
内容的提问来源于stack exchange,提问作者STORM
相关产品推荐
相关产品推荐

