php pdo connection scope - php

Hey guys I have a connection class I found for pdo. I am calling the connection method on the page that the file is included on. The problem is that within functions the $conn variable is not defined even though I stated the method was public, and I was wondering if anyone had an elegant solution other then using global in every function. Any suggestions are greatly appreciated.
CONNECTION
class PDOConnectionFactory{
// receives the connection
public $con = null;
// swich database?
public $dbType = "mysql";
// connection parameters
// when it will not be necessary leaves blank only with the double quotations marks ""
public $host = "localhost";
public $user = "user";
public $senha = "password";
public $db = "database";
// arrow the persistence of the connection
public $persistent = false;
// new PDOConnectionFactory( true ) <--- persistent connection
// new PDOConnectionFactory() <--- no persistent connection
public function PDOConnectionFactory( $persistent=false ){
// it verifies the persistence of the connection
if( $persistent != false){ $this->persistent = true; }
}
public function getConnection(){
try{
// it carries through the connection
$this->con = new PDO($this->dbType.":host=".$this->host.";dbname=".$this->db, $this->user, $this->senha,
array( PDO::ATTR_PERSISTENT => $this->persistent ) );
// carried through successfully, it returns connected
return $this->con;
// in case that an error occurs, it returns the error;
}catch ( PDOException $ex ){ echo "We are currently experiencing technical difficulties. We have a bunch of monkies working really hard to fix the problem. Check back soon: ".$ex->getMessage(); }
}
// close connection
public function Close(){
if( $this->con != null )
$this->con = null;
}
}
PAGE USED ON
include("includes/connection.php");
$db = new PDOConnectionFactory();
$conn = $db->getConnection();
function test(){
try{
$sql = 'SELECT * FROM topic';
$stmt = $conn->prepare($sql);
$result=$stmt->execute();
}
catch(PDOException $e){ echo $e->getMessage(); }
}
test();

You can declarate database class where you carrying conn pdo class, then you don't must duplicates instaces of this. And all database operations you can doing by this class. I mean my answer is what you searching.
But i see, you using only PDO hadle class in Product Factory pattern. You can use normal full database support class under PDO (includes queryies execution from one function) and without this design pattern when you don't want to use many database connectors engines.

Related

How to properly set up a PDO connection using anonymous function and closures

With the help of the answer on a post on similar topic Answer by "teresko" I have managed to understand the factory design method to establish connection to my database. But I am unable to implement the logic in my code as I am receiving this error:
Fatal error: Class 'conn' not found in C:\somewhere\db2.php on line 42
Here is my db file:
$provider = function() {
$db_user="root"; // db user
$db_password="";// db password (mention your db password here)
$db_database="cl";// database name
$db_host="localhost"; // db server
$instance = new PDO("mysql:host=$db_host;dbname=$db_database", $db_user, $db_password);
$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
return $instance;
};
$factory = new StructureFactory( $provider );
$conn = $factory->create('conn');
class StructureFactory {
// protected $provider = null;
protected $connection = null;
public function __construct( callable $provider ) {
$this->provider = $provider;
}
public function create($name) {
if ( $this->connection == null ) {
$this->connection = call_user_func( $this->provider );
}
return new $name($this->connection );
}
}
Since I am a new user, I am unable to request this question as a comment on the original answer. Can you guys help me work out where I'm going wrong please? As the original question says, "I would really like to know how to properly connect to a MySQL database using PHP and PDO and make it easy access-able.I'm eager to learn..."
Given you are a new user, just make it simple PDO instance.
$db_user="root"; // db user
$db_password="";// db password (mention your db password here)
$db_database="cl";// database name
$db_host="localhost"; // db server
$db_charset="utf8";
$conn = new PDO("mysql:host=$db_host;dbname=$db_database;charset=$db_charset", $db_user, $db_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

OOP - Connecting to database via __construct [duplicate]

This question already has an answer here:
PHP: mysql_connect not returning FALSE
(1 answer)
Closed 8 years ago.
I'm very new to OOP and am trying to learn it. So please excuse my noobness. I'm trying to connect to mysql and to test whether the connection is successful or not, I'm using if-else conditions.
Surprisingly, the mysql_connect is always returning true even on passing wrong login credentials. Now I'm trying to figure out why it does and after spending about 20 minutes, I gave up. Hence, I came here to seek the help of the community. Here is my code:
class test
{
private $host = 'localhost';
private $username = 'root2'; // using wrong username on purpose
private $password = '';
private $db = 'dummy';
private $myConn;
public function __construct()
{
$conn = mysql_connect($this->host, $this->username, $this->password);
if(!$conn)
{
die('Connection failed'); // this doesn't execute
}
else
{
$this->myConn = $conn;
$dbhandle = mysql_select_db($this->db, $this->myConn);
if(! $dbhandle)
{
die('Connection successful, but database not found'); // but this gets printed instead
}
}
}
}
$test = new test();
Please don't use the mysql_* functions, there are many, many reasons why - which are well documented online. They are also deprecated and due to be removed.
You'd be much better off using PDO!
Also I'd strongly advise abstracting this database code into a dedicated database class, which can be injected where necessary.
On-topic:
That code snippet seems to work for me, have you tried var_dumping $conn? Does that user have correct rights?
I also hope that you don't have a production server which allows root login without a password!
Ignoring the fact that you're using mysql_* functions rather than mysqli or pdo functions, you should utilise exceptions in OOP code rather than die(). Other than that, I can't replicate your problem - it may be that your mysql server is set up to accept passwordless logins.
class test
{
private $host = 'localhost';
private $username = 'root2'; // using wrong username on purpose
private $password = '';
private $db = 'dummy';
private $myConn;
public function __construct()
{
// returns false on failure
$conn = mysql_connect($this->host, $this->username, $this->password);
if(!$conn)
{
throw new RuntimeException('Connection failed'); // this doesn't execute
}
else
{
$this->myConn = $conn;
$dbhandle = mysql_select_db($this->db, $this->myConn);
if (!$dbhandle)
{
throw new RuntimeException('Connection successful, but database not found'); // but this gets printed instead
}
}
}
}
try {
$test = new test();
} catch (RuntimeException $ex) {
die($ex->getMessage());
}

Should objects be created chronologically as class defined?

I am having a strange error while creating objects. While I create an objects in chronological orders as classed defined, it is going on good. But when I change the order or object creation, it gives error.
The classes I am using are as follows:
<?php
class dbClass{
private $dbHost, $dbUser, $dbPass, $dbName, $connection;
function __construct(){
require_once("system/configuration.php");
$this->dbHost = $database_host;
$this->dbUser = $database_username;
$this->dbPass = $database_password;
$this->dbName = $database_name;
}
function __destruct(){
if(!$this->connection){
} else{
mysql_close($this->connection);
}
}
function mysqlConnect(){
$this->connection = mysql_connect($this->dbHost, $this->dbUser, $this->dbPass) or die("MySQL connection failed!");
mysql_select_db($this->dbName,$this->connection);
}
function mysqlClose(){
if(!$this->connection){
} else{
mysql_close($this->connection);
}
}
}
class siteInfo{
private $wTitle, $wName, $wUrl;
function __construct(){
require_once("system/configuration.php");
$this->wTitle = $website_title;
$this->wName = $website_name;
$this->wUrl = $website_url;
}
function __destruct(){
}
function showInfo($keyword){
if($keyword=="wTitle"){
return $this->wTitle;
}
if($keyword=="wName"){
return $this->wName;
}
if($keyword=="wUrl"){
return $this->wUrl;
}
}
}
?>
The problem is when I create objects in the following order, it is working perfectly:
include("system/systemClass.php");
$dbConnection = new dbClass();
$dbConnection -> mysqlConnect();
$siteInfo = new siteInfo();
But if I change the order to following
include("system/systemClass.php");
$siteInfo = new siteInfo();
$dbConnection = new dbClass();
$dbConnection -> mysqlConnect();
It gives error!
Warning: mysql_connect() [function.mysql-connect]: Access denied for user '#####'#'localhost' (using password: NO) in /home/#####/public_html/#####/system/systemClass.php on line 19
MySQL connection failed!
Your problem comes from the unconventional use of a configuration file that is read ONCE, but should be used in all classes.
When you instantiate the dbclass first, the configuration is read, probably variables get assigned, and you use these in the constructor.
After that, instantiating siteinfo will not read that file again, which is less harmful, because you only end up with an empty object that does return a lot of null, but does work.
The other way round, you get a siteinfo object with all the info, but a nonworking dbclass.
My advice: Don't use a configuration file that way.
First step: Remove the require_once - you need that file to be read multiple times.
Second step: Don't read the file in the constructor. Add one or more parameters to the constructor function and pass the values you want to be used from the outside.
Info: You can use PHP code files that configure stuff, but you shouldn't define variables in them that get used outside. This will work equally well:
// configuration.php
return array(
'database_host' => "127.0.0.1",
'database_user' => "root",
// ...
);
// using it:
$config = require('configuration.php'); // the variable now has the returned array

Cant pass mysqli connection to class

I am trying to pass an mysqli database connection to a php class. The code I have so far (cut down for simplicity) is as follows:
db.php
$db_host = 'localhost';
$db_name = 'dbname';
$db_user = 'username';
$db_password = 'password';
$db = array('db_host'=>$db_host,
'db_name'=>$db_name,
'db_user'=>$db_user,
'db_password'=>$db_password);
$dbCon = new mysqli( $db['db_host'],
$db['db_user'],
$db['db_password'],
$db['db_name']);
if (mysqli_connect_errno())
{
die(mysqli_connect_error()); //There was an error. Print it out and die
}
index.php
<?php
require_once($_SERVER["DOCUMENT_ROOT"] . "/db.php");
$sql = "SELECT id FROM usr_clients";
$stmt = $dbCon->prepare( $sql );
if ($stmt)
{
$stmt->execute();
$stmt->bind_result($id);
while($stmt->fetch())
{
$cl = new Client($id, $dbCon);
$cl->doIt();
}
$stmt->close();
}
?>
client.php
<?php
Class Client
{
private $con;
public static $clientCount = 0;
public function __construct( $id, $con )
{
$this->con = $con;
$sql = "SELECT id FROM usr_clients WHERE id = $id";
$stmt = $this->con->prepare( $sql );
if ($stmt)
{
echo "it worked!";
}
else
{
echo "it failed";
}
}
}
?>
Now the index.php page successfully recognises the database connection declared in db.php, and returns a list of all clients. It then loops through each client, and creates a "client" object, passing it the database connection.
It is here that the problem seems to start. In the client class, the database connection is not recognised. I get multiple errors on the page saying "it failed". In the logs, there is a line about calling prepare() on a non object.
Can anyone explain why the connection works in index.php, but not in the client class?
Thanks
Your main problem is assumptions.
You are assuming that there is no connection passed, judging by indirect consequence.
But a programmer should be always logically correct in their reasoning.
Talking of connection? Verify the very connection. var_dump($con) in the constructor. var_dump($this->con) in the method. If it fails - only now you can blame connection and start for the solution.
If not - there is no reason in looking for another connection passing method. Yet it's time to find the real problem.
If your query fails, you have to ask mysql, what's going on, using $this->con->error, as this function will provide you with a lot more useful information than simple "it fails". The right usage I've explained here: https://stackoverflow.com/a/15447204/285587

Singleton holding multiple ADODB connections

A legacy website is exhibiting unexpected behavior with it's database connections. The application connects to several MySQL databases on the same server and the original developer created a "singleton" class that holds connection objects for each of them.
Lately we have been encountering a strange behavior with the class: when a connection to www is created after creating extra, getting the instance of extra returns a connection that has the correct parameters when viewed with var_dump() but is actually connected to the www database.
What could cause this? The code has worked before at some stage. Creating a new connection on each call to getInstance() fixes the problem but I'd like to solve this the right way if possible.
<?php
class DBConnection
{
private static $default;
private static $extra;
private static $intra;
private static $www;
public static function getInstance($dbname = "default")
{
global $db; // This is an array containing database connection parameters
if(!($dbname == "default" || $dbname == "extra" || $dbname == "www" || $dbname == "intra"))
{
$dbname = "default";
}
if (empty(self::$$dbname)) // Making this pass every time fixes the problem
{
try
{
self::$$dbname = ADONewConnection('mysqlt');
if(isset($db[$dbname]))
{
self::$$dbname->connect(DBHOSTNAME, $db[$dbname]["dbusername"], $db[$dbname]["dbpassword"], $db[$dbname]["dbname"]);
}
else
{
// fallback
self::$$dbname->connect(DBHOSTNAME, DBUSERNAME, DBPASSWORD, DBNAME);
}
self::$$dbname->SetFetchMode(ADODB_FETCH_ASSOC);
self::$$dbname->execute("SET NAMES utf8");
return self::$$dbname;
}
catch(Exception $e)
{
exit("DB connection failed");
}
}
else
{
return self::$$dbname;
}
}
}
Here's a simplified example of the class misbehaving:
$cn = DBConnection::getInstance("extra");
$cn->debug = true;
$rs = $cn->execute("SELECT * FROM messages WHERE id = ".$this->id);
The last line fails with the error message "Table www.messages does not exist".
1: You don't need to establish connection in getInstance().
getInstance must not do anything, but return instance of DB class.
2: when you do self::$$dbname->connect(, if (empty(self::$$dbname)) will return you false next time you call it.
Singleton is described here: http://en.wikipedia.org/wiki/Singleton_pattern
What you have - it's just a static method.

Categories