To avoid exposing your connection details should you fail to remember to catch any exception thrown by the PDO constructor you can use the following class to implicitly change the exception handler temporarily.
<?php
Class SafePDO extends PDO {
public static function exception_handler($exception) {
// Output the exception details
die('Uncaught exception: ', $exception->getMessage());
}
public function __construct($dsn, $username='', $password='', $driver_options=array()) {
// Temporarily change the PHP exception handler while we . . .
set_exception_handler(array(__CLASS__, 'exception_handler'));
// . . . create a PDO object
parent::__construct($dsn, $username, $password, $driver_options);
// Change the exception handler back to whatever it was before
restore_exception_handler();
}
}
// Connect to the database with defined constants
$dbh = new SafePDO(PDO_DSN, PDO_USER, PDO_PASSWORD);
?>
Подключения и Управление подключениями
Соединения устанавливаются автоматически при создании объекта PDO от его базового класса. Не имеет значения, какой драйвер вы хотите использовать; все что требуется, это имя базового класса. Конструктор класса принимает аргументы для задания источника данных (DSN), а также необязательные имя пользователя и пароль (если есть).
Пример #1 Подключение к MySQL
<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
?>
В случае ошибки при подключении будет выброшено исключение PDOException. Его можно перехватить и обработать, либо оставить на откуп глобальному обработчику ошибок, который вы задали функцией set_exception_handler().
Пример #2 Обработка ошибок подключения
<?php
try {
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
foreach($dbh->query('SELECT * from FOO') as $row) {
print_r($row);
}
$dbh = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>
Если ваше приложение не перехватывает исключение PDO конструктора, движок zend выполнит стандартные операции для завершения работы скрипта и вывода обратной трассировки. В этой трассировке будет содержаться детальная информация о соединении с базой данных, включая имя пользователя и пароль. Ответственность за перхват исключений лежит на вас. Перехватить исключение можно явно (с помощью выражения catch), либо неявно, задав глобальный обработчик ошибок функцией set_exception_handler().
При успешном подключении к базе данных в скрипт будет возвращен созданный
PDO объект. Соединение остается активным на протяжении всего времени жизни
объекта. Чтобы закрыть соединение, необходимо уничтожить объект путем удаления
всех ссылок на него (этого можно добиться, присваивая NULL всем переменным,
указывающим на объект). Если не сделать этого явно, PHP автоматически
закроет соединение по окончании работы скрипта.
Пример #3 Закрытие соединения
<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
// здесь мы каким-то образом используем соединение
// соединение больше не нужно, закрываем
$dbh = null;
?>
Во многих приложениях может оказаться полезным использование постоянных соединений к базам данных. Постоянные соединения не закрываются при завершении работы скрипта, они кэшируются и используются повторно, когда другой скрипт запрашивает соединение с теми же учетными данными. Постоянные соединения позволяют избежать создания новых подключений каждый раз, когда требуется обмен данными с базой, что в результате дает прирост скорости работы таких приложений.
Пример #4 Постоянные соединения
<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
PDO::ATTR_PERSISTENT => true
));
?>
Замечание:
Чтобы использовать постоянные соединения, необходимо добавить константу
PDO::ATTR_PERSISTENTв массив параметров драйвера, который передается конструктору PDO. Если просто задать этот атрибут функцией PDO::setAttribute() уже после создания объекта, драйвер не будет использовать постоянные соединения.
Замечание:
Если вы используете PDO ODBC драйвер и ваши ODBC библиотеки поддерживают объединение подключений в пул (ODBC Connection Pooling) (unixODBC и Windows точно поддерживают, но могут быть и другие), то рекомендуется вместо постоянных соединений пользоваться этим пулом. Пул подключений ODBC доступен всем модулям текущего процесса; если PDO сам кэширует соединение, то это соединение будет недоступно другим модулям и не попадет в пул. В результате каждый модуль будет создавать дополнительные подключения для своих нужд.
In order to set the encoding of the database connection, use the exec function:
<?php
try {
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$dbh->exec("SET CHARACTER SET utf8");
$dbh = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>
Just thought I'd add in and give an explanation as to why you need to use 127.0.0.1 if you have a different port number.
The mysql libraries will automatically use Unix sockets if the host of "localhost" is used. To force TCP/IP you need to set an IP address.
I spent hours today trying to get my portable wamp to update a database, using localhost:800 and port 3307 for mysql. For it to work I needed to adjust the connect() instruction as described:
$dsn = "mysql:host=127.0.0.1;port=3307;dbname=mydatabase";
Note that you can specify a port number with "port=####", but this port number will be ignored if the host is localhost. If you want to connect to a local port other than the default, use host=127.0.0.1 instead of localhost.
On connection errors, the PDO constructor seems to do two things no matter your PDO::ATTR_ERRMODE setting:
1. Trigger a warning
2. Throw a PDOException
If you set the PDO::ATTR_ERRMODE parameter, it will only take effect on further operations.
