user2917823
user2917823

Reputation: 199

PHP - extending class (basics)

Silly question, I am really new on PHP, took some codeacademy courses, but the classes part is not yet really clear to me. I am trying to work it out, and to modify the above code.

So below is a class, which checks if the user is logged on, and if so, creates an user session.

class Login
{
    /**
     * @var object The database connection
     */
    private $db_connection = null;
    /**
     * @var array Collection of error messages
     */
    public $errors = array();
    /**
     * @var array Collection of success / neutral messages
     */
    public $messages = array();

    /**
     * the function "__construct()" automatically starts whenever an object of this class is created,
     * you know, when you do "$login = new Login();"
     */
    public function __construct()
    {
        // create/read session, absolutely necessary
        session_start();

        // check the possible login actions:
        // if user tried to log out (happen when user clicks logout button)
        if (isset($_GET["logout"])) {
            $this->doLogout();
        }
        // login via post data (if user just submitted a login form)
        elseif (isset($_POST["login"])) {
            $this->dologinWithPostData();
        }
    }

    /**
     * log in with post data
     */
    private function dologinWithPostData()
    {
        // check login form contents
        if (empty($_POST['user_name'])) {
            $this->errors[] = "Username field was empty.";
        } elseif (empty($_POST['user_password'])) {
            $this->errors[] = "Password field was empty.";
        } elseif (!empty($_POST['user_name']) && !empty($_POST['user_password'])) {

            // create a database connection, using the constants from config/db.php (which we loaded in index.php)
            $this->db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

            // change character set to utf8 and check it
            if (!$this->db_connection->set_charset("utf8")) {
                $this->errors[] = $this->db_connection->error;
            }

            // if no connection errors (= working database connection)
            if (!$this->db_connection->connect_errno) {

                // escape the POST stuff
                $user_name = $this->db_connection->real_escape_string($_POST['user_name']);

                // database query, getting all the info of the selected user (allows login via email address in the
                // username field)
                $sql = "SELECT user_name, user_email, user_password_hash
                        FROM sales_users
                        WHERE user_name = '" . $user_name . "' OR user_email = '" . $user_name . "';";
                $result_of_login_check = $this->db_connection->query($sql);

                // if this user exists
                if ($result_of_login_check->num_rows == 1) {

                    // get result row (as an object)
                    $result_row = $result_of_login_check->fetch_object();

                    // using PHP 5.5's password_verify() function to check if the provided password fits
                    // the hash of that user's password
                    if (password_verify($_POST['user_password'], $result_row->user_password_hash)) {

                        // write user data into PHP SESSION (a file on your server)
                        $_SESSION['user_name'] = $result_row->user_name;
                        $_SESSION['user_email'] = $result_row->user_email;
                        $_SESSION['user_login_status'] = 1;

                    } else {
                        $this->errors[] = "Wrong password. Try again.";
                    }
                } else {
                    $this->errors[] = "This user does not exist.";
                }
            } else {
                $this->errors[] = "Database connection problem.";
            }
        }
    }

    /**
     * perform the logout
     */
    public function doLogout()
    {
        // delete the session of the user
        $_SESSION = array();
        session_destroy();
        // return a little feeedback message
        $this->messages[] = "You have been logged out.";

    }

    /**
     * simply return the current state of the user's login
     * @return boolean user's login status
     */
    public function isUserLoggedIn()
    {
        if (isset($_SESSION['user_login_status']) AND $_SESSION['user_login_status'] == 1) {
            return true;
        }
        // default return
        return false;
    }

}

What I want to do, is to extend this class, and use it to get some other data from the database. So I wrote:

class Price extends Login
{
    public function getPrice()
    {

        $sql = "SELECT *
                FROM sales_pricelist";
        $result = $Login->db_connection->query($sql);
        $result = $result->fetch_object();

        echo $result->product_name;

    }

}

I understand that this part is not correct at all. But it iliustrates what I want to achieve. So the question is, how should the correct version look? I was hoping that I could learn it better when seeing the exact example.

Edit #1:

Is this part $result = $Login->db_connection->query($sql); correct? This basically means, that I am targeting db_connection from the Login class right?

Edit #2:

Thank you for all the comments.

So now, my Price class looks like this:

class Price extends Login
{

    public function __construct() {
            parent::__construct();
    }

    public function getPrice()
    {

        $sql = "SELECT *
                FROM sales_pricelist";
        $result = $this->db_connection->query($sql);
        $result = $result->fetch_object();

        echo $result->product_name;

    }

}

And I am trying to call use the getPrice like this:

$price = new Price();
$price->getPrice();

But something is missing. Any mistakes here?

Upvotes: 0

Views: 129

Answers (2)

Steve
Steve

Reputation: 20469

You reference the current object with $this . As the child class inherits the parents methods and properties, you would access the db property as so:

$result = $this->db_connection->query($sql);

Edit as per comments

  1. As noted, $db_connection has private scope, so unaccessable to child classes. If you wish to access it in child classes, you either need to change it to protected or public, or write a getter method in the parent, with protected or public scope:

    protected function getDb() { return $this->db_connection; }

  2. re parent::__construct() The parent constructor will automatically be called unless you override the method in the child class (by writing a __construct() method in it. If you do that, you will need to call the parent consructor as noted;

  3. Initializing the database connection As noted, the db connection is initialized in the dologinWithPostData() method. For it to be usefull for other methods, it would make more sense to initialize it in the parent constuctor.

  4. General notes This violates all sorts of good OOP principles, such as encapsulation. Learning a decent modern MVC framework would probably give you a better grounding than following random internet tutorials

Upvotes: 2

dudeman
dudeman

Reputation: 603

This looks right to me at first glance. What you need is to call the parent constructor. In you Price class so that you can run your login code.

function __construct() {
    parent::__construct();
}

Upvotes: 1

Related Questions