简体   繁体   English

PHP OOP-尝试调用方法

[英]PHP OOP - Trying to call a method

Just trying to get my head around OOP. 只是想让我了解OOP。 I have been told that I am doing the script below wrong. 有人告诉我我在下面的脚本中做错了。 I was previously trying to call a method from the database class. 我以前试图从数据库类中调用方法。 When really the database class should only be dealing with database stuff. 实际上,数据库类仅应处理数据库内容。 So I have now created an html_class.php where I believe I need to access the database class and then output the html via this class?. 因此,我现在创建了一个html_class.php,我认为我需要在其中访问数据库类,然后通过此类输出html?

The method I am trying to call on the index.php is the getBlogPost() method located in the html_class.php file. 我试图在index.php上调用的方法是位于html_class.php文件中的getBlogPost()方法。 I am trying to call this using echo $htmlObject->getBlogPosts(); 我试图使用echo $htmlObject->getBlogPosts();来调用它$htmlObject->getBlogPosts();

I am assuming this is the proper way to go about doing this? 我假设这是执行此操作的正确方法?

I am currently getting the following errors: 我目前遇到以下错误:

Notice: Undefined variable: db_login_info in C:\xampp\htdocs\xampp\oop\CMS\classes\html_class.php on line 14

Fatal error: Cannot access private property database::$objDbConn in C:\xampp\htdocs\xampp\oop\CMS\classes\html_class.php on line 15

index.php 的index.php

<?php 
require_once("includes/header.php");
require_once("includes/footer.php");
require_once("classes/database_class.php");
require_once("classes/blog_post_class.php");
require_once("classes/html_class.php");
require_once("conf/config.php");

$header = new header();
// createHeader( Title | Description | Keywords)
echo $header->createHeader('Home - Nissan Skyline GTR Blog', 'This is a blog site about the Nissan GTR', 'Nissan, GTR, R35');

$dbObject = new database($db_login_info);
$htmlObject = new makeHTML();


 ?>
    <div id="container">
        <div id="top_nav">
        <a href="admin.php" class="admin_link">Admin Login</a>
        </div>

            <div id="header"></div>

            <div id="nav">
                <ul>
                    <li><a href="index.php">Home</a></li>
                    <li><a href="create-blog.php">Create Blog</a></li>
                    <?php 
                    $sql = "SELECT * FROM create_page";
                    echo $dbObject->createNavigation($sql);
                     ?>
                </ul>
            </div>

            <div id="content_area">
                <?php 
                echo $htmlObject->getBlogPosts(); // Calling the getBlogPost function located in the html_class.php

                // echo $dbObject->getBlogPosts();

                 ?>


            </div>
<?php 
$footer = new footer();
echo $footer->createFooter();
 ?>

database_class.php database_class.php

<?php    

class database {
        private $objDbConn;

        function __construct($db_login_info){
            $this->objDbConn = new mysqli($db_login_info['host'], $db_login_info['username'],
                                        $db_login_info['password'], $db_login_info['database']);

             if (mysqli_connect_errno()) {
                        die("Database connection failed". mysqli_connect_error());
                }
        }
        // I was previoulsy calling this method below on the index.php page and it was working great
        // function getBlogPosts(){
        //  $objRes = mysqli_query($this->objDbConn, "SELECT * FROM `blog_posts` ORDER BY id DESC");
        //   if(mysqli_errno($this->objDbConn)) {
        //      die("Failed query: $strSql". $this->objDbConn->error);
        //   }
        //   $allrows ='';
        //   while ($row = mysqli_fetch_array($objRes)) {

        //      $time = strtotime($row['date']);
        //      $my_format = date("m/d/y @ g:ia", $time);

        //      $allrows .= '<div id="blog_post">';
        //      $allrows .= '<h2 id="blog_title">'.$row['title'].'</h2>';
        //      $allrows .= '<h5> Posted on the '.$my_format.'</h5>'."<br>";
        //      $allrows .= '<div id="blog_content">'.nl2br($row['content']).'</div>'."<br>";
        //      $allrows .= '<b>ID:</b>'.$row['id'].'<a href="delete.php?id='.$row['id'].'" name="delete" onclick="return confirm(\'Are you sure you want to delete this post?\');"> Delete</a></div>';
        //   };

        //   return $allrows;



        // }

    ?>

html_class.php html_class.php

<?php 
require_once("includes/header.php");
require_once("includes/footer.php");
require_once("classes/database_class.php");
require_once("classes/blog_post_class.php");
require_once("classes/html_class.php");
require_once("conf/config.php");


class makeHTML {


    function getBlogPosts(){
        $dbObject = new database($db_login_info); // This is where the Notice: Undefined variable: db_login_info is happening
        $objRes = mysqli_query($dbObject->objDbConn, "SELECT * FROM `blog_posts` ORDER BY id DESC");
         if(mysqli_errno($dbObject->objDbConn)) {
            die("Failed query:". $dbObject->objDbConn->error);
         }
         $allrows ='';
         while ($row = mysqli_fetch_array($objRes)) {

            $time = strtotime($row['date']);
            $my_format = date("m/d/y @ g:ia", $time);

            $allrows .= '<div id="blog_post">';
            $allrows .= '<h2 id="blog_title">'.$row['title'].'</h2>';
            $allrows .= '<h5> Posted on the '.$my_format.'</h5>'."<br>";
            $allrows .= '<div id="blog_content">'.nl2br($row['content']).'</div>'."<br>";
            $allrows .= '<b>ID:</b>'.$row['id'].'<a href="delete.php?id='.$row['id'].'" name="delete" onclick="return confirm(\'Are you sure you want to delete this post?\');"> Delete</a></div>';
         };

         return $allrows;
    }
}



 ?>

config.php config.php文件

<?php 

// Database login details below

$db_login_info = array(
    'host'=>'localhost',
    'username'=>'root',
    'password'=>'',
    'database'=>'cms'
    );

 ?>

Updated html_class.php 更新了html_class.php

<?php 
require_once("includes/header.php");
require_once("includes/footer.php");
require_once("classes/database_class.php");
require_once("classes/blog_post_class.php");
require_once("classes/html_class.php");
require_once("conf/config.php");


class makeHTML {

    private $database;

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

    function getBlogPosts(){

        $objRes = mysqli_query($this->database, "SELECT * FROM `blog_posts` ORDER BY id DESC");
         if(mysqli_errno($this->database)) {
            die("Failed query:". $this->database->error);
         }
         $allrows ='';
         while ($row = mysqli_fetch_array($objRes)) {

            $time = strtotime($row['date']);
            $my_format = date("m/d/y @ g:ia", $time);

            $allrows .= '<div id="blog_post">';
            $allrows .= '<h2 id="blog_title">'.$row['title'].'</h2>';
            $allrows .= '<h5> Posted on the '.$my_format.'</h5>'."<br>";
            $allrows .= '<div id="blog_content">'.nl2br($row['content']).'</div>'."<br>";
            $allrows .= '<b>ID:</b>'.$row['id'].'<a href="delete.php?id='.$row['id'].'" name="delete" onclick="return confirm(\'Are you sure you want to delete this post?\');"> Delete</a></div>';
         };

         return $allrows;
    }
}

Update database_class.php 更新database_class.php

class database {
    public $objDbConn;

    function __construct($db_login_info){
        $this->objDbConn = new mysqli($db_login_info['host'], $db_login_info['username'],
                                    $db_login_info['password'], $db_login_info['database']);

         if (mysqli_connect_errno()) {
                    die("Database connection failed". mysqli_connect_error());
            }


    } 

     ?>

fetchall method in database_class.php : 在使用fetchall方法database_class.php

function fetchall($sql) {
        $query = mysqli_query($this->objDbConn, $sql);
        if ($this->objDbConn->connect_errno) {
            die("Database connection failed with message: " . $objDbConn->connect_error);
        }
    }

You should use " Dependency Injection " to give your makeHtml class the database object. 您应该使用“ Dependency Injection ”为您的makeHtml类提供database对象。

Add a __construct method to your makeHtml class: 在您的makeHtml类中添加__construct方法:

class makeHtml
{
    private $database;

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

When you instantiate your makeHtml class: 当您实例化makeHtml类时:

$htmlObject = new makeHTML($dbObject);

Then inside your class, instead of creating a new database object (and a new connection every time) you can just refer to your database object with $this->database . 然后在您的类内部,无需创建新的数据库对象(每次都创建新的连接),而只需使用$this->database引用数据库对象即可。

Further note to your case above, you will need to make the $objDbConn variable in the database class public so that you can access that variable in the other class. 对于上述情况,请进一步注意,您需要将database类中的$objDbConn变量$objDbConn public以便可以在其他类中访问该变量。 However, it would be "good practice" to have a method within your database class that deals with performing queries and returning the result. 但是,在database类中具有处理执行查询并返回结果的方法将是一种“好的做法”。 Ideally you should end up with something like: 理想情况下,您应该得到如下结果:

$sql = 'SELECT * FROM `blog_posts` ORDER BY id DESC';
$allRows = $this->database->fetchAll($sql);

That will appear in your makeHtml class. 这将出现在您的makeHtml类中。

Okay, a few different things are going on with your code. 好的,您的代码正在发生一些不同的事情。

For starters, you are mixing procedural and object-oriented versions of MySQLi. 首先,您要混合过程版本和面向对象版本的MySQLi。 The fact that you are using MySQLi is a big plus instead of going with the old deprecated version of MySQL. 您正在使用MySQLi的事实是一大优势,而不是不推荐使用旧版本的MySQL。 However, you need to pick between procedural or OOP, and then stick with it. 但是,您需要在过程或OOP之间进行选择,然后再坚持下去。

As for your error messages. 至于您的错误消息。 You are getting the notice about $db_login_info because it does not exist in the getBlogPosts() method. 您会收到有关$db_login_info的通知,因为它在getBlogPosts()方法中不存在。 When you are inside of a method your variable scope becomes limited. 当您处于方法内部时,变量范围将受到限制。 Meaning that variables declared outside of it are not visible within the method unless they are passed in as parameters. 这意味着在其外部声明的变量在方法中不可见,除非将它们作为参数传递。

The second message is about class scope. 第二条消息是关于类范围的。 Your variable $dbObjConn is declared as private , which is fine, but you can only access a private variable from within the same class. 你的变量$dbObjConn被声明为private ,这是很好的,但你只能访问private来自同一个类的变量。 If you declare it public then you can access it the way you are. 如果您将其声明为public则可以按原样访问它。

So here are some modifications I can suggest making to your code. 因此,我建议对您的代码进行一些修改。 Having a database class isn't a bad thing, it is easier to create a connection as an object and then pass that object around to other classes that need it. 拥有数据库类不是一件坏事,将连接创建为对象然后将其传递给需要它的其他类会更容易。 But, when you do this you should not mix the procedural versions of MySQLi with the OOP version. 但是,执行此操作时,请勿将MySQLi的过程版本与OOP版本混合使用。 (I recommend you stick with the OOP version). (我建议您坚持使用OOP版本)。

Your database_class.php could look something like this: 您的database_class.php可能看起来像这样:

class database {
    private $objDbConn;

    function __construct($db_login_info){
        $this->objDbConn = new mysqli($db_login_info['host'], $db_login_info['username'],
                                      $db_login_info['password'], $db_login_info['database']);

        //This is where you are using the procedural interface
        //if (mysqli_connect_errno()) {
        //    die("Database connection failed". mysqli_connect_error());
        //    }
        //}

        //Use the OOP version instead
        if ($this->objDbConn->connect_errno) {
            die("Database connection failed with message: " . $this->objDbConn->connect_error);
        }

    }

    //Keep populating this class with more stuff.  Like:
    public function getDB() {
        return $this->dbObjConn; //use this method to access your private database variable from outside the class
    }
}

The html_class.php file could use some love as well: html_class.php文件也可以使用一些爱:

class makeHTML {

    private $database; //Here is a place for your shiny database object.

    public functon __construct($database) {
        $this->database = $database;
    }

    public function getBlogPosts() {
        $dbObject = $this->database->getDB();
        $objRes = $dbObject->query($dbObject->objDbConn, "SELECT * FROM `blog_posts` ORDER BY id DESC");
         if($dbObject->errno) {
            die("Failed query:". $dbObject->error);
         }
         $allrows ='';
         while ($row = $objRes->fetch_array()) {

            $time = strtotime($row['date']);
            $my_format = date("m/d/y @ g:ia", $time);

            $allrows .= '<div id="blog_post">';
            $allrows .= '<h2 id="blog_title">'.$row['title'].'</h2>';
            $allrows .= '<h5> Posted on the '.$my_format.'</h5>'."<br>";
            $allrows .= '<div id="blog_content">'.nl2br($row['content']).'</div>'."<br>";
            $allrows .= '<b>ID:</b>'.$row['id'].'<a href="delete.php?id='.$row['id'].'" name="delete" onclick="return confirm(\'Are you sure you want to delete this post?\');"> Delete</a></div>';
         };

         return $allrows;
    }

    //Again, keep adding more to this class as you see fit....
}

Then to put all of this together, your calling code would look something like: 然后将所有这些放在一起,您的调用代码将类似于:

<?php 

include "config.php";

$myDatabase = new database($db_login_info);

$html = new makeHTML($myDatabase);

$posts = $html->getBlogPosts();

print($posts);

?>

you cannot use private member of object. 您不能使用对象的私有成员。 Instead you could use method or make member public . 相反,您可以使用方法或将成员设为公开 Also instead of creating connection object every time you should create connection object in config file and include this file once. 另外,不是每次都应在配置文件中创建连接对象并一次包含此文件时创建连接对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM