Testing issue in pdo code in php - php

Hi this is my php code:
<?php
function dbConnect() {
global $dbh;
$dbInfo['database_target'] = "localhost";
$dbInfo['database_name'] = "pdo";
$dbInfo['username'] = "root";
$dbInfo['password'] = "";
$dbConnString = "mysql:host=" . $dbInfo['database_target'] . "; dbname=" . $dbInfo['database_name'];
$dbh = new PDO($dbConnString, $dbInfo['username'], $dbInfo['password']);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$error = $dbh->errorInfo();
if($error[0] != "") {
print "<p>DATABASE CONNECTION ERROR:</p>";
print_r($error);
}
}
function dbQuery($queryString) {
global $dbh;
$query = $dbh->query($queryString);
$i = 0;
foreach ($query as $query2) {
$queryReturn[$i] = $query2;
$i++;
}
if($i > 1) {
return $queryReturn;
} else {
return $queryReturn[0];
}
}
dbConnect(); // Connect to Database
?>
when run this code, it shows output like this:
DATABASE CONNECTION ERROR:
Array ( [0] => 00000 [1] => [2] => )
I want to know, this code correct or not, and If any error in this code, please guide me, I am new to pdo.
Thank you.

Don't check errorInfo after making a connection.
PDO throws an exception if connection failed.

