[RESOLVED] Fatal error: Call to a member function prepare() on a non-object
Page 1 of 2 12 LastLast
Results 1 to 15 of 17

Thread: [RESOLVED] Fatal error: Call to a member function prepare() on a non-object

  1. #1
    Senior Member cluelessPHP's Avatar
    Join Date
    Apr 2015
    Location
    Scotland
    Posts
    324

    resolved [RESOLVED] Fatal error: Call to a member function prepare() on a non-object

    PHP Code:
    <?php       

    error_reporting
    (-1); // reports all errors
    ini_set("display_errors""1"); // shows all errors
    ini_set("log_errors"1);
    ini_set("error_log""php-error.log");


    class 
    Database
    {
            public
            
    $connection,
            
    $host,
            
    $user,
            
    $password,
            
    $dataBase;

        function 
    __construct()
        {
            
    $this->connection false;
            
    $this->host "localhost";
            
    $this->user "root";
            
    $this->password "";
            
    $this->dataBase "soma";
            
    $this->connect();
        }
        
        function 
    connect()
        {
            if(!isset(
    $this->connection))    //test for connection 
            
    {
                    try 
                    {
                        
    $this->connection = new PDO("mysql:host=$this->host;dataBase=$this->dataBase"$this->user$this->password);
                    }
                    catch (
    PDOException $e
                    {
                        echo 
    $e->getMessage();
                        die();
                    }
            }
            if (!
    $this->connection//if no connection end 
            
    {    
                function 
    __destruct() 
                {
                     
    $this->connection null;
                }
            }
            else
            {
                return 
    $this->connection;
            }    
        }    
        
    }


    class 
    Username extends Database
        
    {
    //basic test insert 
         
    public function insert() 
            {

                
    $test $this->connection->prepare("INSERT INTO username (username) VALUES ('Yeaaap')");
                
    $test->execute();
                
            }
        }

    $tester = new Username(); 
    $tester->insert();
    var_export($test);

    It "should be a database class which will extend so I can insert into it current error message

    PHP Code:
    Fatal errorCall to a member function prepare() on a non-object in ... on line 64 
    You need to believe in things that aren't true. How else can they become?― Terry Pratchett, Hogfather
    Blog

    Six month project

  2. #2
    Pedantic Curmudgeon Weedpacket's Avatar
    Join Date
    Aug 2002
    Location
    General Contact Unit "Coping Mechanism"
    Posts
    22,395
    When connect is first called, $this->connection has already been set (to false, so the actual connection doesn't happen.

    I suggest you replace false in the constructor there with null. A variable containing null doesn't count as being set.
    THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER
    FAQs! FAQs! FAQs! Most forums have them!
    Search - Debugging 101 - Collected Solutions - General Guidelines - Getting help at all

  3. #3
    High Energy Magic Dept. NogDog's Avatar
    Join Date
    Aug 2006
    Location
    Ankh-Morpork
    Posts
    14,675
    The other option is to test for empty() instead of !isset() -- mainly a stylistic thing, though Weedpacket's suggestion might save a microsecond or two, since it only needs to check if it's set.
    Last edited by NogDog; 02-17-2017 at 04:03 PM.
    "Well done....Consciousness to sarcasm in five seconds!" ~ Terry Pratchett, Night Watch

    How to Ask Questions the Smart Way (not affiliated with this site, but well worth reading)

    My Blog
    cwrBlog: simple, no-database PHP blogging framework

  4. #4
    Senior Member Derokorian's Avatar
    Join Date
    Apr 2011
    Location
    Denver
    Posts
    2,232
    Quote Originally Posted by Weedpacket View Post
    When connect is first called, $this->connection has already been set (to false, so the actual connection doesn't happen.

    I suggest you replace false in the constructor there with null. A variable containing null doesn't count as being set.
    Or just don't assign it at all in the constructor, since an uninitialized variable (IE empty property) is already null, and the purpose of the connect is to set it anyway.
    Sadly, nobody codes for anyone on this forum. People taste your dishes and tell you what is missing, but they don't cook for you. ~anoopmail
    I'd rather be a comma, then a full stop.
    User Authentication in PHP with MySQLi - Don't forget to mark threads resolved - MySQL(i) warning

  5. #5
    Senior Member cluelessPHP's Avatar
    Join Date
    Apr 2015
    Location
    Scotland
    Posts
    324
    PHP Code:
    <?php       

    error_reporting
    (-1); // reports all errors
    ini_set("display_errors""1"); // shows all errors
    ini_set("log_errors"1);
    ini_set("error_log""php-error.log");


    class 
    Database 
        
    {
            
            protected 
            
    $host,
            
    $dbname,
            
    $user,
            
    $password,
            
    $db;

            function 
    __construct($host "",$dbname "",$user "",$password ""
            {
                
    $this->host "localhost";
                
    $this->user "root";
                
    $this->password "";
                
    $this->dataBase "soma";
                
                try 
                {
                    
    $this->db = new PDO("mysql:host=$this->host;dbname=$this->dataBase"$this->user$this->password);
                }
                catch (
    PDOException $e
                {
                    echo 
    $e->getMessage();
                    die();
                }    
                
            }
                    
            function 
    testConnection()
            {
                
                if (!
    $this->db//if no connection end 
                
    {    
                    
    $this->db true
                }
                else
                {
                    function 
    __destruct() 
                    {
                        return    
    $this->db null;
                        throw new 
    Exception('DOH!!');
                        return 
    false;                      
                    }
                }    
                
            }

        }


    class 
    Username extends Database
        
    {
    //basic test insert 
         
    public function insert() 
            {    
                
    $test $this->db->prepare("INSERT INTO username (username) VALUES ('Yeaaap')");
                
    $test->execute();
                echo 
    "got it";
            }
        }

    $tester = new Username(); 
    $tester->insert();
    //var_export($tester);
    The problem with this, it allows me to insert but I veuagley suspect it's wrong
    You need to believe in things that aren't true. How else can they become?― Terry Pratchett, Hogfather
    Blog

    Six month project

  6. #6
    High Energy Magic Dept. NogDog's Avatar
    Join Date
    Aug 2006
    Location
    Ankh-Morpork
    Posts
    14,675
    A few things to consider...

    1. You can simply(?) have your Database class extend PDO, adding a few tweaks to let you put your DB config within the class, if that's what you'd like to do.
    PHP Code:
    class Database extends PDO
    {
        private 
    $host   'localhost';
        private 
    $user   'root';
        private 
    $pass   '';
        private 
    $dbname 'soma';

        public function 
    __construct($dsn null$user null$pass null$opts null)
        {
            
    parent::__construct(
                
    "mysql:host={$this->host};dbname={$this->dbname}",
                
    $this->user,
                
    $this->pass,
                
    $opts
            
    );
            
    $this->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);
        }

    2. Since Username is not a database thing, but something that uses a database thing (a.k.a. object), in this case I would not have it extend the Database class, but instead use it via composition, in this case passing an already created PDO object into the class's constructor.
    PHP Code:
    class Username
    {
        private 
    $pdo;

        public function 
    __construct(PDO $pdo)
        {
            
    $this->pdo $pdo;
        }

        public function 
    create($username)
        {
            
    $sql "INSERT INTO username (username) VALUES (:username)";
            
    $stmt $this->pdo->prepare($sql);
            
    $stmt->bindParam(':username'$username);
            
    $stmt->execute();
            return 
    $stmt->rowCount();
        }

    Then to use it:
    PHP Code:
    $db = new Database();
    $username = new Username($db);
    $username->create('NogDog'); 
    Note that since Database is a child of PDO, it counts as being a PDO-type object with regard to the type-hinting for Username's constructor.
    "Well done....Consciousness to sarcasm in five seconds!" ~ Terry Pratchett, Night Watch

    How to Ask Questions the Smart Way (not affiliated with this site, but well worth reading)

    My Blog
    cwrBlog: simple, no-database PHP blogging framework

  7. #7
    Senior Member cluelessPHP's Avatar
    Join Date
    Apr 2015
    Location
    Scotland
    Posts
    324
    PHP Code:
    class Database extends PDO 
    Oh I think I understand, PDO is a class in php so by extending it you're taking advantage of pre-existing erm...wrappers?/classes?
    You need to believe in things that aren't true. How else can they become?― Terry Pratchett, Hogfather
    Blog

    Six month project

  8. #8
    High Energy Magic Dept. NogDog's Avatar
    Join Date
    Aug 2006
    Location
    Ankh-Morpork
    Posts
    14,675
    Quote Originally Posted by cluelessPHP View Post
    PHP Code:
    class Database extends PDO 
    Oh I think I understand, PDO is a class in php so by extending it you're taking advantage of pre-existing erm...wrappers?/classes?
    Yep. You could do the same sort of thing with the MySQLi class if you wanted to (I wouldn't ), but you could not do it with the old MySQL extension, since it was just a set of functions. So your new Database class becomes a specific implementation of the PDO class by extending it, inheriting all its methods and properties, then adding to those or overriding them as needed. On the other hand, a User is not a specific case of a database, so it doesn't make much sense to have it be a child of (extend) either PDO or its child Database class. It does, however, need access to the database, so by passing any PDO-type object into it via its constructor, you now have a sort of contract in place saying, "You can only use me if you give me a PDO object that I can use."
    "Well done....Consciousness to sarcasm in five seconds!" ~ Terry Pratchett, Night Watch

    How to Ask Questions the Smart Way (not affiliated with this site, but well worth reading)

    My Blog
    cwrBlog: simple, no-database PHP blogging framework

  9. #9
    Senior Member Derokorian's Avatar
    Join Date
    Apr 2011
    Location
    Denver
    Posts
    2,232
    Quote Originally Posted by NogDog View Post
    Yep. You could do the same sort of thing with the MySQLi class if you wanted to (I wouldn't ), but you could not do it with the old MySQL extension, since it was just a set of functions. So your new Database class becomes a specific implementation of the PDO class by extending it, inheriting all its methods and properties, then adding to those or overriding them as needed. On the other hand, a User is not a specific case of a database, so it doesn't make much sense to have it be a child of (extend) either PDO or its child Database class. It does, however, need access to the database, so by passing any PDO-type object into it via its constructor, you now have a sort of contract in place saying, "You can only use me if you give me a PDO object that I can use."
    Another benefit of using the database class in the username class, is it becomes easier to change the database connection the class uses. Instead of changing the definition of the class, you can simply construct it with a different database object.

    PHP Code:
    $db = new Database2(); // same class with different connection parameters
    $username = new Username($db); 
    $username->create('NogDog'); 
    now You've saved to an entirely new connection without having to restructure your classes.
    Sadly, nobody codes for anyone on this forum. People taste your dishes and tell you what is missing, but they don't cook for you. ~anoopmail
    I'd rather be a comma, then a full stop.
    User Authentication in PHP with MySQLi - Don't forget to mark threads resolved - MySQL(i) warning

  10. #10
    Senior Member cluelessPHP's Avatar
    Join Date
    Apr 2015
    Location
    Scotland
    Posts
    324
    Makes sense, going to try work on something I have an idea for now it's quite outside and I can google things again
    You need to believe in things that aren't true. How else can they become?― Terry Pratchett, Hogfather
    Blog

    Six month project

  11. #11
    Settled 4 red convertible dalecosp's Avatar
    Join Date
    Jul 2002
    Location
    Accelerating Windows at 9.81 m/s....
    Posts
    8,364
    And the formal name for this concept is Inheritance.
    /!!\ mysql_ is deprecated --- don't use it! Tell your hosting company you will switch if they don't upgrade! /!!!\ ereg() is deprecated --- don't use it!

    dalecosp "God doesn't play dice." --- Einstein "Perl is hardly a paragon of beautiful syntax." --- Weedpacket

    Getting Help at All --- Collected Solutions to Common Problems --- Debugging 101 --- Unanswered Posts --- OMBE: Office Machines, Business Equipment

  12. #12
    Senior Member cluelessPHP's Avatar
    Join Date
    Apr 2015
    Location
    Scotland
    Posts
    324
    Quote Originally Posted by dalecosp View Post
    And the formal name for this concept is Inheritance.
    Yep. sitting working with classes and functions more now, interacting with them properly is my main concern now
    You need to believe in things that aren't true. How else can they become?― Terry Pratchett, Hogfather
    Blog

    Six month project

  13. #13
    High Energy Magic Dept. NogDog's Avatar
    Join Date
    Aug 2006
    Location
    Ankh-Morpork
    Posts
    14,675
    I found the book "PHP 5 Objects, Patterns, and Practice", by Matt Zandstra, to be a big help to me when I was first trying to really understand OOP.
    "Well done....Consciousness to sarcasm in five seconds!" ~ Terry Pratchett, Night Watch

    How to Ask Questions the Smart Way (not affiliated with this site, but well worth reading)

    My Blog
    cwrBlog: simple, no-database PHP blogging framework

  14. #14
    Senior Member Derokorian's Avatar
    Join Date
    Apr 2011
    Location
    Denver
    Posts
    2,232
    Quote Originally Posted by NogDog View Post
    I found the book "PHP 5 Objects, Patterns, and Practice", by Matt Zandstra, to be a big help to me when I was first trying to really understand OOP.
    +1
    Sadly, nobody codes for anyone on this forum. People taste your dishes and tell you what is missing, but they don't cook for you. ~anoopmail
    I'd rather be a comma, then a full stop.
    User Authentication in PHP with MySQLi - Don't forget to mark threads resolved - MySQL(i) warning

  15. #15
    Senior Member cluelessPHP's Avatar
    Join Date
    Apr 2015
    Location
    Scotland
    Posts
    324
    PHP Code:
    <?php 

    class ShopProduct
    {
        public 
            
    $numPages,
            
    $playLength,
            
    $title,
            
    $producerMainName,
            
    $producerFirstName,
            
    $price;
            
            function 
    __construct($title$firstName$mainName$price$numPages=0$playLength=0)
            {
                
    $this->title $title;
                
    $this->producerFirstName $firstName;
                
    $this->producerMainName $mainName;
                
    $this->price $price;
                
    $this->numPages $numPages;
                
    $this->playLength $playLength;
            }
            
            function 
    getProducer()
            {
            return 
                
    "{$this->producerFirstName} ".
                
    "{$this->producerMainName}";
            }
            
            function 
    getSummaryLine()
            {
                
    $base "$this->title ({$this->producerMainName},";
                
    $base .= "{$this->producerFirstName})";
                return 
    $base;
            }    
    }

    class 
    CdProduct extends ShopProduct
    {
        function 
    getPlayLength()
        {
            return 
    $this->playLength;
        }
        
        function 
    getSummaryLine()
        {
            
    $base "{$this->title} ({$this->producerMainName},";
            
    $base .= "{$this->producerFirstName})";
            
    $base .= ": Playing time - {$this->playLength}";
            return 
    $base;
        }
    }    
    class 
    BookProduct extends ShopProduct
    {
        function 
    getNumberOfPages()
        {
            return 
    $this->numPages;
        }
        
        function 
    getSummaryLine()
        {
            
    $base "{$this->title} ({$this->producerFirstName},";
            
    $base .= "{$this->producerFirstName})";
            
    $base .= ": Page count - {$this->numPages}";
            return 
    $base;
        }
    }

    $product2 = new CdProduct("Exile on Coldharbour lane""The " "Alabama 3"10.99null60.33);
    print 
    "artist: {$product2->getProducer()}\n";
    print 
    "Summary: {$product2->getSummaryLine()}\n";
    It's more a case of this I'm not quite sure about yet, sure I can print static stuff but I will need to be able to dynamically generate stuff too
    PHP Code:
    $product2 = new CdProduct("Exile on Coldharbour lane""The " "Alabama 3"10.99null60.33);
    print 
    "artist: {$product2->getProducer()}\n";
    print 
    "Summary: {$product2->getSummaryLine()}\n"
    You need to believe in things that aren't true. How else can they become?― Terry Pratchett, Hogfather
    Blog

    Six month project

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
  •