0

I have been turning and twisting this to the best of my non-existing PDO knowledge, but still without any luck.

the code:

function write($id, $data) {
        global $dbcon;

        $id = mysql_real_escape_string($id);
        $data = mysql_real_escape_string($data);
        $sql = $dbcon->exec("INSERT INTO `sessions` 
                                        (`session_id`, `session_data`, 
                                         `session_expire`, `session_agent`, 
                                         `session_ip`, `session_referrer`) 
                                        VALUES
                                        (\"".$id."\", \"".$data."\",
                                         \"".time()."\",\"".($this->session_encryption($_SERVER['HTTP_USER_AGENT']))."\",
                                         \"".($this->session_encryption($_SERVER['REMOTE_ADDR']))."\", \"".($this->session_encryption((isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_^~@&|=+;!,(){}[].?%*#'))))."\")
                                        ON DUPLICATE KEY UPDATE 
                                        `session_data` = \"".$data."\",
                                        `session_expire` = \"".time()."\"");
        return true;
    }

Give me the following error:

Fatal error: Call to a member function exec() on a non-object

on the

$sql = $dbcon->exec(

line. I have been trying to solve this all evening, but without any luck.

This is my PDO connection script:

require_once(INC_PATH.'/config.php');

$dsn = "$db_type:host=$db_host;port=$db_port;dbname=$db_name;charset=$db_charset";
try{
    $dbcon = new PDO($dsn, $db_user, $db_pass);
    $dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    //$dbcon = null; //Close database connection.
}
catch(PDOException $e){
    echo $e->getMessage();
}

Hope one of you kind souls out there can help me, I would deeply appreciate it!

Thanks.

UPDATE: I have a global.php file which looks like this:

//Load database
require_once(INC_PATH.'/database.php');

//Load session handler
require_once(INC_PATH.'/class_sessions.php');
$Sessions = new SessionManager();
session_start();

The database.php is included before the sessions class, and when I view the website, it does not give any errors on this part of the sessions class (which is before the write function:

function read($id) {
        global $dbcon;

        $data = '';
        $id = mysql_real_escape_string($id);
        $sql = $dbcon->prepare("SELECT 
                                `session_data` 
                            FROM 
                                `sessions` 
                            WHERE 
                                `session_id` = '".$id."'");

        $sql->execute();

        $a = $sql->columnCount();
        if($a > 0) {
            $row = $sql->fetchObject();
            $data = $row['session_data'];
        }

        return $data;
    }
MrE
  • 1,124
  • 3
  • 14
  • 28
  • 1
    $dbcon is then not an object. Is the "PDO connection script" actually being included and executed? Try and `echo "dbcon created";` after `$dbcon = new PDO($dsn, $db_user, $db_pass);`. – CodeCaster Sep 06 '11 at 19:06
  • I have a global.php file which includes both the sessions-management script (above) and the PDO connection script. One moment, let me try. UPDATE: I can see it echo it just fine. – MrE Sep 06 '11 at 19:08
  • 1
    Is the db script being included first? Also, I would be remiss if I didn't say that you should avoid globals. I won't go into detail on it here since you can google and find a million reasons, but in short: they create a dependence on something you cannot always control and they decrease code portability. – Corbin Sep 06 '11 at 19:11
  • I will update my initial post with more info, 2 sec :) - thanks ! – MrE Sep 06 '11 at 19:12
  • I am quite new to this so sorry for the maybe very obvious question: but how can I avoid globals? – MrE Sep 06 '11 at 19:18
  • @MrE: like this : http://stackoverflow.com/questions/130878/global-or-singleton-for-database-connection – greg0ire Sep 06 '11 at 19:23
  • You can pass the db connection variable to the read() and write() functions. function read($dbcon, $id) { ... } – Ed Manet Sep 06 '11 at 19:24

2 Answers2

2

Are you sure your connection script is getting executed? Try checking if $dbcon is set. Also, you may be missing global $dbcon within the connection script.

By the way, since you're already using PDO, might I recommend you use placeholders in your query:

$sql = "INSERT INTO `sessions` 
    (`session_id`, `session_data`, `session_expire`, 
        `session_agent`, `session_ip`, `session_referrer`) 
    VALUES
    (:session_id, :session_data, :session_expire, 
        :session_agent, :session_ip, :session_referrer)
    ON DUPLICATE KEY UPDATE 
    `session_data` = :session_data,
    `session_expire` = :session_expire";

$params = array(
    ':session_id' => $id,
    ':session_data' => $data,
    ':session_expire' => time(), 
    ':session_agent' => $this->session_encryption($_SERVER['HTTP_USER_AGENT']),
    ':session_ip', => $this->session_encryption($_SERVER['REMOTE_ADDR']),
    ':session_referrer' => $this->session_encryption((isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_^~@&|=+;!,(){}[].?%*#';
);
$stmt = $dbcon->prepare($sql);
if ($stmt->execute($params) === FALSE) {
   // handle error
}
Doug Kress
  • 3,537
  • 1
  • 13
  • 19
  • Thanks! I did a "isset($dbcon)" and it returned false. Now my question is.. how come it is not set? I cannot see the logic at this point. Thanks for pointing me in the right direction. – MrE Sep 06 '11 at 19:28
1

First check that the global object is not being overwritten by another function. I strongly suggest you use Dependency injection instead of globals.

$Sessions = new SessionManager($dbcon);

And inside the Session Management class you can do something like

class SessionManager
{
    protected $db;
    public function __construct($db) { $this->db = $db; }

    public function read($id) 
    {
        $stmt = $this->db->prepare("SELECT session_data
                            FROM sessions
                            WHERE session_id = ?");
        $stmt->execute(array($id));
        return $stmt->fetchColumn();
     }
}

And secondly, since you are using PDO, you dont need to call mysql_real_escape_string(), use prepared statements and placeholders :)

mpratt
  • 1,598
  • 12
  • 21
  • I am quite new to php/sql, so forgive me for my maybe obvious questions. But how would one use dependency injections? and since my PDO connection is called dbcon, would you tell me where that goes in your above code? or have I misunderstood something? Thanks a lot! :) – MrE Sep 06 '11 at 19:39