0

I've search everywhere for a solution to this problem but nothing has sorted it. There a few questions similar to this on stack but I am confused as to whether I am implementing the solutions properly and it is another issue or if I'm wrong. I would like to know if any has any insight to the problem. I need to access a database from another class but I get the error Fatal error: Call to a member function prepare() on a non-object in demo.php on line 40. Here is my db_connect.php

<?php



class DbConnect {

    function __construct() {        
    }

     /**
     * Establishing database connection
     * @return database connection handler
     */
     function connect() {
       $db = null;
        if (isset($_SERVER['SERVER_SOFTWARE']) &&
             strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false) {
          // Connect from App Engine.
          try{
            $db = new pdo('mysql:unix_socket=/cloudsql/projectid:instance;dbname=guestbook', 'root', 'password');
          }catch(PDOException $ex) {
            die('Unable to connect.');
          }
         } 
         $db = null;
     }
}
?>

Here is where the error is coming from in demo.php

<?php

class Demo {

    private $conn;

    function __construct() {
        require_once dirname(__FILE__) . '/include/db_connect.php';
        // opening db connection
        $db = new DbConnect();
        $this->conn = $db->connect();
    }

    public function getAllChatRooms() {
         $stmt = $this->conn->prepare("SELECT * FROM chat_rooms");
         $stmt->execute();
         $tasks = $stmt->get_result();
         $stmt->close();
         return $tasks;
    }

    public function getAllUsers() {
        $stmt = $this->conn->prepare("SELECT * FROM users");
        $stmt->execute();
        $tasks = $stmt->get_result();
        $stmt->close();
        return $tasks;
    }

    public function getDemoUser() {
         $name = 'Joe Bloggs';
         $email = 'admin@somewebsite.info';
*Error     
 40 ->*  $stmt = $this->conn->prepare("SELECT user_id from users WHERE email = ?");
         $stmt->bind_param("s", $email);
         $stmt->execute();
         $stmt->store_result();
         $num_rows = $stmt->num_rows;
         if ($num_rows > 0) {
             $stmt->bind_result($user_id);
             $stmt->fetch();
             return $user_id;
          } else {
             $stmt = $this->conn->prepare("INSERT INTO users(name, email) values(?, ?)");
            $stmt->bind_param("ss", $name, $email);
            $result = $stmt->execute();
            $user_id = $stmt->insert_id;
            $stmt->close();
            return $user_id;
        }
    }
}
?>

In the function __construct am I not getting an instance of the database and assigning it to $conn ? I don't understand if this is correct or not. I have changed around DBConnect around to see if mysqli would work instead of pdo but that didn't fix anything. If anyone can shed some light on this I will be very grateful.

edit:

I'll rephrase what I am looking for. I would like to know if there is a way to connect mysqli to Google App Engine with SQL so that the pdo issue can be avoided. pdo is only used when connecting to the database and if I can change that to mysqli that I should be able to communicate with demo.php without having to change the methods such as bind_param that is not supported by pdo. Correct? If there is a simple way to update demo.php to work with pdo I am equally happy to do that but I don't know what methods are supported by pdo and I don't know php as a whole. What is the simplest option from a coding point of view and is it possible to use mysqli with GAE or does it have to be pdo? If GAE does not support mysqli can someone please tell me how to go about update the functions in demo.php?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
keith milton
  • 68
  • 10
  • a simple google search was enough to find that : Working with different connection interfaces Google Cloud SQL supports connections from PHP using common connection methods, including PDO_MySQL, mysqli, and MySQL API. PDO_MySQL, mysqli, and MySQL API are enabled by default in App Engine, in development (locally) or in your production (deployed App Engine application). – lisa Apr 14 '16 at 16:16
  • 1
    Regarding your edit, check http://php.net/manual/en/mysqli.construct.php You just have to change the code of your connect method so instead of using pdo it uses mysql... – lisa Apr 14 '16 at 16:18
  • I marked your answer as correct, thank you – keith milton Apr 14 '16 at 16:31
  • Just found the answer to the problem and it had been staring me in the face all day. Thank you for pointing back in the right direction. – keith milton Apr 14 '16 at 16:41

1 Answers1

1

your DbConnect::connect() function doesn't return the pdo object created. So basically when you do:

$this->conn = $db->connect();

you're doing:

$this->conn = null;

To fix the issue add a return statement at the end of your connect function:

return $db;
lisa
  • 584
  • 2
  • 16
  • I tried what you suggested and it gives me a new error Fatal error: Call to undefined method PDOStatement::bind_param(). As far as i know this is because bind_param is not a method of pdo. So is there a way to change the pdo to mysqli so that I don't have to change much of the demo.php ? I am very new to php and this seems like the easiest option but I have not figured out how to do this. – keith milton Apr 14 '16 at 15:42
  • @keithmilton As this fixed the issue you were asking about, could you please mark the answer as accepted? – lisa Apr 14 '16 at 15:54
  • Regarding this new issue, if you check the PdoStatement doc (http://php.net/manual/en/pdostatement.bindparam.php) you'll see that the function is bindParam() not bind_param() – lisa Apr 14 '16 at 15:55
  • Thank you, i'll check it out now. – keith milton Apr 14 '16 at 16:05