0

Hi I'm creating a login script but for some reason I'm getting an undefined property error when I am calling on $mysqli however I have called it in the same way on other functions and it has worked fine for example I am calling it as so $this->mysqli->prepare(); this has worked for my insert functions.

However when using it in the instance of real_escape_string() I am actually getting two errors:

Notice: Undefined property: Login::$mysqli in /Applications/XAMPP/xamppfiles/htdocs/imanage/class.Login.php on line 28

Fatal error: Call to a member function real_escape_string() on a non-object in /Applications/XAMPP/xamppfiles/htdocs/imanage/class.Login.php on line 28

EDIT: Line 28 is referring to this line $safeUser = $this->mysqli->real_escape_string($user);

I don't really understand what I've done differently, any ideas on how I can fix this?

Would appreciate any input and help

My code is below:

index.php

<div id="maincontentWrapper">
<div id="maincontent">
    <div id="contentWrapper"></div><!--End loginWrapper -->
        <article>
            <p>Welcome to iManage, please login in below.</p>
        </article>
    <div id="loginform">
        <div id="loginWrapper">
        <form id="loginForm" method="POST" action="class.Login.php">
        <h1><span class="log-in">Log in</span> or <span class="sign-up"><a href="register">sign up</a></span></h1>
        <div id="errorDiv"><?php 
                    if (isset($_SESSION['error']) & isset($_SESSION['formAttempt'])) {
                            unset($_SESSION['formAttempt']);
                            print "Errors encountered<br/>\n";
                            foreach ($_SESSION['error'] as $error) {
                            print $error . "<br />\n";
                        } //end foreach
                        } //end if 
                ?></div>
    <p class="float">
        <label for="login"><i class="icon-user"></i>Username</label>
        <input type="text" id="email" name="email" placeholder="E-mail">
          <span class="errorFeedback errorSpan" id="emailError">E-mail is required</span>
    </p>
    <p class="float">
        <label for="password"><i class="icon-lock"></i>Password</label>
        <input type="password" id="password" name="password" placeholder="Password" class="showpassword"> 
                <span class="errorFeedback errorSpan" id="passwordError">Password is required</span>

    </p>
    <p class="clearfix"> 
        <input type="submit" name="submit" value="Log in"></form>
    </p>   
        </div>
    
    </div>
    
    
</div>
</div>

</div>

class.Login.php

<?php

include("connect/class.Connect.php");

class Login extends Database {
    
    public $id;
    public $email;
    public $username;
    
    function __construct() {
        
        if (session_id() == "") {
            session_start();    
        }
        
        if (isset ($_SESSION['isLoggedIn']) && $_SESSION['isLoggedIn'] == true) {
            $this->_initUser();
        } 
        
    } // end construct
    
    public function authenticate($user, $pass) {
        
        $user = isset($_POST['email']);
        $pass = isset($_POST['password']);
    
        $safeUser = $this->mysqli->real_escape_string($user);
        $incomingPassword = $this->mysqli->real_escape_string($pass);
        
        $query = "SELECT * from users WHERE email = '{$safeUser}'";
            
                if (!$result = $this->mysqli->query($query)) {
                        error_log("Cannot retrieve account for {$user}");
                        return false;
                }   
                
                // will be only one row, so no while() loop needed
                $row = $result->fetch_assoc();
                $dbPassword = $row['password'];
                
                if (crypt($incomingPassword,$dbPassword) != $dbPassword) {
                        error_log("Passwords for {$user} don't match");
                        return false;
                }
                    $this->id = $row['id'];
                    $this->username = $row['username'];
                    $this->email = $row['email'];
                    $this->isLoggedIn = true;
                    
                    $this->_setSession();
                    return true;    
        
    } // end authenticate 
    
        private function _setSession() {
        
        if (session_id() == '') {
            session_start();    
        }
        
        $_SESSION['id'] = $this->id;
        $_SESSION['email'] = $this->email;
        $_SESSION['username'] = $this->username;
        $_SESSION['isLoggedIn'] = $this->isLoggedIn;
        
    } // end function setSession


    private function _initUser() {
        
        if (session_id() == '') {
            session_start();    
        }
        
        $this->id = $_SESSION['id'];
        $this->email = $row['email'];
        $this->username = $row['username'];
        $this->user_role = $row['user_role'];
        $this->isLoggedIn = $_SESSION['isLoggedIn'];
        
    } // end initUser
     
         function preventaccess () {
        if (!isset($_POST['submit'])) {
            die(header("Location: login.php"));
        }
    } // end prevent access 

     function validatelogin () {
                    $_SESSION['formAttempt'] = true;
        
        if (isset($_SESSION['error'])) {
            unset($_SESSION['error']);
        }
        
            $_SESSION['error'] = array();
         
            $required = array("email", "password");
        
            //Check required fields
            foreach ($required as $requiredField) {
                if (!isset($_POST[$requiredField]) || $_POST[$requiredField] == "") {
                $_SESSION['error'][] = $requiredField . " is required.";
            }
            }
            
                
            if (!filter_var($_POST['email'],FILTER_VALIDATE_EMAIL)) {
            $_SESSION['error'][] = "Invalid e-mail address";
            }
            
            if (count($_SESSION['error']) > 0) {
                die(header("Location: login.php")); 
            } else {
                $user = new User;
                if ($user->authenciate($_POST['email'], $_POST['password'])) {
                    unset($_SESSION['formAttempt']);    
                 die(header("Location: authenticated.php"));
            }else {
                 $_SESSION['error'][] = "There was a  problem with your username or password.";
                 die(header("Location: login.php"));
                }
        }
        } // end validate 
        
}
    $run = new Login();
    $run->__construct();
    $run->authenticate($_POST['email'],$_POST['password']);
    $run->validatelogin();
?>

connect/class.Connect.php

<?php

/**
 * MySQLi database
 */
class Database {
    
    
        public function __construct(){
                
                $this->mysqli = new mysqli('localhost', 'root', '', 'imanage');
                
                if(mysqli_connect_errno()) {
         
                    echo "Error: Could not connect to database.";
         
                exit;
 
        }
        /*else{
            echo"Your Database successfully connected"; 
        }*/
                
    }
    
    public function __destruct(){
        $this->mysqli->close(); 
    }
  
  
        
}
Community
  • 1
  • 1
user0129e021939232
  • 6,205
  • 24
  • 87
  • 140
  • It would help if you'd point out exactly what line line 28 is. – Andy Lester Sep 07 '13 at 21:44
  • @AndyLester Sorry, I've edited my question to reflect this – user0129e021939232 Sep 07 '13 at 21:46
  • too much code for such a common error. I suggest to close. – hakre Sep 07 '13 at 21:49
  • and for your cause of the error: you're not calling the constructor of the parent class: `parent::__construct()` - but anyway, you have some issues in your code. If you share *why* you wrote / designed it that way, it might be even possible to give you some good hints not only how to remove the warning. You have some real issues in that code you should remove if you want to learn these things effectively. – hakre Sep 07 '13 at 21:53
  • And if you are interested in code-review, please know about; http://codereview.stackexchange.com/ – hakre Sep 07 '13 at 21:54
  • @gutigrewal , please learn to use prepared statements – tereško Sep 07 '13 at 22:54

2 Answers2

1
class Login extends Database {
            ################
    ...

    function __construct() {

        ...

        parent::__construct();    <--- missing
        ######################

        ...

    } // end construct

    ...
hakre
  • 193,403
  • 52
  • 435
  • 836
  • adding this still doesn't make a difference – user0129e021939232 Sep 07 '13 at 22:36
  • Well, the error has to go away or you're still doing this wrong. But as I commented earlier (and that is the spin), even if the error goes away, you still have issues in your code. In short: Your question should be closed because it does not fit this website. You have to ask a concrete programming question as outlined in the help section. – hakre Sep 07 '13 at 22:38
  • what sort of issues do you see? would be helpful to know – user0129e021939232 Sep 07 '13 at 22:39
  • sure, you are eager. But read closely. I was already telling you there are more issues two time until now. And even you're curious you can't ask differently? – hakre Sep 07 '13 at 22:42
0

You do not have a property mysqli defined in your Database class. This should do

<?php

    /**
     * MySQLi database
     */
    class Database {

        private $_mysqli;
        public function __construct() {

            $this->_mysqli = new mysqli('localhost', 'root', '', 'imanage');

            if(mysqli_connect_errno()) {

                echo "Error: Could not connect to database.";

                exit;

            }
            /*else{
                echo"Your Database successfully connected"; 
            }*/

        }

        public function __destruct(){
            $this->_mysqli->close(); 
        }

    }
?>
  • 1
    but if I use `$this->mysqli` when calling on my database I get successful interaction, why is it any different in this case? can you also edit your answer with an example of how you would define the property `mysqli` please – user0129e021939232 Sep 07 '13 at 21:48
  • thanks so when Im querying the database how would I call this then? currently I'm using `$this->mysqli->prepare();` in your case would I use `$this->_mysqli`? also why does my `mysqli` work in the case of the prepared statements and not in the above example? – user0129e021939232 Sep 07 '13 at 21:58
  • if the parent constructor sets that property, you need at least once call the parent's constructor to have that property set. A computer program is really dumb, it only does what you have written into it. If you've missed to call the parents constructor, the script won't fix that on it's own. – hakre Sep 07 '13 at 22:02
  • @hakre am I not calling it by using this line `$run->__construct();` – user0129e021939232 Sep 07 '13 at 22:09
  • most likely not. constructors are not called *that* way. Either via `new ClassName();` or by `parent::__construct()` but not like you just commented. – hakre Sep 07 '13 at 22:10
  • ok, but i'm calling but class like so `$run = new Login();` is this what you mean? or am I misinterpreting? @hakre – user0129e021939232 Sep 07 '13 at 22:24
  • @gutigrewal: please see http://stackoverflow.com/a/18678540/367456 I underlined the parts I think you need to think about with number signs. – hakre Sep 07 '13 at 22:31