how to use PDO connection object in different files [duplicate] - php

This question already has an answer here:
How to use PDO connection in other classes?
(1 answer)
Closed 2 years ago.
Hello i am new to PDO with MYSQL, here are my two files
1) index.php
require_once 'prd.php';
try{
$db = new PDO ('mysql:host=xxxx;dbname=xxx;charset=utf8', 'xxx', 'xxxx');
echo 'connectd';
}catch(PDOException $conError){
echo 'failed to connect DB' . $conError->getMessage ();
}
$conn = new prdinfo();
$conn->con($db);
2) product.php
class prdinfo{function con($db){
try{
foreach($db->query("select * from products where vendor_id = 2" ) as $row){
$prod_id = $row ['product_id'];
echo '<br/>' . $prod_id;
}
}catch(PDOException $ex){
echo 'an error occured' . $ex->getMessage();
}
}
}
my problem is here i can pass the connection object to every file, but i have so many files to use database queries, so i need to pass the $bd to all the files. this is getting burden on the code. so is there any way to connect the database with PDO.
Thanks

pdo.php, taken from here. People often overlook many important connection options, so I had to write a dedicated article that explains how to connect with PDO properly
product.php
<?php
class prdinfo
{
function __construct($db)
{
$this->db = $db;
}
function getVendor($vendor)
{
$sql = "select * from products where vendor_id = ?";
$stm = $this->db->prepare($sql);
$stm->execute(array($vendor));
return $stm->fetchAll();
}
}
index.php
<?php
require 'pdo.php';
require 'product.php';
$info = new prdinfo($pdo);
$vendor = $info->getVendor(2);
foreach ($vendor as $row)
{
echo $row['product_id'];
}
It would be also a good idea to implement class autoloading instead of manually calling require.

The simplest way of doing it is to do the database connectivity in a separate file like "database.php and then you can include this file on every new page you are creating...eg if you are creating a page like "dothis.php". then at the top of your dothis.php page write a statement include_once ('/path/to/your/file/database.php');
then you can use your $db object in the whole file wherever you want.

What you can do is to create a PHP file, let's say 'pdoconn.php'. In that file, prepare that $db object. Finally, for each of your PHP files, just include pdoconn.php at first. So, while your PHP files are being loaded, they will firstly connect to MySQL and give you the $db object.

Related

PHP: Why isn't my count(); printing out my array? [duplicate]

This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 5 years ago.
I'm currently doing a populating/editing my DB using PHP on a webpage I'm going to build. I'm relatively new to PHP so please excuse my "greenhorn" knowledge. My DB connection works, however, I don't understand why my function "displaySQL" and then counting the quantity as an array is not generating anything on my webpage. There's no number displayed on the screen, I was going to have that value put inside an HTML table afterwards. My DB settings are also established for the parameter part (host, username, password). Thanks for any help.
class User{
var $conn;
function __construct($hostname,$username,$password){
try{
$conn = new PDO("mysql:host=$hostname;dbname=pjj5",
$username, $password);
echo "Connected successfully <br>";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
}
//display all users information
function displaySQL(){
$sql = "SELECT * FROM accounts";
$q = $conn->prepare($sql);
$q->execute();
$results = $q->fetchAll();
return $results;
}
$db = new User($hostname,$username,$password);
$res = $db->displaySQL();
echo count($res);
To access a variable of an object within the object you need to use the syntax $this->.
This line:
$conn = new PDO("mysql:host=$hostname;dbname=pjj5",
$username, $password);
and this line
$q = $conn->prepare($sql);
should have $this->conn instead of $conn. In the first function you create the connection to a new $conn variable that is local in scope to the function only, which gets discarded after the object is constructed. For the function displaySQL() $conn is undefined.

Classes and methods with PDO, and retrieving the data

I'm new to OOP programming, and I'm really lost with this what the title says. When I try to put the query in a class and in another file, I get errors in a file called Main.php and don't even know what to do to fix them:
Notice: Undefined variable: sth in Select.php on line 10
Fatal error: Cannot access empty property in Select.php on line 10
If I put the select in Connection.php, it returns the rows just fine, but with classes, I get those.
Here's my code:
Connection.php:
<?php
$hostname = 'localhost';
$username = 'user';
$password = 'pass';
function connectDB ($hostname, $username, $password){
$dbh = new PDO("mysql:host=$hostname;dbname=database", $username, $password);
return $dbh;
}
$dbh = connectDB ($hostname, $username, $password);
echo 'Connected to database <br/>';
Select.php:
<?php require_once 'Connection.php';
class Select {
public function select() {
$sql= "select * from table limit 10; <br/>";
echo $sql;
$select = $dbh->query($sql)->fetchall(PDO::FETCH_ASSOC);
foreach($this->$sth as $row){
echo $row['column']."<br/>";
}
}
}
The question is, how can I print the result from the query (for example from main.php, which has an autoloader), and why do I get those errors, when on a single file, they work just fine?
Edit:
<?php
$test = new Select($dbh);
echo $test->select();
?>
Besides the fixes in the replies, I included Connection.php into the main.php, changed the echo in Select.php to return and it works perfectly now. Adding this in case someone ever gets as lost as me.
You do not want to iterate over the query, but the result of that query. So this probably is what you are looking for:
<?php
class Select {
public function select() {
$sql= 'select * from table limit 10';
$select = $dbh->query($sql)->fetchall(PDO::FETCH_ASSOC);
foreach($select as $row){
echo $row['column']."<br/>";
}
}
}
And you also need to take care that the $dbh object is actually present inside that method. Either inject it into the object or specify it as method argument. So your full class will probably look something like that:
<?php
class Select {
private $dbh;
public function __construct($dbh) {
$this->dbh = $dbh;
}
public function select() {
$sql= 'select * from table limit 10';
$select = $this->dbh->query($sql)->fetchall(PDO::FETCH_ASSOC);
foreach($select as $row){
echo $row['column']."<br/>";
}
}
}
And you instantiate the object like that:
$selectObj = new Select($dbh);
Some general warning, though: Using PDO's fetchall() method is convenient, but carries a huge risk: it means that the full result set has to be copied into an array inside the php script. For bigger results that may lead to issues with memory usage (scripts getting terminated for security reasons). Often it is the better approach to use a while loop over a single row fetched from the result set in each iteration.

Is this right way to use php oop and mysqli?

I am not very experienced in php oop. Moreover, when mysqli comes with php oop, it make me more confused about using it in best efficient way. Anyway, first look at my connection class:
<?php
//connectionclass.php
class connection{
public $conn;
public $warn;
public $err;
function __construct(){
$this->connect();
}
private function connect(){
$this->conn = # new mysqli('localhost', 'sever_user', 'user_password');
if ($this->conn->connect_error) {
$this->conn = FALSE;
$this->warn = '<br />Failed to connect database! Please try again later';
}
}
public function get_data($qry){
$result = $this->conn->query($qry);
if($result->num_rows>=1){
return $result;
}else{
$this->err = $this->conn->error;
return FALSE;
}
$result->free();
}
public function post_data($qry){
$this->conn->query($qry);
if($this->conn->affected_rows>=1){
return TRUE;
}else{
$this->err = $this->conn->error;
return FALSE;
}
}
}
?>
Now please structure of a php page which uses mysql database to store and get data:
<?php
//login.php
include('/include/connectionclass.php');
$db = new connection();
$query = "SELECT * FROM USERS WHERE user_country='India'";
$data = $db->get_data($query);
if($data){
while($row=$data->fetch_assoc()){
echo 'User Name: ':.$row["user_name"].' Age: '.$row["age"];
}
}
?>
So my login.php uses connection class to get data about users. All the things are running well. But one things made me confused. In connectionclass.php $this->conn is itself an object as it calls new mysqli. So this is an object inside another object $db. Moreover, When I am using $data = $db->get_data($query);, a result set is created inside object $db by method get_data, then this result set is copied into a variable $data inside login.php page.
So according to me, actually two result sets/data sets are creating here, one inside db object and one inside login page. Is it right way to use mysqli and php to get dataset from mysql database? Will it use more memory and server resources when the dataset is larger (when have to get large amount of data for many users)?
If it is not right way, please explain your points and please give me code which can be used efficiently for php oop and mysqli.

Is it ok to define PDO db connection in function?

I am thinking, is it safe and OK to use db connection in function to return it anywhere in the project? If I want to reuse this project to build another one, I can change db connection only in this function and I don't need to go all over the script searching and changing connection parameter.
function connect_db(){
$db = new PDO('mysql:host=localhost;dbname=;charset=utf8', '', '');
return $db;
}
Now I can call it anywhere functions.php file is required once, by returning
$db = connect_db();
and then whatever statement follows.
Is it ok and safe?
And how to close connection like this at the end of the page?
$db = NULL;
apparently won't work.
Yes, it is safe and ok to have a single place that creates a connection to your database. I would change your function just a bit though:
<?php
function connect_db(){
try{
return new PDO('mysql:host=localhost;dbname=mydb', 'username', 'password', array(PDO::MYSQL_ATTR_INIT_COMMAND =>'SET NAMES utf8'));
}catch (PDOException $e){
echo '<p>Error connecting to database! ' . $e->getMessage() . '</p>';
die();
}
}
?>
You can read more about the PDO constructor in the documentation.
And to close the PDO connection created this way you do indeed just:
<?php
$pdo = NULL;
?>
Please note that there is really a lot more to be said on this subject. Ideally you would have a class that handles the creation of your PDO object(s). You might want to take a look at this excellent answer from Gordon as a place to start.

Prblems with setting PDO connection global

after reading a lot of post but not getting this thing running, maybe somone can help me with this.
I am trying to include a PHP (Module.php) file which craps information from db into my index.php. This index.php also includes the file with the database connection. The problem is the included file which handles the db selects seems not to know about the PDO Object, the Script dies which this error:
Fatal error: Call to a member function prepare() on a non-object in
I tried to make the PDO Object global. But unfortunately this is not working.
Thanks a lot for any help (and safe me not going crazy ...)
Tony
index.php
//DB Connection
require_once ("include/db_connect_inc.php");
$request = $_GET['Controll'];
switch ($request) {
case 0:
echo "XY";
break;
case 1:
global $objDb;
//This file should be able to use the DB Object
include("modules/Eat/Module.php");
break;
}
Module.php
global $objDb;
$dbSelect = $objDb->prepare(
"SELECT DISTINCT ON (nummer) nummer
FROM tableX
"
);
$dbSelect->execute();
while($row = $dbSelect->fetch(PDO::FETCH_ASSOC)) {
$all = $row['nummer'];
}
echo "1 - " . $all;
db_connect_inc.php
$strDbLocation = 'pgsql:host=localhost;dbname=test';
$strDbUser = 'root';
$strDbPassword = 'root';
try{
$objDb = new PDO($strDbLocation, $strDbUser, $strDbPassword);
$objDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$objDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
global $objDb;
}
catch (PDOException $e){
//echo 'Fehler beim Öffnen der Datenbank: ' . $e->getMessage();
print "Error!: " . $e->getMessage() . "<br/>";
}
As you don't seem to use any functions, your variable is already set in the global scope, so you should get rid of all the global $objDb; lines.
That should solve the problem as long as there is no error in the first 3 lines where you connect to the database.
Apart from that I would use OOP / classes and use dependency injection to make sure my Module class is always provided with the stuff it needs (a db connection in this case).

Categories