I am thinking to connect to 2 database in my project in php.
one is an existing database from our ticketing system that uses MS ACESS and the other one is the one im using now its MYSQL.
The use of the MS access is just to retrieve data from it and the MYSQL will be used to both retrieve and store data.
Is it possible to connect to both database at the same time??
Short answer: Yes.
Long answer:
You should ensure that your code always uses connection identifiers to avoid confusion and have clean, readable code. (Especially when you connect to both databases using an abstraction layer like ODBC or PDO)
Please look into the PHP Manual on PDO and connection management
Example:
$link_mysql = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$link_msaccess = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\\test.mdb");
// query MySQL DB
foreach($link_mysql->query('SELECT * FROM test') as $row) {
print_r($row);
}
// query MS Access DB
foreach($link_msaccess->query('SELECT * FROM omg_its_access') as $row) {
print_r($row);
}
Example without PDO:
$link_mysql = mysql_connect("localhost", $user, $pass);
mysql_select_db("test", $link_mysql);
$link_msaccess = odbc_connect("odbc:Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\\test.mdb");
// you may omit the link identifier for MySQL, but i suggest to use it explicitly
$res1 = mysql_query('SELECT * FROM test', $link_mysql);
while ($row = mysql_fetch_row($res1)) {
print_r($row);
}
// for ODBC the link identifier is mandatory
$res2 = odbc_exec($link_msaccess, 'SELECT * FROM omg_its_access');
while ($row = odbc_fetch_row($res2)) {
print_r($row);
}
As you see above, the code for the two database drivers differs in its syntax - that is why i suggest to use PDO.
PDO will avoid a lot of hassle and will make switching to another database driver much easier if you decide to do so later. It abstracts all database drivers and gives you a simple interface to handle them all with the same syntax.
if you're using PDO, for example, thats possible. just create one pdo-object for each connection - just use the mysql-driver for mysql and an odbc-connection for access.
Related
When reading on php.net about MySQL functions. I encountered this message
Warning
This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include:
mysqli_connect()
PDO::__construct()
I've read about PDO. How can I update my code to PDO using either MySQL or MSSQL?
I see a lot of code posted on SO implementing my_sql functions. And comments from others (including myself) pressing the questioners to abandon MySQL functions and start using PDO or MySQLI. This post is here to help. You can refer to it as it provides explanation to why they are deprecated and what PDO is, plus a minimal code example to implement PDO.
First of all:
Conversion from mysql functions to PDO is not a simple case of search and replace. PDO is an Object Oriented Programming add on for the PHP language.
That means an other approach in writing the code as with the mysql functions. First why convert?
Why are mysql functions deprecated?
The mysql extension is ancient and has been around since PHP 2.0, released 15 years ago (!!); which is a decidedly different beast than the modern PHP which tries to shed the bad practices of its past. The mysql extension is a very raw, low-level connector to MySQL which lacks many convenience features and is thereby hard to apply correctly in a secure fashion; it's therefore bad for noobs. Many developers do not understand SQL injection and the mysql API is fragile enough to make it hard to prevent it, even if you're aware of it. It is full of global state (implicit connection passing for instance), which makes it easy to write code that is hard to maintain. Since it's old, it may be unreasonably hard to maintain at the PHP core level.
The mysqli extension is a lot newer and fixes all the above problems. PDO is also rather new and fixes all those problems too, plus more.
Due to these reasons* the mysql extension will be removed sometime in the future.
source Deceze
How to implement PDO
PDO offers one solution for connecting to multiple databases. This answer covers only MySQL and MSSQL servers.
Connecting to a MySQL database, prerequisites
This is fairly simple and doesn't require any pre set-up of PHP. Modern PHP installations are standard shipped with a module that allows PDO connections to MySQL servers.
The module is php_pdo_mysql.dll
Connecting to a MSSQL database, prerequisites
This is a more advanced set-up. You need php_pdo_sqlsrv_##_ts.dll or php_pdo_sqlsrv_##_nts.dll drivers. They are version specific hence the ##. At the moment of writing, Microsoft has released
official drivers for PHP 5.5.x. The 5.6 drivers aren't yet officially released by Microsoft, but are available as non-official builds by others.
The module is php_pdo_sqlsrv_##_ts.dll for the thread safe variant
The module is php_pdo_sqlsrv_##_nts.dll for the non-thread safe variant
Connecting to a database using PDO
To connect to a database you need to create a new PDO instance from the PDO construct.
$connection = new PDO(arguments);
The PDO constructor takes 1 required arguments and 3 optional.
DSN or Data Source Name, mostly this is a string containing information about the driver, host and database name. Since PHP 7.4 it can also include username and password.
Username
Password
Options
Connecting to MySQL
$dsn = 'mysql:dbname=databasename;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
Let's take a look at $dsn: First it defines the driver (mysql). Then the database name and finally the host.
Connecting to MSSQL
$dsn = 'sqlsrv:Server=127.0.0.1;Database=databasename';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
Let's take a look at $dsn: First it defines the driver (sqlsrv). Then the host and finally the database name.
When you create the instance a connection is made to the database. You only have to do this once during the execution of a PHP script.
You need to wrap the PDO instance creation in a try-catch clause. If the creation fails a back trace is shown revealing critical information about your application, like username and password. To avoid this catch the errors.
try
{
$connection = new PDO($dsn, $user, $password);
}
catch( PDOException $Exception )
{
echo "Unable to connect to database.";
exit;
}
To throw errors returned by your SQL server add this options to your PDO instance using setAttribute: $connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Performing queries
PDO uses prepared statements. This is a real difference between PDO's approach and mysql functions. The latter was very susceptible to SQL-INJECTION. One would build a query like this:
$SQL = 'SELECT ID FROM users WHERE user = '.$username ;
When a malicious website or person posts the username injector; DROP TABLE users. The results will be devastating. You needed to proof your code by escaping and encapsulating strings and variables with quotes. This had to be done
for every query. On larger websites or poorly maintained code the risk of having a form that allowed SQL injection could become very high. Prepared statements eliminates the chance of first tier SQL injection like the example above.
The PDO drivers act as a man-in-the-middle between your PHP-server and database server, called a data-access abstraction layer. It doesn't rewrite your SQL queries, but do offer a generic way to connect to multiple database types
and handles the insertion of variables into the query for you. Mysql functions constructed the query on execution of the PHP code. With PDO the query actually gets build on the database server.
A prepared SQL example:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
Note the difference; Instead of a PHP variable using $ outside the string, we introduce a variable using : within the string. Another way is:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = ?';
How to perform the actual query
Your PDO instance provides two methods of executing a query. When you have no variables you can use query(), with variables use prepare(). query() is immediately executed upon calling. Please note the object oriented way of the call (->).
$result = $connection->query($SQL);
The prepare method
The prepare method takes two arguments. The first is the SQL string and the second are options in the form of an Array. A basic example
$connection->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
In our SQL string example we've used a named variable called :username. We still need to bind a PHP variable, integer or string to it. We can do this in two ways. Either build an array containing the named variables as key or use the method bindParam or bindValue.
I will explain the array variant and the method bindValue for the sake of simplicity.
Array
You can do something like this for named variables, where you provide the variable as array key:
$queryArguments = array(':username' => $username);
And this for indexed variables (?):
$queryArguments = array($username);
When you have added all the variables you need you can call upon the method execute() to perform the query. Thereby passing the array as argument to the function execute.
$result = $connection->execute($queryArguments);
bindValue
The bindValue method allows you to bind values to the PDO instance. The method takes two required arguments and one optional. The optional arguments set the data-type of the value.
For named variables:
$connection->bindValue(':username', $username);
For indexed variables:
$connection->bindValue(1, $username);
After binding the values to the instance, you can call upon execute without passing any arguments.
$result = $connection->execute();
NOTE: You can only use a named variable once! Using them twice will result in a failure to execute the query. Depending on your settings this will or will not throw an error.
Fetching the results
Again I will only cover the basics for fetching results from the returned set. PDO is a fairly advanced add-on.
Using fetch and fetchAll
If you did a select query or executed a stored procedure that returned a result set:
fetch
fetch is a method that could take up to three optional arguments. It fetches a single row from the result set. By default it returns an array containing the column names as keys and indexed results.
Our example query could return something like
ID EMAIL
1 someone#example.com
fetch will return this as:
Array
(
[ID] => 1
[0] => 1
[EMAIL] => someone#example.com
[1] => someone#example.com
)
To echo all output of a result set:
while($row = $result->fetch())
{
echo $row['ID'];
echo $row['EMAIL'];
}
There are other options you can find here: fetch_style;
fetchAll
Fetches all rows in a single array. Using the same default option as fetch.
$rows = $result->fetchAll();
If you used a query that didn't return results like a insert or update query you can use the method rowCount to retrieve the amount of rows affected.
A simple class:
class pdoConnection {
public $isConnected;
protected $connection;
public function __construct($dsn, $username, $password, $options = array()) {
$this->isConnected = true;
try {
$this->connection = new PDO($dsn, $username, $password, $options);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); //sets the default to return 'named' properties in array.
} catch (PDOException $e) {
$this->isConnected = false;
throw new Exception($e->getMessage());
}
}
public function disconnect() {
$this->connection = null;
$this->isConnected = false;
}
public function query($SQL) {
try {
$result = $this->connection->query($SQL);
return $result;
} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}
public function prepare($SQL, $params = array()) {
try {
$result = $this->connection->prepare($SQL);
$result->execute($params);
return $result;
} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}
}
How to use:
$dsn = 'mysql:dbname=databasename;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$db = new pdoConnection($dsn, $user, $password);
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
$result = $db->prepare($SQL, array(":username" => 'someone'));
while($row = $result->fetch())
{
echo $row['ID'];
echo $row['EMAIL'];
}
When reading on php.net about MySQL functions. I encountered this message
Warning
This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include:
mysqli_connect()
PDO::__construct()
I've read about PDO. How can I update my code to PDO using either MySQL or MSSQL?
I see a lot of code posted on SO implementing my_sql functions. And comments from others (including myself) pressing the questioners to abandon MySQL functions and start using PDO or MySQLI. This post is here to help. You can refer to it as it provides explanation to why they are deprecated and what PDO is, plus a minimal code example to implement PDO.
First of all:
Conversion from mysql functions to PDO is not a simple case of search and replace. PDO is an Object Oriented Programming add on for the PHP language.
That means an other approach in writing the code as with the mysql functions. First why convert?
Why are mysql functions deprecated?
The mysql extension is ancient and has been around since PHP 2.0, released 15 years ago (!!); which is a decidedly different beast than the modern PHP which tries to shed the bad practices of its past. The mysql extension is a very raw, low-level connector to MySQL which lacks many convenience features and is thereby hard to apply correctly in a secure fashion; it's therefore bad for noobs. Many developers do not understand SQL injection and the mysql API is fragile enough to make it hard to prevent it, even if you're aware of it. It is full of global state (implicit connection passing for instance), which makes it easy to write code that is hard to maintain. Since it's old, it may be unreasonably hard to maintain at the PHP core level.
The mysqli extension is a lot newer and fixes all the above problems. PDO is also rather new and fixes all those problems too, plus more.
Due to these reasons* the mysql extension will be removed sometime in the future.
source Deceze
How to implement PDO
PDO offers one solution for connecting to multiple databases. This answer covers only MySQL and MSSQL servers.
Connecting to a MySQL database, prerequisites
This is fairly simple and doesn't require any pre set-up of PHP. Modern PHP installations are standard shipped with a module that allows PDO connections to MySQL servers.
The module is php_pdo_mysql.dll
Connecting to a MSSQL database, prerequisites
This is a more advanced set-up. You need php_pdo_sqlsrv_##_ts.dll or php_pdo_sqlsrv_##_nts.dll drivers. They are version specific hence the ##. At the moment of writing, Microsoft has released
official drivers for PHP 5.5.x. The 5.6 drivers aren't yet officially released by Microsoft, but are available as non-official builds by others.
The module is php_pdo_sqlsrv_##_ts.dll for the thread safe variant
The module is php_pdo_sqlsrv_##_nts.dll for the non-thread safe variant
Connecting to a database using PDO
To connect to a database you need to create a new PDO instance from the PDO construct.
$connection = new PDO(arguments);
The PDO constructor takes 1 required arguments and 3 optional.
DSN or Data Source Name, mostly this is a string containing information about the driver, host and database name. Since PHP 7.4 it can also include username and password.
Username
Password
Options
Connecting to MySQL
$dsn = 'mysql:dbname=databasename;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
Let's take a look at $dsn: First it defines the driver (mysql). Then the database name and finally the host.
Connecting to MSSQL
$dsn = 'sqlsrv:Server=127.0.0.1;Database=databasename';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
Let's take a look at $dsn: First it defines the driver (sqlsrv). Then the host and finally the database name.
When you create the instance a connection is made to the database. You only have to do this once during the execution of a PHP script.
You need to wrap the PDO instance creation in a try-catch clause. If the creation fails a back trace is shown revealing critical information about your application, like username and password. To avoid this catch the errors.
try
{
$connection = new PDO($dsn, $user, $password);
}
catch( PDOException $Exception )
{
echo "Unable to connect to database.";
exit;
}
To throw errors returned by your SQL server add this options to your PDO instance using setAttribute: $connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Performing queries
PDO uses prepared statements. This is a real difference between PDO's approach and mysql functions. The latter was very susceptible to SQL-INJECTION. One would build a query like this:
$SQL = 'SELECT ID FROM users WHERE user = '.$username ;
When a malicious website or person posts the username injector; DROP TABLE users. The results will be devastating. You needed to proof your code by escaping and encapsulating strings and variables with quotes. This had to be done
for every query. On larger websites or poorly maintained code the risk of having a form that allowed SQL injection could become very high. Prepared statements eliminates the chance of first tier SQL injection like the example above.
The PDO drivers act as a man-in-the-middle between your PHP-server and database server, called a data-access abstraction layer. It doesn't rewrite your SQL queries, but do offer a generic way to connect to multiple database types
and handles the insertion of variables into the query for you. Mysql functions constructed the query on execution of the PHP code. With PDO the query actually gets build on the database server.
A prepared SQL example:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
Note the difference; Instead of a PHP variable using $ outside the string, we introduce a variable using : within the string. Another way is:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = ?';
How to perform the actual query
Your PDO instance provides two methods of executing a query. When you have no variables you can use query(), with variables use prepare(). query() is immediately executed upon calling. Please note the object oriented way of the call (->).
$result = $connection->query($SQL);
The prepare method
The prepare method takes two arguments. The first is the SQL string and the second are options in the form of an Array. A basic example
$connection->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
In our SQL string example we've used a named variable called :username. We still need to bind a PHP variable, integer or string to it. We can do this in two ways. Either build an array containing the named variables as key or use the method bindParam or bindValue.
I will explain the array variant and the method bindValue for the sake of simplicity.
Array
You can do something like this for named variables, where you provide the variable as array key:
$queryArguments = array(':username' => $username);
And this for indexed variables (?):
$queryArguments = array($username);
When you have added all the variables you need you can call upon the method execute() to perform the query. Thereby passing the array as argument to the function execute.
$result = $connection->execute($queryArguments);
bindValue
The bindValue method allows you to bind values to the PDO instance. The method takes two required arguments and one optional. The optional arguments set the data-type of the value.
For named variables:
$connection->bindValue(':username', $username);
For indexed variables:
$connection->bindValue(1, $username);
After binding the values to the instance, you can call upon execute without passing any arguments.
$result = $connection->execute();
NOTE: You can only use a named variable once! Using them twice will result in a failure to execute the query. Depending on your settings this will or will not throw an error.
Fetching the results
Again I will only cover the basics for fetching results from the returned set. PDO is a fairly advanced add-on.
Using fetch and fetchAll
If you did a select query or executed a stored procedure that returned a result set:
fetch
fetch is a method that could take up to three optional arguments. It fetches a single row from the result set. By default it returns an array containing the column names as keys and indexed results.
Our example query could return something like
ID EMAIL
1 someone#example.com
fetch will return this as:
Array
(
[ID] => 1
[0] => 1
[EMAIL] => someone#example.com
[1] => someone#example.com
)
To echo all output of a result set:
while($row = $result->fetch())
{
echo $row['ID'];
echo $row['EMAIL'];
}
There are other options you can find here: fetch_style;
fetchAll
Fetches all rows in a single array. Using the same default option as fetch.
$rows = $result->fetchAll();
If you used a query that didn't return results like a insert or update query you can use the method rowCount to retrieve the amount of rows affected.
A simple class:
class pdoConnection {
public $isConnected;
protected $connection;
public function __construct($dsn, $username, $password, $options = array()) {
$this->isConnected = true;
try {
$this->connection = new PDO($dsn, $username, $password, $options);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); //sets the default to return 'named' properties in array.
} catch (PDOException $e) {
$this->isConnected = false;
throw new Exception($e->getMessage());
}
}
public function disconnect() {
$this->connection = null;
$this->isConnected = false;
}
public function query($SQL) {
try {
$result = $this->connection->query($SQL);
return $result;
} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}
public function prepare($SQL, $params = array()) {
try {
$result = $this->connection->prepare($SQL);
$result->execute($params);
return $result;
} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}
}
How to use:
$dsn = 'mysql:dbname=databasename;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$db = new pdoConnection($dsn, $user, $password);
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
$result = $db->prepare($SQL, array(":username" => 'someone'));
while($row = $result->fetch())
{
echo $row['ID'];
echo $row['EMAIL'];
}
When reading on php.net about MySQL functions. I encountered this message
Warning
This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include:
mysqli_connect()
PDO::__construct()
I've read about PDO. How can I update my code to PDO using either MySQL or MSSQL?
I see a lot of code posted on SO implementing my_sql functions. And comments from others (including myself) pressing the questioners to abandon MySQL functions and start using PDO or MySQLI. This post is here to help. You can refer to it as it provides explanation to why they are deprecated and what PDO is, plus a minimal code example to implement PDO.
First of all:
Conversion from mysql functions to PDO is not a simple case of search and replace. PDO is an Object Oriented Programming add on for the PHP language.
That means an other approach in writing the code as with the mysql functions. First why convert?
Why are mysql functions deprecated?
The mysql extension is ancient and has been around since PHP 2.0, released 15 years ago (!!); which is a decidedly different beast than the modern PHP which tries to shed the bad practices of its past. The mysql extension is a very raw, low-level connector to MySQL which lacks many convenience features and is thereby hard to apply correctly in a secure fashion; it's therefore bad for noobs. Many developers do not understand SQL injection and the mysql API is fragile enough to make it hard to prevent it, even if you're aware of it. It is full of global state (implicit connection passing for instance), which makes it easy to write code that is hard to maintain. Since it's old, it may be unreasonably hard to maintain at the PHP core level.
The mysqli extension is a lot newer and fixes all the above problems. PDO is also rather new and fixes all those problems too, plus more.
Due to these reasons* the mysql extension will be removed sometime in the future.
source Deceze
How to implement PDO
PDO offers one solution for connecting to multiple databases. This answer covers only MySQL and MSSQL servers.
Connecting to a MySQL database, prerequisites
This is fairly simple and doesn't require any pre set-up of PHP. Modern PHP installations are standard shipped with a module that allows PDO connections to MySQL servers.
The module is php_pdo_mysql.dll
Connecting to a MSSQL database, prerequisites
This is a more advanced set-up. You need php_pdo_sqlsrv_##_ts.dll or php_pdo_sqlsrv_##_nts.dll drivers. They are version specific hence the ##. At the moment of writing, Microsoft has released
official drivers for PHP 5.5.x. The 5.6 drivers aren't yet officially released by Microsoft, but are available as non-official builds by others.
The module is php_pdo_sqlsrv_##_ts.dll for the thread safe variant
The module is php_pdo_sqlsrv_##_nts.dll for the non-thread safe variant
Connecting to a database using PDO
To connect to a database you need to create a new PDO instance from the PDO construct.
$connection = new PDO(arguments);
The PDO constructor takes 1 required arguments and 3 optional.
DSN or Data Source Name, mostly this is a string containing information about the driver, host and database name. Since PHP 7.4 it can also include username and password.
Username
Password
Options
Connecting to MySQL
$dsn = 'mysql:dbname=databasename;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
Let's take a look at $dsn: First it defines the driver (mysql). Then the database name and finally the host.
Connecting to MSSQL
$dsn = 'sqlsrv:Server=127.0.0.1;Database=databasename';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
Let's take a look at $dsn: First it defines the driver (sqlsrv). Then the host and finally the database name.
When you create the instance a connection is made to the database. You only have to do this once during the execution of a PHP script.
You need to wrap the PDO instance creation in a try-catch clause. If the creation fails a back trace is shown revealing critical information about your application, like username and password. To avoid this catch the errors.
try
{
$connection = new PDO($dsn, $user, $password);
}
catch( PDOException $Exception )
{
echo "Unable to connect to database.";
exit;
}
To throw errors returned by your SQL server add this options to your PDO instance using setAttribute: $connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Performing queries
PDO uses prepared statements. This is a real difference between PDO's approach and mysql functions. The latter was very susceptible to SQL-INJECTION. One would build a query like this:
$SQL = 'SELECT ID FROM users WHERE user = '.$username ;
When a malicious website or person posts the username injector; DROP TABLE users. The results will be devastating. You needed to proof your code by escaping and encapsulating strings and variables with quotes. This had to be done
for every query. On larger websites or poorly maintained code the risk of having a form that allowed SQL injection could become very high. Prepared statements eliminates the chance of first tier SQL injection like the example above.
The PDO drivers act as a man-in-the-middle between your PHP-server and database server, called a data-access abstraction layer. It doesn't rewrite your SQL queries, but do offer a generic way to connect to multiple database types
and handles the insertion of variables into the query for you. Mysql functions constructed the query on execution of the PHP code. With PDO the query actually gets build on the database server.
A prepared SQL example:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
Note the difference; Instead of a PHP variable using $ outside the string, we introduce a variable using : within the string. Another way is:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = ?';
How to perform the actual query
Your PDO instance provides two methods of executing a query. When you have no variables you can use query(), with variables use prepare(). query() is immediately executed upon calling. Please note the object oriented way of the call (->).
$result = $connection->query($SQL);
The prepare method
The prepare method takes two arguments. The first is the SQL string and the second are options in the form of an Array. A basic example
$connection->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
In our SQL string example we've used a named variable called :username. We still need to bind a PHP variable, integer or string to it. We can do this in two ways. Either build an array containing the named variables as key or use the method bindParam or bindValue.
I will explain the array variant and the method bindValue for the sake of simplicity.
Array
You can do something like this for named variables, where you provide the variable as array key:
$queryArguments = array(':username' => $username);
And this for indexed variables (?):
$queryArguments = array($username);
When you have added all the variables you need you can call upon the method execute() to perform the query. Thereby passing the array as argument to the function execute.
$result = $connection->execute($queryArguments);
bindValue
The bindValue method allows you to bind values to the PDO instance. The method takes two required arguments and one optional. The optional arguments set the data-type of the value.
For named variables:
$connection->bindValue(':username', $username);
For indexed variables:
$connection->bindValue(1, $username);
After binding the values to the instance, you can call upon execute without passing any arguments.
$result = $connection->execute();
NOTE: You can only use a named variable once! Using them twice will result in a failure to execute the query. Depending on your settings this will or will not throw an error.
Fetching the results
Again I will only cover the basics for fetching results from the returned set. PDO is a fairly advanced add-on.
Using fetch and fetchAll
If you did a select query or executed a stored procedure that returned a result set:
fetch
fetch is a method that could take up to three optional arguments. It fetches a single row from the result set. By default it returns an array containing the column names as keys and indexed results.
Our example query could return something like
ID EMAIL
1 someone#example.com
fetch will return this as:
Array
(
[ID] => 1
[0] => 1
[EMAIL] => someone#example.com
[1] => someone#example.com
)
To echo all output of a result set:
while($row = $result->fetch())
{
echo $row['ID'];
echo $row['EMAIL'];
}
There are other options you can find here: fetch_style;
fetchAll
Fetches all rows in a single array. Using the same default option as fetch.
$rows = $result->fetchAll();
If you used a query that didn't return results like a insert or update query you can use the method rowCount to retrieve the amount of rows affected.
A simple class:
class pdoConnection {
public $isConnected;
protected $connection;
public function __construct($dsn, $username, $password, $options = array()) {
$this->isConnected = true;
try {
$this->connection = new PDO($dsn, $username, $password, $options);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); //sets the default to return 'named' properties in array.
} catch (PDOException $e) {
$this->isConnected = false;
throw new Exception($e->getMessage());
}
}
public function disconnect() {
$this->connection = null;
$this->isConnected = false;
}
public function query($SQL) {
try {
$result = $this->connection->query($SQL);
return $result;
} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}
public function prepare($SQL, $params = array()) {
try {
$result = $this->connection->prepare($SQL);
$result->execute($params);
return $result;
} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}
}
How to use:
$dsn = 'mysql:dbname=databasename;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$db = new pdoConnection($dsn, $user, $password);
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
$result = $db->prepare($SQL, array(":username" => 'someone'));
while($row = $result->fetch())
{
echo $row['ID'];
echo $row['EMAIL'];
}
I am used to mysql database access using the procedural mysql method. I am a beginner - intermediate programmer.
I am trying to learn the PDO api, however all resources which discuss using PDO show the connection string, username and password.
e.g.
<?php
try {
$db_conn = new PDO('mysql:host=localhost;dbname=databaseName','username', 'password');
}
catch (PDOException $e) {
echo 'Could not connect to database';
}
$sql = 'SELECT * FROM Products';
$stmt = $db_conn->prepare($sql);
...
...
...
?>
What I want, and think would be better programming is to put my PDO connection into a new file. then where I want to run an SQL query, I require_once('PDO.php') or similar.
The problem I have with this is as follows:
How do I close the connection? Simply $db_conn = null; ??
Should I close the connection after each query is run, then re-open the connection?
Should I close the connection or is it automatically destroyed when the user closes the browser?
I am working from a book called PHP Master: Writing Cutting Edge Code. http://www.sitepoint.com/books/phppro1/ and this has completely omitted any reference to closing the connection / destroying the object after it has been used.
Furthermore, I have looked at online tutorials, and they all connect to the database using PDO inline as opposed to having a separate database connector. This I am not happy with for many reasons:
I have to type username & password to connect every time.
If I get a developer to take a look at code / write some code, they will all have access to the database.
If I change the DB username & Password, then each file which connects to the database will need to be updated.
Could anybody recommend a better resource? Could anybody advise on what is the best practice way to do this?
Many thanks
Your question about how to store the database name, username and password have nothing to do with the capabilities of PDO. This is an implementation choice. The way you use to work with procedural functions can also be applied to PDO, the difference is that with PDO you work with objects instead.
So for simplicity, store the PDO creation of an object, either in a function or class, in which you can create the PDO instance anytime, e.g.
function createPDO($cfg) {
try {
return new PDO("mysql:host=".$cfg['host'].",port:".($cfg['port']).";dbname=".($cfg['name']).";",$cfg['username'], $cfg['password']);
} catch(PDOException $e) {
// handle exceptions accordingly
}
}
You can centralise these in whatever PHP file you like to include, just like you were used with the procedural functions.
You have two choices, either put all the relevant database information inside the createPDO, or use something like a config ($cfg) variable to store all this information.
$config = array();
$config['db'] = array(
'host' => 'localhost',
'name' => 'databse',
'username' => 'userx',
'password' => 'passy'
/* .. etc */
)
Using the createPDO function would be as followed
$db_conn = createPDO($config['db']);
For connections closing, each connection made to the database automatically disconnects after PHP exits its execution. You can however, close the connection if you wish, by setting the variable of the PDO object you assigned it to, in this example (and in yours) $db_conn to null
$db_conn = null; // connection closed.
The PDO has a manual http://php.net/manual/en/book.pdo.php here, which is a good start getting to know PDO a bit better.
You do not close the connection after a query, you simply leave it open for the next query. When PHP exists and your page is shown, the connection will be closed automatic.
It is a good idea to put the db stuff in a separate file and include that.
Even better, put all your db stuff in a class in use that.
Have a look at the pdo php page. Although not the best examples, they should get you started.
I have a script that connects to multiple databases (Oracle, MySQL and MSSQL), each database connection might not be used each time the script runs but all could be used in a single script execution. My question is, "Is it better to connect to all the databases once in the beginning of the script even though all the connections might not be used. Or is it better to connect to them as needed, the only catch is that I would need to have the connection call in a loop (so the database connection would be new for X amount of times in the loop).
Yeah Example Code #1:
// Connections at the beginning of the script
$dbh_oracle = connect2db();
$dbh_mysql = connect2db();
$dbh_mssql = connect2db();
for ($i=1; $i<=5; $i++) {
// NOTE: might not use all the connections
$rs = queryDb($query,$dbh_*); // $dbh can be any of the 3 connections
}
Yeah Example Code #2:
// Connections in the loop
for ($i=1; $i<=5; $i++) {
// NOTE: Would use all the connections but connecting multiple times
$dbh_oracle = connect2db();
$dbh_mysql = connect2db();
$dbh_mssql = connect2db();
$rs_oracle = queryDb($query,$dbh_oracle);
$rs_mysql = queryDb($query,$dbh_mysql);
$rs_mssql = queryDb($query,$dbh_mssql);
}
now I know you could use a persistent connection but would that be one connection open for each database in the loop as well? Like mysql_pconnect(), mssql_pconnect() and adodb for Oracle persistent connection method. I know that persistent connection can also be resource hogs and as I'm looking for best performance/practice.
Here is a good post on why persistent connections could cause problems
Use a lazy connection wrapper class:
class Connection
{
private $pdo;
private $dsn;
public __construct($dsn)
{
$this->dsn = $dsn;
}
public query($sql)
{
//the connection will get established here if it hasn't been already
if (is_null($this->pdo))
$this->pdo = new PDO($this->dsn);
//use pdo to do a query here
}
}
I hope you're already using PDO. If not, you should be. PDO is database independent. If you did this using procedural functions, you'd have to create a new class for each database type.
Anyways, this is just a skeleton (you'd want to add a $params option in query(), for example), but you should be able to get the idea. The connection is only attempted when you call query(). Constructing the object does not make a connection.
As an aside, consider using Doctrine. It has lazy connections and makes life easier in general.
The best performance/practice rule is simple: do connect to one database only.
As for the connects - try to implement some database access class. Which can connect automatically on demand.