扩展从mysqli扩展的类中的类

时间:2011-02-22 22:24:04

标签: php oop class mysqli

我不确定这是否可行,因为我在OOP编程方面还不是很好。

我从mysqli扩展了这个db类,

class database extends mysqli
{
    # overwrite parent __construct
    public function __construct($hostname = null,$username = null,$password = null,$database = null,$port = null, $socket = null)
    {
        $hostname = $hostname !== null ? $hostname : ini_get("mysqli.default_host");
        $username = $username !== null ? $username : ini_get("mysqli.default_user");
        $password = $password !== null ? $password : ini_get("mysqli.default_pw");
        $database = $database !== null ? $database : "";
        $port     = $port     !== null ? $port     : ini_get("mysqli.default_port");
        $socket   = $socket   !== null ? $socket   : ini_get("mysqli.default_socket");

        parent::__construct($hostname,$username,$password,$database,$port,$socket);

        # check if connect errno is set
        if (mysqli_connect_errno()) 
        {
            throw new RuntimeException('Cannot access database: ' . mysqli_connect_error());
        }

    }


    # fetches all result rows as an associative array, a numeric array, or both
    # mysqli_fetch_all (PHP 5 >= 5.3.0)
    public function fetch_all($query) 
    {
        $result = parent::query($query);
        if($result) 
        {
            # check if mysqli_fetch_all function exist or not
            if(function_exists('mysqli_fetch_all')) 
            {
                # NOTE: this below always gets error on certain live server
                # Fatal error: Call to undefined method mysqli_result::fetch_all() in /.../class_database.php on line 28
                return $result->fetch_all(MYSQLI_ASSOC);
            }

            # fall back to use while to loop through the result using fetch_assoc
            else
            {
                while($row = $result->fetch_assoc())
                {
                    $return_this[] = $row;
                }

                if (isset($return_this))
                {
                    return $return_this;
                }
                else
                {
                    return false;
                }
            }
        }
        else
        {
            return self::get_error();
        }
    }

    # fetch a result row as an associative array
    public function fetch_assoc($query)
    {
        $result = parent::query($query);
        if($result) 
        {
            return $result->fetch_assoc();
        } 
        else
        {
            # call the get_error function
            return self::get_error();
            # or:
            # return $this->get_error();
        }
    }

    public function query($query)
{
    $result = $this->query($query);
    if($result) 
    {
        return $result;
    }
    else
    {
        return $this->get_error();
    }

}

    ...

    # display error
    public function get_error() 
    {
        if($this->errno || $this->error)
        {
            return sprintf("Error (%d): %s",$this->errno,$this->error);
        }
    }

    public function __destruct()
    {
       parent::close();
        //echo "Destructor Called";
    }
}

我有这种程序式的代码,我想把它变成一个从上面的数据库类扩展的类,

if(isset($_REQUEST['search'])) $search = $_REQUEST['search'];

$sql = "
SELECT *

FROM root_pages

WHERE root_pages.pg_cat_id = '2'
AND root_pages.parent_id != root_pages.pg_id
AND root_pages.pg_hide != '1'
AND root_pages.pg_url != 'cms'
AND root_pages.pg_content_1 LIKE '%".$search."%'
OR root_pages.pg_content_2 LIKE '%".$search."%'

AND root_pages.pg_content_1 NOT LIKE '%http://%'
AND root_pages.pg_content_2 NOT LIKE '%http://%'

ORDER BY root_pages.pg_created DESC
";

$items = $connection->fetch_all($sql);
$total_item = $connection->num_rows($sql);

所以我认为,从理论上讲,我可以将这些代码扩展到这样的类中,

class search extends database
{

public $search = null;

public function __construct($keyword)
{
   $this->search = $keyword;    
}


public function get_result()
{
$sql = "
SELECT*

FROM root_pages

WHERE root_pages.pg_cat_id = '2'
AND root_pages.parent_id != root_pages.pg_id
AND root_pages.pg_hide != '1'
AND root_pages.pg_url != 'cms'
AND root_pages.pg_content_1 LIKE '%".$this->search."%'
OR root_pages.pg_content_2 LIKE '%".$this->search."%'

AND root_pages.pg_content_1 NOT LIKE '%http://%'
AND root_pages.pg_content_2 NOT LIKE '%http://%'

ORDER BY root_pages.pg_created DESC
";

$items = parent::fetch_all($sql);

return $items;
  }
}

然后我称之为搜索对象,

$output = new search('1');
print_r($output->get_result());

但我收到了很多错误,

  

警告:mysqli :: query()   [mysqli.query]:无法获取搜索   在C:\ wamp \ www \ xxx \ class_database.php中   在xx线上

     

警告:database :: get_error()   [database.get-error]:无法获取   搜索   C:\ wamp \ www \ xxx \ class_database.php on   第xx行

     

警告:mysqli :: close()   [mysqli.close]:无法获取搜索   在C:\ wamp \ www \ xxx \ class_database.php中   在xx线上

我做错了什么?我该如何解决?

感谢。

修改

当我尝试以这种方式从父类(数据库)调用子类(搜索)时,

$database = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
print_r(search::get_result());

然后我收到此错误,

  

致命错误:非静态方法   无法调用mysqli :: query()   静静地   C:\ wamp \ www \ xxx \ class_database.php on   线

唉...

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

因为search类中的search属性是非静态的,所以必须首先实例化一个对象:

$database = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$search = new search("search term");
print_r($search->get_result());

也许在PHP中阅读有关OOP的基础教程,这是Google的第一篇:

http://www.killerphp.com/tutorials/object-oriented-php/

编辑:你的self::get_error();类中还有一些database的调用,这些调用应该重写为实例方法而不是类方法:

$this->get_error()

答案 1 :(得分:1)

您使用了错误的方法来调用mysqli类中database类的方法。

您只想在访问静态方法,静态属性,常量或要覆盖的当前方法的父级时使用双冒号::。尽管php手册如何在方法列表中使用::列出它们,但mysqli类中的所有方法都不是静态的。

parent::__construct()中使用__construct()的方式是正确的,因为您使用的是覆盖的父级的当前方法。

但是在其他方法中,您希望使用$this->来引用其他父方法。

fetch_all()fetch_assoc()中使用$this->query()代替parent::query()

__destruct()中使用$this->close();代替。

当您使用self::get_error();时,您要么将其更改为$this->,要么修改您的函数定义以使其保持静态public static function get_error()

答案 2 :(得分:0)

我认为从database课程扩展课程可能是个坏主意......

这是我的解决方案:

class search
{

    public $mysqli = null;

    public function __construct($mysqli)
    {
       $this->mysqli = $mysqli;
    }

    public function get_result($parameter)
    {
        $sql = "
        SELECT *
        FROM root_contacts_cfm
        WHERE root_contacts_cfm.cnt_id = '".$parameter."'
        ORDER BY cnt_id DESC
        ";

        $item = $this->mysqli->fetch_assoc($sql);
        return $item;
    }
}

将对象database类传递到search类,因此我可以通过此方式调用此搜索类:

$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
print_r($output->get_result('1'));

我是对的吗??