Please read the docs:
http://php.net/manual/en/pdo.query.php
http://en.php.net/PDOStatement
PDO::query returns a PDOStatement object. This class has a public property rowCount.
You don't need to iterate over all results, count em etc,..
ALL Code in function dbQuery($queryString) {
Can be replaced by a single line:
return $query->rowCount > 1 ? $query->fetch() : /* else */;

I think you meant global $dbInfo; instead of global $dbh; because dbInfo seems to be undefined in this function unlike dbh.

Related

Uncaught Error: Call to a member function prepare() (PDO, php)

I'm trying to get data from a table using a public function in PHP, but I get this error:
Uncaught Error: Call to a member function prepare() (PDO, php)
I'm searching for 2, 3 hours... But no result is similar or I did not understand.
<?php
class Config {
public static $SQL;
private function __construct() {
$host_name = "localhost";
$base_user = "root";
$base_pass = "";
$base_name = "home_page";
try {
self::$SQL = new PDO("mysql:host=$host_name;dbname=$base_name", $base_user, $base_pass);
self::$SQL->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
die("Something went wrong, database connection closed. Reason: ". $e->getMessage());
}
}
public static function GetData($table, $data, $id) {
$wc = Config::$SQL->prepare('SELECT `'.$data.'` FROM `'.$table.'` WHERE `ID` = ?');
$wc->execute(array($id));
$r_data = $wc->fetch();
return $r_data[$data];
}
}
?>
And I use this in my base file:
<h1><?php echo Config::GetData("page_details", "Moto", 1) ?></h1>
The error is from this line:
$wc = self::$SQL->prepare('SELECT `'.$data.'` FROM `'.$table.'` WHERE `ID` = ?');
Is there any particular reason why you want to use STATICeverywhere? The common approach is using public, dynamic methods and properties. I rewrote your sample with suggested naming convention in PHPs OOP, it works:
<?php
class Config
{
/** #var PDO $conn */
private $conn = null;
public function __construct()
{
$host_name = "localhost";
$base_user = "root";
$base_pass = "";
$base_name = "home_page";
try {
$this->conn = new PDO("mysql:host=$host_name;dbname=$base_name", $base_user, $base_pass);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully"; // <- this is unnnesesary
} catch (PDOException $e) {
die("Something went wrong, database connection closed. Reason: " . $e->getMessage());
}
}
public function findById($table, $data, $id)
{
$stmt = $this->conn->prepare('SELECT `' . $data . '` FROM `' . $table . '` WHERE `uid` = ?');
$stmt->execute(array($id));
return $stmt->fetch(PDO::FETCH_ASSOC);
}
}
// just for test
$cfg = new Config();
print_r($cfg->findById('foo', '*', 1));
or in your case
<?php echo $cfg->findById("page_details", "Moto", 1)['Moto'] ?>

OOP PHP Database results to Array

I am new to the idea of oop php and i am trying to write an irc php.
What I'm trying to do:
I am trying to query my database, get results from my database and put it into an array inside my program.
I tried making a new function to carry out the task and called it in the __construct function.
I have shortened the code but it pretty much looks like this:
Any thoughts and ideas are much appreciated.
class IRCBot
{
public $array = array();
public $servername = "localhost";
public $username = "root";
public $password = "usbw";
public $dbname = "bot";
function __construct()
{
//create new instance of mysql connection
$conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($mysqli->connect_errno)
{
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo $mysqli->host_info . "\n";
$this->database_fetch();
}
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($query);
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row();
}
}
function main()
{
print_r($array);
}
}
$bot = new IRCBot();
Changes
1) Change if ($mysqli->connect_errno) to if ($conn->connect_errno)
2) Change $array[] = $row(); to $array[] = $row;
3) Add return $array; in function database_fetch()
4) Call database_fetch() function inside main() function instead of constructor.
5) Add $this->conn in mysqli_query() (Thanks #devpro for pointing out.)
Updated Code
<?php
class IRCBot
{
public $array = array();
public $servername = "localhost";
public $username = "root";
public $password = "usbw";
public $dbname = "bot";
public $conn;
function __construct()
{
//create new instance of mysql connection
$this->conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($this->conn->connect_errno)
{
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
}
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($this->conn,$query);
while($row = mysqli_fetch_assoc($result)){
$array[] = $row;
}
return $array;
}
function main()
{
$data = $this->database_fetch();
print_r($data);
}
}
Quick Start
Object Oriented Programming in PHP
Classes and Objects
Principles Of Object Oriented Programming in PHP
First of all you need to fix error from your constructor, you can modify as:
function __construct()
{
//create new instance of mysql connection
$this->conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($this->conn->connect_errno)
{
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
echo $this->conn->host_info . "\n";
}
Here, you need to replace $mysqli with $conn because your link identifier is $conn not $mysqli
No need to call database_fetch() here.
You need to use $conn as a property.
Now you need to modify database_fetch() method as:
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($this->conn,$query);
$array = array();
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row;
}
return $array;
}
Here, you need to pass add first param in mysqli_query() which should be link identifier / database connection.
Second, you need to use return for getting result from this function.
In last, you need to modify your main() method as:
function main()
{
$data = $this->database_fetch();
print_r($data);
}
Here, you need to call database_fetch() method here and than print the data where you need.

php mysqli "No database selected" using class

