PHP OOP访问其他类中的方法

时间:2015-06-16 02:09:13

标签: php mysql oop

我是新手以oop方式做事。这就是我得到的。

首先,我创建了一个将我连接到数据库的课程。然后我创建了一个类来从数据库中获取结果。

/engine/classes.php

class DB
{
    public static function dbConnect() 
    {
        $db = new mysqli(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
        if ($db->connect_error) {
        die('A connection to the database cannot be made.');
        }
    }
}

class Blog
{
    public function fetchBlog() 
    {
        DB::dbConnect();
        $results = array();
        if ($blog = $db->query('SELECT * FROM blog')) {
            if ($blog->num_rows) {
                 while ($row = $blog->fetch_object()) {
                     $results[] = $row;
                 }
             $blog->free();
             }
         }
     }
}

然后我有一个core.php文件,其中包含我的classes.php文件并实例化这些类。像这样

/engine/core.php

require_once 'classes.php';

$con = new DB();
$con->dbConnect();

$blog = new Blog();

然后我终于得到了index.php,我希望能够回应我得到的结果。看起来像这样

的index.php

<?php include 'engine/core.php'; ?>
html stuff
<div id="blog">
    <?php
    $blog->fetchBlog();
    if (!count($results)) {
        echo'There are no blog posts at this time.';
    } else {
        foreach ($results as $r) { 
            echo'<div class="blogPost">
                <em>', escape($r->postDate), '</em>
                <h1>', escape($r->postTitle), '</h1>
                <div>', escape($r->postBody), '</div>
            </div>';
        } 
    }

    ?>
</div>

我确实有错误报告,并且没有在core.phpclasses.php上收到错误。但是,在我的index.php页面上,我收到了这些错误

Notice: Undefined variable: db in C:\wamp\www\website\engine\classes.php on line 138
 Fatal error: Call to a member function query() on a non-object in C:\wamp\www\website\engine\classes.php on line 138

我该如何纠正?我假设我需要一个__construct在那里,我也假设我没有正确地调用dbConnect方法。我尝试了很多东西,但在这里列出它们会太多了吗?谁能告诉我我做错了什么?

3 个答案:

答案 0 :(得分:2)

问题是你的$db变量是DB::dbConnect()函数的本地变量,这意味着一旦该函数运行完毕,它就会被销毁。

$results也存在一个问题,你没有从函数中返回它或从函数调用中赋值。

通过以下编辑,您将能够使其发挥作用,我会对其进行评论,希望能让您更好地了解我为什么按照我的方式做事。

  

/engine/classes.php

class DB
{
    /**
     * keep the variable available for all instances of the DB class since it's static.
     */ 
    static protected $db;

    /**
     * get database instance, connect if necessary
     */
    public static function conn()
    {
        /**
         * automatically connect to the database if it's not connected
         * this is known as lazy loading, which means it only creates
         * the resource at the exact time that it needs it
         */
        if (false === (self::$db instanceof mysqli) {
            self::connect();
        }
        return self::$db;
    }

    /**
     * create a connection to the database
     */
    protected static function connect() 
    {
        self::$db = new mysqli(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
        if (self::$db->connect_error) {
            die('A connection to the database cannot be made.');
        }
    }
}

class Blog
{
    public function fetchBlog() 
    {
        $results = array();
        /**
         * Since the db method is static, you can just call it without an instance
         */
        if ($blog = DB::conn()->query('SELECT * FROM blog')) {
            if ($blog->num_rows) {
                 while ($row = $blog->fetch_object()) {
                     $results[] = $row;
                 }
             $blog->free();
             }
         }
     /**
      * you didn't do anything with the results, presumably you want to return them so you can do something with them
      */
     return $results;
     }

}
  

/engine/core.php

require_once 'classes.php';

/**
 * It is unnecessary to create an instance of the DB class
 * as all methods are defined statically
 */
//$con = new DB();
//$con->dbConnect();

$blog = new Blog();
  

的index.php

<?php include 'engine/core.php'; ?>
<!-- html stuff -->
<div id="blog">
    <?php
    /**
     * You must assign the output of the function call so you can make use of it
     */
    $results = $blog->fetchBlog();
    if (!count($results)) {
        echo'There are no blog posts at this time.';
    } else {
        foreach ($results as $r) { 
            echo'<div class="blogPost">
                <em>', escape($r->postDate), '</em>
                <h1>', escape($r->postTitle), '</h1>
                <div>', escape($r->postBody), '</div>
            </div>';
        } 
    }

    ?>
</div>

答案 1 :(得分:0)

在您的班级Blog中,您只需访问从未在该行中声明的变量$db

if ($blog = $db->query('SELECT * FROM blog')) {

您必须向类DB添加变量$db,然后在班级Blog中创建该类的新实例。

答案 2 :(得分:0)

if ($blog = $db->query('SELECT * FROM blog')) {行中,永远不会声明$db

您需要做的是从构造函数返回DB对象,因此您的类DB应如下所示:

class DB
{
    public static function dbConnect() 
    {
        $db = new mysqli(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
        if ($db->connect_error) {
            die('A connection to the database cannot be made.');
        }

        // Note this line :)
        return $db;

    }
}

除此之外,还有许多改进,可以在您的代码中完成。首先,我建议您从这里详细介绍OOP:http://php.net/manual/en/language.oop5.php

偏离主题,但我想补充一些建议。您已将数据库对象创建方法创建为静态。我建议为这些对象实现Singleton设计模式,因为在整个应用程序中只需要这个类的一个对象。 Read More