Search code examples
phpmysqlpdomampunix-socket

PDO Fatal error: Call to a member function prepare() on a non-object (using classes)


I am receiving the following error when loading my index page:

Fatal error: Call to a member function prepare() on a non-object in /Applications/MAMP/htdocs/parse/helloworld/helloworld/libraries/Database.php on line 32

I will place all of the relevant code below, sorry for the length but it should be fairly straight forward to read. The short version is I am practicing PDO and PHP classes so I am remaking an existing project I had on a different machine. (which is why a there is a lot of calls in the index file which acts more like a controller).

I am pulling my hair out here because it works on my other machine and from what i can tell the two projects are identical... I am just getting this error. I had this in my previous project, but that was because I had misspelled the database in the config file... I am 100% positive I did not do that again but I don't know what else I missed -- clearly the PDO class is not being made if I var_dump it returns null... Any and all help would be greatly appreciated (especially if it is in regards to my PDO class style I am just following a blog which seemed to make sense when it worked).

EDIT: After some debugging it was clear that the try block in the database class was failing because a connection could not be established. This was clear after running $this->error = $e->getMessage() which returned:

string(119) "SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/Applications/MAMP/tmp/mysql/mysql.sock' (2)"

As the accepted answer below states the error indicates localhost trying to connect via a unix socket and mysqld not being able to able to accept unix socket connections.

So the original error leads to the ultimate question of: how do you connect to a unix socket when mysqld is not accepting unix socket connections and/or why does mysqld not accept unix socket connections?

End EDIT.

This is my (relevant) PDO class:

<?php
class Database {
private $host = DB_HOST;
private $user = DB_USER;
private $pass = DB_PASS;
private $dbname = DB_NAME;

private $dbh;
private $error;
private $stmt;

public function __construct() {
    // Set DSN
    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
    // Set options
    $options = array (
            PDO::ATTR_PERSISTENT => true,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
    );
    // Create a new PDO instanace
    try {
        $this->dbh = new PDO ($dsn, $this->user, $this->pass, $options);
    }       // Catch any errors
    catch ( PDOException $e ) {
        var_dump($dsn);
        $this->error = $e->getMessage();
    }
}


public function query($query) {
    $this->stmt = $this->dbh->prepare($query);
}

This is the index file that gets called

<?php
require('core/init.php');

//Create objects...
$type = new Type;
$post = new Post;
$group = new Group;
$follower = new Follower;

//Create template object
$template = new Template('templates/front.php');

$template->types = $type->getAllTypes();
$template->groups = $group->getAllGroups();
$template->posts = $post->getAllPosts();
$template->replies = $post->getReplies();
$template->followers = $follower->getAllFollowers();

echo $template;

and these are the other relevant files: config --

<?php

//DB Params
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASS", "root");
define("DB_NAME", "dobbletwo");
define("SITE_TITLE", "Welcome To Dooble!");

init --

//include configuration
require_once('config/config.php');

//helper functions
require_once('helpers/photo_helper.php');
require_once('helpers/system_helper.php');


//Autoload Classes
function __autoload($class_name){
    require_once('libraries/'.$class_name . '.php');
}

for the sake of brevity (which may be far gone at this point I will only show one of the classes i load to prove that I am constructing the db(type, post, group, follower, template...)

<?php

class Type {
//Initialize DB variable
public $db;

/*
*   Constructor
*/
public function __construct(){
    $this->db = new Database;
}

Solution

  • the mysql libraries seem to interpret localhost as meaning you want to connect via a unix socket. your error indicates your mysqld isn't setup to accept unix socket connections.

    to connect via tcp/ip instead, change define("DB_HOST", "localhost"); to define("DB_HOST", "127.0.0.1");