Skip to content
Advertisement

How to set pdo timezone at connection

I have this code where I connect to database and the code is working properly. However the now() function of MySQL is out of sync with PHP set default time zone function. I am comparing the PHP date with MySQL now. Therefore, I wanted to set the database time zone as well.

    private $host="9999999";
    private $user="99999999";
    private $pwd="8888888";
    private $dbName="88888888";

    protected function connect(){
        $dsn='mysql:host='.$this->host.';dbname='.$this->dbName;
        $pdo = new PDO($dsn, $this->user, $this->pwd);
    
        $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    
        return $pdo;
    }
    
    



I wanted to set the database time upon connection. I have this code from this site I wanted to adapt it to mine. This is the code below. I came across this code and I thought it could be of help but I am finding it hard to implement with my already working code.

$now = new DateTime();
$mins = $now->getOffset() / 60;
$sgn = ($mins < 0 ? -1 : 1);
$mins = abs($mins);
$hrs = floor($mins / 60);
$mins -= $hrs * 60;
$offset = sprintf('%+d:%02d', $hrs*$sgn, $mins);

//Your DB Connection - sample
$pdo = new PDO('mysql:host=localhost;dbname=test', 'dbuser', 'dbpassword');
$pdo->exec("SET time_zone='$offset';");

I got several error when I implemented it. One of which is.

Parse error: syntax error, unexpected ‘new’ (T_STRING), expecting function (T_FUNCTION) in /home/…/…classes/dbh.class.php on line 12. I thought may be I needed to put private and it still throw errors.

Please, how do I implement the two codes together

Link to the code I am adapting is this. Set timezone in PHP and MySQL

FULL CODE 1.(index.php)

$datedefault=date_default_timezone_set($zone['continent'].'/'.$zone['city']);

2.(dbh.class.php)

class Dbh{
    private $host="22222";
    private $user="777777";
    private $pwd="6666";
    private $dbName="55555";
    
    protected function connect(){
$now = new DateTime();
$mins = $now->getOffset() / 60;
$sgn = ($mins < 0 ? -1 : 1);
$mins = abs($mins);
$hrs = floor($mins / 60);
$mins -= $hrs * 60;
$offset = sprintf('%+d:%02d', $hrs*$sgn, $mins);
        $dsn='mysql:host='.$this->host.';dbname='.$this->dbName;
        $pdo = new PDO($dsn, $this->user, $this->pwd);
        $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$pdo->exec("SET time_zone='$offset';");     
return $pdo;
    }
}

This is where I am using the class 3. (user.class.php)

class Users extends Dbh{

    
        protected function getByandbye($email, $phone){
        $sql="SELECT * FROM user WHERE `email`=? OR CONCAT (`pre`,`phone`)=?";
        $stmt= $this->connect()->prepare($sql);
        $stmt->execute([$email, $phone]);
        $user=$stmt->fetch();
        return $user;

    }
}

Advertisement

Answer

You can execute SET time_zone as an initial command. Although you really should use prepared statements all the time, this might be an acceptable hack.

protected function connect() {
    $tz = (new DateTime('now', new DateTimeZone('Asia/Kabul')))->format('P');
    $dsn = 'mysql:host='.$this->host.';dbname='.$this->dbName;
    $pdo = new PDO($dsn, $this->user, $this->pwd, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone='$tz'"
    ]);

    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

    return $pdo;
}

However, I need to point out that such class is completely useless. PDO is a class already and wrapping the connection logic like that serves no purpose. What I would do instead is execute it procedurally without any class.

$tz = (new DateTime('now', new DateTimeZone('Asia/Kabul')))->format('P');

$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone='$tz'"
]);

$stmt = $pdo->prepare('SET time_zone=?');
$stmt->execute([$tz]);

Now you can pass $pdo around to whichever class that needs the connection.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement