我是新手以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.php
或classes.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
方法。我尝试了很多东西,但在这里列出它们会太多了吗?谁能告诉我我做错了什么?
答案 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。