我不确定这是否可行,因为我在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 线
唉...
有什么想法吗?
答案 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'));
我是对的吗??