www.webdeveloper.com
Results 1 to 11 of 11

Thread: Cant seem to figure this OOP issue out (new to OOP but not PHP)

  1. #1
    Join Date
    Feb 2012
    Posts
    102

    Question Cant seem to figure this OOP issue out (new to OOP but not PHP)

    I keep getting a fatal error message "Fatal error: Call to a member function save() on a non-object"
    Here is my code. If anyone can help me figure this out it would be great. I am new to OOP (its a harder transition from procedural than I thought it would be!)

    PHP Code:
    <?php
    define 
    ("DB_USER" "#######"); // Insert database username
        
    define ("DB_PASSWORD" "#######"); // Insert database password
        
    define ("DB_HOST" "localhost"); // Insert database host
        
    define ("DB_NAME" "#######"); // Insert database name
        
        
    Class Contact extends AbstractModel {
            
            protected 
    $dbc;
            protected 
    $_user = array();
            
            public function 
    __construct() {
                
                
    //Connect to the Database
                
    @$dbc=new mysqli(DB_HOSTDB_USERDB_PASSWORDDB_NAME);
                
    $this->dbc $dbc;
                
                if(
    mysqli_connect_errno()) {
                    die(
    'The connection to the database could not be established.');
                }
                
            } 
    // End of Constructor Function
        
            
    public function load($id) { // Runs a SELECT Query and stores in array
            
                
    $q "SELECT id, name, email FROM contacts WHERE id='$id'";
                
    $r $this->dbc->query($q);
                
    $user $r->fetch_array(MYSQLI_ASSOC);
                
    $this->_user $user;
            }
            
            public function 
    getData($key false) { // Returns data 
                
                
    if ($key) {
                    return 
    $this->_user[''.$key.''];
                }else{
                    return 
    $this->_user;
                }
            }
            
            public function 
    setData($arr$value=false) { // UPDATES rows in the database
                
                
    $temp 
                
                if (
    is_array($arr)) {
                    
    $new array_merge($this->_user$arr);
                    
    $this->_user $new;
                }else{ 
                    
    $this->_user[$arr] = $arr[$value];
                }
                
            }
            
            public function 
    save() {
            
                if (
    $this->_user['id']) {
                    
    $q "UPDATE contacts SET name='$this->_user['name']', email='$this->_user['email']' WHERE id=$this->_user['id']";
                    
    $r $this->dbc->query($q);
                }else{ 
                    
    $q "INSERT INTO contacts (name, email) VALUES ('$this->_user['name']', '$this->_user['email'])";
                    
    $r $this->dbc->query($q);
                }
            }
            
            public function 
    delete($id) {
            
            }
            
            
        }
    and here is the code I am running:

    PHP Code:
    $contact->setData('name''John Walker')->save(); //Should run an UPDATE query
    echo '<br/><br/>';
    print_r($contact->load(1)->getData());
    //Should print
    // id => 1,
    // name => John Walker
    // email => john@doe.com

    $contact->setData(array(
    "id" => 1,
    "name" => "John Doe the 2nd",
    "email" => "john@doe2.com"
    ))->save();
    echo 
    '<br/><br/>';
    print_r($contact->load(1)->getData());
    //Should print
    // id => 1,
    // name => John Doe the 2nd
    // email => john@doe2.com 

  2. #2
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,611
    Which line is failing? For now, I'll assume it's a line in the calling code where you reference $contact->, in which case you need to look at where that variable gets set -- or is it actually being set at all? (If it is that line, then the error is telling you that $contact is not an object, but some other type of variable (string, integer, null, etc.).
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  3. #3
    Join Date
    Jan 2006
    Posts
    67
    Add

    PHP Code:
    return $this
    to the end of your function
    PHP Code:
    public function setData 

  4. #4
    Join Date
    Feb 2012
    Posts
    102
    Quote Originally Posted by chickenland View Post
    Add

    PHP Code:
    return $this
    to the end of your function
    PHP Code:
    public function setData 
    Thanks, that worked for that issue but now I am having issues with updating the database in the save() Here is the function: Can you look over it and see where I am messing up?

    PHP Code:
    public function save() {
            
                if (
    $this->_user['id']) {
                    
    $q "UPDATE contacts SET name='$this->_user['name']', email='$this->_user['email']' WHERE id=$this->_user['id']";
                    
    $r $this->dbc->query($q);
                }else{ 
                    
    $q "INSERT INTO contacts (name, email) VALUES ('$this->_user['name']', '$this->_user['email'])";
                    
    $r $this->dbc->query($q);
                    if (
    $this->dbc->affected_rows == 1) {
                        
    $this->_user['id'] = $this->dbc->insert_id;
                        return 
    $this;
                    }
                }
            } 

  5. #5
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,611
    If you want complex variable expressions to be interpolated within a double-quoted string, use "complex variable notation" (i.e. curly braces):
    PHP Code:
    $q "UPDATE contacts SET name='{$this->_user['name']}', email='{$this->_user['email']}' WHERE id={$this->_user['id']}"
    However, since you are using MySQLi, I'd really like to see you use a prepared statement and bound parameters instead of using (potentially unsanitized) external inputs directly within a query.
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  6. #6
    Join Date
    Feb 2012
    Posts
    102
    Thanks NogDog. Yes I know about prepared statements, I am just trying to get the functionality down first then I will work on the security. For some reason when I attempt to use this code:

    PHP Code:
    $contact->setData('name''John Walker')->save(); //Should run an UPDATE query
    echo '<br/><br/>';
    print_r($contact->load(1)->getData()); 
    with these functions:

    PHP Code:
    public function setData($arr$value=false) { // UPDATES rows in the database
                
                
    if (is_array($arr)) {
                    
    $new array_merge($this->_user$arr);
                    
    $this->_user $new;
                }else{ 
                    
    $this->_user[''.$arr.''] = $arr[''.$value.''];
                }
                return 
    $this;
            }
            
            public function 
    save() {
            
                if (isset(
    $this->_user['id'])) {
                    
    $q "UPDATE contacts SET name='{$this->_user['name']}', email='{$this->_user['email']}' WHERE id={$this->_user['id']}";
                    
    $r $this->dbc->query($q);
                    return 
    $this;
                }else{ 
                    
    $q "INSERT INTO contacts (name, email) VALUES ('{$this->_user['name']}', '{$this->_user['email']})";
                    
    $r $this->dbc->query($q);
                    if (
    $this->dbc->affected_rows == 1) {
                        
    $this->_user['id'] = $this->dbc->insert_id;
                        return 
    $this;
                    }
                }
            } 
    it returns name=>n instead of name=>John Walker
    I believe it is something I have wrong with this line:
    PHP Code:
     $this->_user[''.$arr.''] = $arr[''.$value.'']; 
    What do you think?

  7. #7
    Join Date
    Feb 2012
    Posts
    102
    Ok so I figured out my last question and I have one more question about this issue:

    How could I better format this function:
    PHP Code:
    public function save() {
            
                if (isset(
    $this->_user['id'])) {
                    
    $q "UPDATE contacts SET name='{$this->_user['name']}', email='{$this->_user['email']}' WHERE id={$this->_user['id']}";
                    
    $r $this->dbc->query($q);
                    return 
    $this;
                }else{ 
                    
    $q "INSERT INTO contacts (name, email) VALUES ('{$this->_user['name']}', '{$this->_user['email']})";
                    
    $r $this->dbc->query($q);
                    if (
    $this->dbc->affected_rows == 1) {
                        
    $this->_user['id'] = $this->dbc->insert_id;
                        return 
    $this;
                    }
                }
            } 
    so it checks for an id value and if there is no id it runs an insert. If there is an id then it runs an update. The update portion is working but the insert is not.

  8. #8
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,611
    Try changing this...
    PHP Code:
    if (isset($this->_user['id'])) { 
    ...to this...
    PHP Code:
    if (!empty($this->_user['id'])) { 
    You initialize $_user to be an array, so it is always "set" (I believe).
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  9. #9
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,611
    Never mind, I was reading that as testing if $_user was set, not the specific array element -- unless you set that element to an empty string if it's not yet set (as opposed to NULL)?
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  10. #10
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,611
    PS: Here's a way you could avoid some code repetition:
    PHP Code:
        public function save() {    
            if (!empty(
    $this->_user['id'])) {
                
    $sql "UPDATE contacts SET name='{$this->_user['name']}', email='{$this->_user['email']}' WHERE id={$this->_user['id']}";
            }
            else {
                
    $sql "INSERT INTO contacts (name, email) VALUES ('{$this->_user['name']}', '{$this->_user['email']})";
            }
            
    $r $this->dbc->query($sql);
            if(
    $r == false) {
                throw new 
    Exception($this->dbc->error.PHP_EOL.$sql);
            }
            if (empty(
    $this->_user['id']) and $this->dbc->affected_rows == 1) {
                    
    $this->_user['id'] = $this->dbc->insert_id;
            }
            return 
    $this;
        } 
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  11. #11
    Join Date
    Apr 2010
    Posts
    227
    Hi

    You could use this instead:

    PHP Code:
      $q "INSERT INTO contacts (name, email) VALUES ('{$this->_user['name']}', '{$this->_user['email']})
    ON DUPLICATE KEY UPDATE SET name='
    {$this->_user['name']}', email='{$this->_user['email']}'"
    Personally I like stripping sql code out into its own class like so

    PHP Code:




    class DBClass {

    function 
    update($table$key$data = array()){
            try{
                
    $dbh = new PDO("mysql:host=$this->hostname;dbname=$this->database","$this->username","$this->password");
            }
            catch(
    PDOException $e){
                
    $dbh null;    
            } 
            
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARESfalse);
            
    $dbh->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);

            
    $string "UPDATE $table SET ";
            
    $fields "";
            
    $values = array();
            foreach(
    $data as $key => $value){              
                
    $fields .= "$key=?,";               
                
    $values[] = $value;   
            }
            
    $fields substr($fields0, -1);             
            
    $values[] = $key;  
            
    $string .= $fields." WHERE id=?";
            
    $query $dbh->prepare($string);
            
    $query->execute($values);
            
            
    $dbh null;   
    }

    function 
    insert($table$data){
            try{
                
    $dbh = new PDO("mysql:host=$this->hostname;dbname=$this->database","$this->username","$this->password");
            }
            catch(
    PDOException $e){
                
    $dbh null;    
            } 

            
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARESfalse);
            
    $dbh->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);

            
    $string "INSERT INTO $table ";
            
    $fields "(";
            
    $values "(";
            foreach(
    $data as $key => $value){              
                
    $fields .= "$key,";               
                
    $values .= "?,";   
                
    $data2[] = $value;
            }
            
    $fields substr($fields0, -1);
            
    $values substr($values0, -1);
            
    $fields .= ")";
            
    $values .= ")";
            
    $string .= $fields." values ".$values;
            
    $query $dbh->prepare($string);
            
    $query->execute($data2);
            
            
    $dbh null;    
    }
    }

    //usage

        
    $values = array('columnAname' => $valueA,'columnBname' => $valueB);  
        
    $dbobject = new DBClass(); 
        
    $dbobject->update("tablename",$key$values); 

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles