我开始使用PHP类并研究OOP。
我创建了一个数据库类,看起来像这样(片段):
class Database
{
private $link;
private $result;
private $count;
function connect()
{
$this->link = mysql_connect(DB_HOST, DB_USER, DB_PW);
$return = $this->link ? 'Connected to database.' : 'Failed to connect.';
$this->open(); // I have another function in this class to select the db
echo $return;
}
function query($query)
{
$this->result = mysql_query($query);
}
function fetch()
{
return mysql_fetch_assoc($this->result);
}
function count()
{
$this->count = mysql_num_rows($this->result);
return $this->count;
}
}
为了测试,我创建了另一个名为Guestbook的类,它看起来像这样:
class Guestbook
{
function fetch()
{
Database::query('SELECT * FROM guestbook LIMIT 2');
while($row = Database::fetch()){
$result_array[] = $row;
return $result_array;
}
}
现在我测试了调用函数:
$db = new Database();
$db->connect();
$db->query('SELECT * FROM test');
while($row = $db->fetch()) {
echo $row['id'].'<br />';
}
echo $db->count();
$db->close();
这是意料之中的事。所以我继续上了留言簿课程:
$db->connect();
$guestbook = new Guestbook();
$results = $guestbook->fetch();
foreach($results as $gb) {
echo $gb['id'];
}
echo $db->count(); // HERE'S MY PROBLEM !
$db->close();
一切都如我所愿,但当我第二次调用$db->count()
时,它会回声上一个计数,而不是2(因为我在Guestbook fetch函数中设置了LIMIT 2)。
如何正确地与这些类进行交互,以便在全局范围内使用类似$db->count()
的东西
提前感谢您的任何提示或解决方案!
首先,没有理由将mysql_*
实现封装在OOP中。如果你要做OOP,那么只需要使用Mysqli
或PDO
,它们有你可以扩展的OOP类。
其次,您希望在GuestBook类中保留Database的实例,而不是使其成为Database类本身的扩展。
对于如何用OOP包装数据库访问器并仍然全局访问count(),很难给出明确的建议。
很明显,您的代码是错误的。
通过使用符号
Database::query
您指的是Database类上的某种静态方法,这似乎不是本文的目的。看起来您的代码不会因为与PHP4的某些向后兼容性而崩溃。
你可以这样重写留言簿:
class Guestbook
{
private $db;
function __construct(&$db) {
$this->db = $db;
}
function fetch($option)
{
$this->db->query('SELECT * FROM guestbook LIMIT 2');
while($row = $this->db->fetch()){
$result_array[] = $row;
return $result_array;
}
}
然后
$db = new Database();
$db->connect();
$guestbook = new Guestbook($db);
$results = $guestbook->fetch();
echo $db->count();
该技术使用一种称为"依赖注入"的模式
当您有guestbook->fetch()方法的结果时,为什么要使用db类的count?
这做了完全相同的把戏:
echo count( $resutls );
请参阅$db
是Database类的对象永远不要访问Guestbook 的函数或属性
你可以用count( $resutls )
直接得到这个
OR可能必须采用继承概念
感谢
您将类的静态版本与实例化版本混合在一起。如果你想创建一个类的多个实例,你应该有一个__construct函数。虽然这不是必须的,但最好有一个。
您正在创建一个新实例,并将其分配给$db变量($db=new Database();)。但是,在GuestBook类中,您静态地引用了数据库类(database::)。该语法引用的"基类"在所有实例中都是相同的。您要做的是引用您创建的数据库类的实例。通常,您会将要使用的数据库实例传递到构造函数中的GuestBook类中,将其存储在类变量中,然后使用$this引用它。
class Guestbook
private $db = null;
{
function __construct($db) {
$this->db = $db;
}
function fetch($option) {
$this->db->query('SELECT ...');
...
}
}
$db = new Database();
$guestbook = new Guestbook($db);