When I'm using mysqli without class it's going ok:
index.php
require_once(dirname(__FILE__) . '/config.php');
$mysqli = new mysqli($hostname, $username, $password, $dbname);
$queryText = "SELECT * FROM User";
if($query = $mysqli->query($queryText)) {
$results = $query->fetch_array();
echo $results['userId'];
} else {
echo "Error ";
echo $mysqli->errno . " " . $this->mysqli->error;
}
?>
But when I start using mysqli with class something goes wrong. connectDB doesn't give any error, so i get connected to DB. But then when trying do any query it give me "No database selected error"
Result of index.php is: Error 1046 No database selected
index.php
<?php
require_once(dirname(__FILE__) . '/banana.php');
$banana = new Banana(1);
if ($banana->connectDB()) {
$banana->doQuery();
}
?>
banana.php
<?php
require_once(dirname(__FILE__) . '/config.php');
class Banana {
private $mysqli, $userId, $query;
function __construct($userId) {
$this->userId = $userId;
}
function __destruct() {
$this->mysqli->close();
}
public function connectDB() { // Подключение к БД
$this->mysqli = new mysqli($hostname, $username, $password, $dbname);
if ($this->mysqli->connect_errno) {
echo "Error (" . $this->mysqli->connect_errno . ") " . $this->mysqli->connect_error;
return false;
}
return true;
}
public function doQuery() {
$queryText = "SELECT * FROM User";
if($this->query = $this->mysqli->query($queryText)) {
$results = $query->fetch_array();
echo $results['userId'];
} else {
echo "Error ";
echo $this->mysqli->errno . " " . $this->mysqli->error;
}
}
?>
So it's very frustrating. I'm about 2 weeks in php, but can't find answer for couple days. I guess the answer is obvious but I can't see it.
Thank you for your time and patience.
One of the first problems you will encounter when you run your script is here:
public function connectDB() { // Подключение к БД
$this->mysqli = new mysqli($hostname, $username, $password, $dbname);
Note that all 4 variables you are using in your function call ($hostname, etc.) are undefined in the scope of the method.
There are several ways you can solve this:
Pass the variables as parameters to the method:public function connectDB($hostname, ...
Pass the necessary variable to your class constructor and set configuration properties in your class that you can use later on;
Use constants instead of variables;
Declare your variables global.
I would recommend one of the first 2 and definitely not the last one.
You can read more in the php manual about variable scope.
It looks like you are a copy'n'paste victim. In doQuery() change:
if($this->query = $this->mysqli->query($queryText)) {
$results = $query->fetch_array();
To:
if($this->query = $this->mysqli->query($queryText)) {
$results = $this->query->fetch_array();

PHP using PDO to store session in DB doesnt produce the errors i expected

SOLVED :
answer is in the 2nd post
i try to store session in DB using PDO, but it doesn't produce errors i expected, please read my code.
here's the code for my session handler class:
class MySessionHandler implements SessionHandlerInterface
{
protected $conn = NULL;
public function open($savePath, $sessionName)
{
if(is_null($this->conn))
{
$dsn = 'mysql:host=localhost;dbname=php_advanced';
$username = 'root';
$password = 'password';
try
{
$this->conn = new PDO($dsn, $username, $password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
$this->conn = NULL;
die('error in open function ' . $e->getMessage());
}
}
return TRUE;
}
public function close()
{
echo '<p>close</p>';
$this->conn = NULL;
return TRUE;
}
public function read($id)
{
echo '<p>read</p>';
$query = 'SELECT data FROM session_table WHERE session_id = :id';
try
{
$pdo = $this->conn->prepare($query);
$pdo->bindValue(':id', $id);
$pdo->execute();
// Kalo query berhasil nemuin id..
if($pdo->rowCount() == 1)
{
list($sessionData) = $pdo->fetch();
return $sessionData;
}
return FALSE;
}
catch(PDOException $e)
{
$this->conn = NULL;
die('error in read function => ' . $e->getMessage());
}
}
public function write($id, $data)
{
echo '<p>write</p>';
$query = 'REPLACE INTO session_table(session_id, data) VALUES(:id, :data)';
try
{
$pdo = $this->conn->prepare($query);
$pdo->bindValue(':id', $id);
$pdo->bindValue(':data', $data);
$pdo->execute();
// return the value whether its success or not
return (bool)$pdo->rowCount();
}
catch(PDOException $e)
{
$this->conn = NULL;
die('error in write function => ' . $e->getMessage());
}
}
public function destroy($id)
{
echo '<p>destroy</p>';
$query = 'DELETE FROM session_table WHERE session_id = :id LIMIT 1';
try
{
$pdo = $this->conn->prepare($query);
$pdo->bindValue(':id', $id);
$pdo->execute();
$_SESSION = array();
return (bool)$pdo->rowCount();
}
catch(PDOException $e)
{
$this->conn = NULL;
die('error in destroy function => ' . $e->getMessage());
}
}
public function gc($maxLifeTime)
{
echo '<p>garbage collection</p>';
$query = 'DELETE FROM session_table WHERE DATE_ADD(last_accessed INTERVAL :time SECOND) < NOW()';
try
{
$pdo = $this->conn->prepare($query);
$pdo->bindValue(':time', $maxLifeTime);
$pdo->execute();
return TRUE;
}
catch(PDOException $e)
{
$this->conn = NULL;
die('error in gc function => ' . $e->getMessage());
}
}
}
$SessionHandler = new MySessionHandler();
session_set_save_handler($SessionHandler);
session_name('my_session');
session_start();
i remove the session_write_close on purpose. This probably sounds stupid, but i want to get the session error to learn more..
here's session script(using the book's code):
require('session_class.php');
?><!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>DB Session Test</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<?php
// Store some dummy data in the session, if no data is present:
if (empty($_SESSION)) {
$_SESSION['blah'] = 'umlaut';
$_SESSION['this'] = 3615684.45;
$_SESSION['that'] = 'blue';
// Print a message indicating what's going on:
echo '<p>Session data stored.</p>';
} else { // Print the already-stored data:
echo '<p>Session Data Exists:<pre>' . print_r($_SESSION, 1) . '</pre></p>';
}
// Log the user out, if applicable:
if (isset($_GET['logout'])) {
session_destroy();
echo '<p>Session destroyed.</p>';
} else { // Otherwise, print the "Log Out" link:
echo 'Log Out';
}
// Reprint the session data:
echo '<p>Session Data:<pre>' . print_r($_SESSION, 1) . '</pre></p>';
// Complete the page:
echo '</body>
</html>';
// Write and close the session:
// session_write_close() <<<<<--- I REMOVE THIS ON PURPOSE TO GET ERROR
?>
but i dont get any error, then i try to use book's mysqli script to connect db and it produces error i expected because i removed the session_write_close()..
can anyone explain why if im using PDO it doesn't generate error? i'm even dont use
register_shutdown_function('session_write_close');
in my session class destructor (on purpose)
NOTE : I'm doing this on purpose because i want to learn more.
the error im expecting is like when im using mysqli connection(connection closed by php at the end of script then session try to write and close but no connection available) :
Warning: mysqli_real_escape_string() expects parameter 1 to be mysqli, null given in /var/www/ullman_advance/ch3/ullman_db.php on line 66
Warning: mysqli_real_escape_string() expects parameter 1 to be mysqli, null given in /var/www/ullman_advance/ch3/ullman_db.php on line 66
Warning: mysqli_query() expects parameter 1 to be mysqli, null given in /var/www/ullman_advance/ch3/ullman_db.php on line 67
Warning: mysqli_close() expects parameter 1 to be mysqli, null given in /var/www/ullman_advance/ch3/ullman_db.php on line 33
update 1
i recently figured it out that mysqli needs database connection everytime it uses mysqli_real_escape_string() and mysqli_query and because of but what im thinking is my pdo also needs db connection when the script ends -> db connection closed -> MySessionHandler will try to write and close, but there's no db connection since pdo has been closed by php, but no error produced..
update 2
i just tried to pass session_set_save_handler function callback and it produces the errors
<?php
$conn = NULL;
function open_session()
{
echo '<p>open session</p>';
global $conn;
$_dsn = 'mysql:host=localhost;dbname=php_advanced';
$_username = 'root';
$_password = 'password';
$conn = new PDO($_dsn, $_username, $_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return TRUE;
}
function close_session()
{
echo '<p>close session</p>';
global $conn;
$conn = NULL;
return TRUE;
}
function read_session($sid)
{
echo '<p>read session</p>';
global $conn;
$query = 'SELECT data FROM session_table WHERE session_id = :sid';
$pdo = $conn->prepare($query);
$pdo->bindValue(':sid', $sid, PDO::PARAM_STR);
$pdo->execute();
if($pdo->rowCount() == 1)
{
list($session_data) = $pdo->fetch();
echo '<pre>';
print_r($session_data);
echo '</pre>';
return $session_data;
}
else
{
return '';
}
}
function write_session($sid, $data)
{
echo '<p>write session</p>';
global $conn;
$query = 'REPLACE INTO session_table(session_id, data) VALUES(:sid, :data)';
$pdo = $conn->prepare($query);
$pdo->bindValue(':sid', $sid, PDO::PARAM_STR);
$pdo->bindValue(':data', $data, PDO::PARAM_STR);
$pdo->execute();
return $pdo->rowCount();
}
function destroy_session($sid)
{
echo '<p>destroy session </p>';
global $conn;
$query = 'DELETE FROM session_table WHERE session_id = :sid';
$pdo = $conn->prepare($query);
$pdo->bindValue(':sid', $sid, PDO::PARAM_STR);
$pdo->execute();
// clean the session array;
$_SESSION = array();
return (bool)$pdo->rowCount();
}
function clean_session($expire)
{
echo '<p>clean session</p>';
global $conn;
$query = 'DELETE FROM session_table WHERE DATE_ADD(last_accessed, INTERVAL :expire SECOND) < NOW()';
$pdo = $conn->prepare($query);
$pdo->bindValue(':expire', $expire, PDO::PARAM_INT);
$pdo->execute();
return $pdo->rowCount();
}
session_set_save_handler('open_session', 'close_session', 'read_session', 'write_session', 'destroy_session', 'clean_session');
session_name('my_session');
session_start();
but still when im passing MySessionHandler class , it doesn't produce error because of no connection.
SOLUTION
sorry guys my mistake actually its a pretty easy answer why MySessionHandler class doesnt produce error wihtout session_write_close() in the end of script,
session_set_save_handler() by default will register session_write_close() to register_shutdown_function()
so if u want to make your own shutdown function for session then use :
session_set_save_handler($SessionClass, FALSE) , if u do this then u must provide session_write_close() in your class destructor
source : http://php.net/manual/en/function.session-set-save-handler.php
thanks for the tips and your attention

Does PHP close SQL connections opened with PDO at the end of the script if I don't explicitly close it?

I know I can close a PDO SQL connection setting the handler to NULL.
But if I don't do that, does PHP close the connection at the end of the script?
Fore example, can I use
$db = new PDO('sqlite:db.sqlite');
/* Code */
if ($cond1) { exit; }
/* More code */
if ($cond2) { exit; }
/* ... */
$db = NULL;
/* Code not related to the database */
... or should I use this:
$db = new PDO('sqlite:db.sqlite');
/* Code */
if ($cond1) {
$db = NULL;
exit;
}
/* More code */
if ($cond2) {
$db = NULL;
exit;
}
/* ... */
$db = NULL;
/* Code not related to the database */
According to the docs:
The connection remains active for the lifetime of that PDO object. To
close the connection, you need to destroy the object by ensuring that
all remaining references to it are deleted--you do this by assigning
NULL to the variable that holds the object. If you don't do this
explicitly, PHP will automatically close the connection when your
script ends.
EXAMPLE.
This is your dbc class
<?php
class dbc {
public $dbserver = 'server';
public $dbusername = 'user';
public $dbpassword = 'pass';
public $dbname = 'db';
function openDb() {
try {
$db = new PDO('mysql:host=' . $this->dbserver . ';dbname=' . $this->dbname . ';charset=utf8', '' . $this->dbusername . '', '' . $this->dbpassword . '');
} catch (PDOException $e) {
die("error, please try again");
}
return $db;
}
function getAllData($qty) {
//prepared query to prevent SQL injections
$query = "select * from TABLE where qty = ?";
$stmt = $this->openDb()->prepare($query);
$stmt->bindValue(1, $qty, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
?>
your PHP page:
<?php
require "dbc.php";
$getList = $db->getAllData(25);
foreach ($getList as $key=> $row) {
echo $row['columnName'] .' key: '. $key;
}
Your connection will be closed as soon as the results are returned
According to the docs When you call exit:
Terminates execution of the script. Shutdown functions and object destructors will always be executed even if exit is called.
This means your PDO connection will be closed. It's always good practice to close it yourself though.

Categories