2012-03-02 95 views
0

我开始使用PHP类并查看OOP。正确地与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; 
    } 
} 

只是为了测试,我创建了另一个类叫做留言,看起来像这样:

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(为我设定的限制2在留言取功能)。

我如何使用这些类正确的交互,这样我就可以使用类似$db->count()全球?

在此先感谢您提供任何提示或解决方案!

+0

你为什么要静态地从调用数据库的模式你留言分类?如果你想静态使用它,你应该声明它,并且只能像这样使用它:) 我建议制作数据库单例。 – 2012-03-02 14:17:01

+1

问题在于这里混合了静态和对象调用。将它规范化,以便在任何地方使用静态或对象。建议看看Singleton模式。 – 2012-03-02 14:25:32

+1

另一件事是,你通常会保留在留言簿类中的所有内容。您可以调用$ guestbook-> getPosts(),它通过一个私有或受保护的getDataRow()方法获取所需的数据,该方法将数据设置为留言簿中的受保护变量,以便您可以多次访问它而不必每次都访问数据库。 – 2012-03-02 14:29:00

回答

2

这是很难给你你怎么可以换用OOP数据库访问一个明确的意见,仍然()全球访问计数。

显然你的代码是错误的。

使用符号

Database::query 

你指的是某种对数据库类,它似乎并没有在这里是意图静态方法。它看起来像你的代码不会因为与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(); 

这种技术使用一种被称为“依赖注入”

+0

感谢您向我展示我如何做到这样的事情! – Fabian 2012-03-02 14:39:35

1

当您从guestbook-> fetch()方法获得结果时,为什么要使用db类中的count?

这究竟同样的伎俩:

echo count($resutls); 
+0

我已经这样做了,但我想使用mysql_count。 – Fabian 2012-03-02 14:18:37

+0

在这种情况下,没有理由这样做,恕我直言。但是,如果你真的想要它,你可以从留言簿中返回整个数据库对象。这不是你通常会做的,因为你只是为已经存在的东西创建不必要的代码。 – 2012-03-02 14:21:22

4

首先,没有任何理由来包装mysql_*实现OOP中。如果你打算做OOP,那么只需使用你可以扩展的OOP类的MysqliPDO

其次,您想要在GuestBook类中保存数据库的实例,而不是将其作为Database类本身的扩展。

+0

我只是在玩这个话题。我想理解它,所以我自己创造了一些东西。这不会用于任何实际的项目。 – Fabian 2012-03-02 14:20:38

+0

我明白,我只是说你用一条可怜的路去尝试并获得理解:-) – prodigitalson 2012-03-02 14:25:41

+0

@Fabian真实的项目与否,prodigalson给了你如何改善 – 2012-03-02 14:27:05

0

看到$db是类数据库的对象 从未访问的留言

功能或属性,您可以直接与count($resutls)

得到这样或可能要与继承的概念

谢谢

0

你混合静态和你的类的实例化版本。如果你想能够创建一个类的多个实例,你应该有一个__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);