Примечания к исследованию PHPPDO lib.culog.cn 13 ноября 2007 г. 09:36 Автор: Лю Шуй Мэн Чунь [Большой, Средний, Маленький]
■Что такое PDO?
Расширение POD (объект данных PHP) было добавлено в PHP5. В PHP6 PDO будет использоваться по умолчанию для подключения к базе данных. Все расширения, не относящиеся к PDO, будут удалены из расширения в PHP6. Это расширение предоставляет встроенный класс PDO PHP для доступа к базе данных. Различные базы данных используют одно и то же имя метода для решения проблемы несогласованных подключений к базе данных.
Я настроил его для разработки под windows.
■Цель PDO — предоставить легкий, понятный и удобный API, который объединяет общие функции различных библиотек РСУБД, но не исключает более продвинутые функции. Обеспечивает дополнительную степень абстракции/совместимости с помощью PHP-скриптов.
■Особенности PDO:
производительность. PDO с самого начала узнала об успехах и неудачах масштабирования существующих баз данных. Поскольку код PDO совершенно новый, у нас есть возможность перепроектировать производительность с нуля, чтобы воспользоваться преимуществами новейших функций PHP 5. способность. PDO предназначен для обеспечения общей функциональности базы данных в качестве основы, обеспечивая при этом легкий доступ к уникальным функциям СУБД. Простой. PDO создан для того, чтобы облегчить вам работу с базами данных. API не вторгается в ваш код и ясно дает понять, что делает каждый вызов функции. Расширяемый во время выполнения. Расширение PDO является модульным, что позволяет загружать драйверы для серверной части базы данных во время выполнения без необходимости перекомпиляции или переустановки всей программы PHP. Например, расширение PDO_OCI реализует API базы данных Oracle вместо расширения PDO. Существуют также драйверы для MySQL, PostgreSQL, ODBC и Firebird, и другие находятся в разработке.
■Установить PDO
У меня есть расширение PDO для разработки под WINDOWS. Если вы хотите установить и настроить его под Linux, поищите в другом месте.
Требования к версии:
Он уже включен в пакет программ php5.1 и более поздних версий;
Для php5.0.x вам необходимо загрузить его с pecl.php.net и поместить в свою библиотеку расширений, которая представляет собой папку ext папки, в которой находится PHP;
В руководстве говорится, что версии до 5.0 не могут запускать расширения PDO.
Конфигурация:
Измените файл конфигурации php.ini, чтобы он поддерживал pdo (если вы не понимаете php.ini, сначала выясните, что вам нужно изменить php.ini, отображаемый при вызове функции phpinfo()).
Пучок
Удалите точку с запятой перед расширением =php_pdo.dll. Точка с запятой является символом комментария файла конфигурации php. Это расширение необходимо.
Есть еще
;расширение=php_pdo.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_informix.dll
;расширение=php_pdo_mssql.dll
;расширение=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;расширение=php_pdo_oci8.dll
;расширение=php_pdo_odbc.dll
;расширение=php_pdo_pgsql.dll
;расширение=php_pdo_sqlite.dll
База данных, соответствующая каждому расширению:
Имя драйвераПоддерживаемые базы данныхPDO_DBLIBFreeTDS/Microsoft SQL Server/SybasePDO_FIREBIRDFirebird/Interbase 6PDO_INFORMIXIBM Informix Dynamic ServerPDO_MYSQLMySQL 3.x/4.xPDO_OCIOracle Call InterfacePDO_ODBCODBC v3 (IBM DB2, unixODBC и win32)PDO_PGSQLPostgreSQLPDO_SQLITESQLite 3 и SQLite 2
Какую базу данных вы хотите использовать, просто укажите соответствующую Просто удалите символ комментария «;» перед расширением.
■Использование PDO
Я предполагаю, что вы установили mysql. Если нет, сначала найдите способ его установки. У меня есть mysql5.0.22, и другие, кто использует MySQL 4.0.26, также могут его использовать.
★Подключение к базе данных:
Мы используем следующий пример для анализа базы данных соединений PDO:
<?php
$dbms='mysql'; //Тип базы данных Oracle использует ODI. Для разработчиков, если вы используете разные базы данных, вам нужно только изменить это, и вам не нужно запоминать так много функций.
$host='localhost';//Имя хоста базы данных
$dbName='test'; //Используемая база данных
$user='root'; //Имя пользователя подключения к базе данных
$pass='' //Соответствующий пароль
$dsn="$dbms:host=$host;dbname=$dbName";
//
пытаться{
$dbh=newPDO($dsn,$user,$pass);//Инициализация объекта PDO означает создание объекта подключения к базе данных $dbh
echo "Соединение успешно<br/>";
/*Вы также можете выполнить операцию поиска
foreach($dbh->query('SELECT * from FOO')as$row){
print_r($row);//Вы можете использовать echo($GLOBAL), чтобы увидеть эти значения;
}
*/
$дбх=ноль;
}catch(PDOException$e){
die("Ошибка!: ".$e->getMessage()."<br/>");
}
//По умолчанию это не длинное подключение. Если вам нужно длинное подключение к базе данных, нужно добавить в конце параметр: array(PDO::ATTR_PERSISTENT => true).
$db=newPDO($dsn,$user,$pass,array(PDO::ATTR_PERSISTENT=>true))
;
★Запрос к базе данных:
Мы уже выполнили запрос выше, и мы также можем использовать следующий запрос:
<?php
$db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER); //Установить атрибуты
$rs=$db->query("SELECT * FROM foo");
$rs->setFetchMode(PDO::FETCH_ASSOC);
$result_arr=$rs->fetchAll();
print_r ($result_arr);
?>
Поскольку выше используется метод setAttribute(), эти два параметра вводятся для принудительного перевода имени поля в верхний регистр. Ниже приведены параметры PDO::setAttribute():
PDO::ATTR_CASE: принудительно указать имя столбца в формате, как подробно описано ниже (второй параметр):
PDO::CASE_LOWER: принудительно указать имя столбца в нижнем регистре
PDO
.: :CASE_NATURAL: Имена столбцов следуют исходному способу.
PDO::CASE_UPPER: Принудительно переводить имена столбцов в верхний регистр.
PDO::ATTR_ERRMODE: сообщение об ошибке.
PDO::ERRMODE_SILENT: не отображает информацию об ошибке, только код ошибки.
PDO::ERRMODE_WARNING: отображает предупреждение об ошибке.
PDO::ERRMODE_EXCEPTION: выдает исключение.
PDO::ATTR_ORACLE_NULLS (действителен не только для ORACLE, но и для других баз данных): ) указывает соответствующее значение в php для значения NULL, возвращаемого базой данных.
PDO::NULL_NATURAL: без изменений.
PDO::NULL_EMPTY_STRING: пустая строка преобразуется в NULL.
PDO::NULL_TO_STRING: NULL преобразуется в пустую строку.
PDO::ATTR_STRINGIFY_FETCHES: преобразование числовых значений в строки при выборке. Требуется bool.
PDO::ATTR_STATEMENT_CLASS: установить предоставленный пользователем класс оператора, полученный из PDOStatement. Невозможно использовать с постоянными экземплярами PDO. Requiresarray(string classname, array(mixedstructor_args). )) .
PDO::ATTR_AUTOCOMMIT (доступно в OCI, Firebird и MySQL): следует ли автоматически фиксировать каждый отдельный оператор.
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (доступно в MySQL): использовать буферизованные запросы.
$rs->setFetchMode(PDO::FETCH_ASSOC); в примере это PDOStatement::setFetchMode(), объявление возвращаемого типа.
Есть следующие:
PDO::FETCH_ASSOC -- форма ассоциативного массива
PDO::FETCH_NUM -- Форма числового индексного массива
PDO::FETCH_BOTH -- Оба доступны в виде массива, который используется по умолчанию.
PDO::FETCH_OBJ — в форме объекта, аналогичного предыдущему mysql_fetch_object().
Дополнительные объявления типа возвращаемого значения (имя метода PDOStatement::) см. в руководстве.
★ Вставка, обновление, удаление данных,
$db->exec("УДАЛЕНИЕ ИЗ `xxxx_menu`, где middle=43");
Подведем краткий итог описанным выше операциям:
Операциями запроса в основном являются PDO::query(), PDO::exec(), PDO::prepare().
PDO::query() в основном используется для операций, возвращающих записанные результаты, особенно для операций SELECT.
PDO::exec() предназначен в основном для операций, которые не возвращают набор результатов, таких как INSERT, UPDATE, DELETE и других операций. Возвращаемый результат — это количество столбцов, на которые влияет текущая операция.
PDO::prepare() — это в основном операция предварительной обработки. Вам нужно использовать $rs->execute() для выполнения оператора SQL в предварительной обработке. Этот метод может связывать параметры, и его невозможно объяснить просто в этой статье. .Все Вы можете обратиться к руководствам и другой документации.
Основными операциями получения набора результатов являются: PDOStatement::fetchColumn(), PDOStatement::fetch(), PDOStatement::fetchALL().
PDOStatement::fetchColumn() — это поле первой записи, указанной в результате выборки. По умолчанию используется первое поле.
PDOStatement::fetch() используется для получения записи.
PDOStatement::fetchAll() предназначен для объединения всех наборов записей в один. Для получения результатов вы можете установить тип требуемого набора результатов через PDOStatement::setFetchMode.
Есть также две сопутствующие операции: PDO::lastInsertId() и PDOStatement::rowCount(). PDO::lastInsertId() возвращает последнюю операцию вставки, а типом столбца первичного ключа является последний идентификатор автоинкремента.
PDOStatement::rowCount() в основном используется для набора результатов, на который влияют операции DELETE, INSERT и UPDATE PDO::query() и PDO::prepare(), и недопустим для метода PDO::exec(). и операции SELECT.
★Транзакции и автоматическая отправка
На этом этапе вы подключились к MySQL через PDO. Прежде чем отправлять запросы, вы должны понять, как PDO управляет транзакциями. Если вы раньше не сталкивались с транзакциями, вы должны сначала знать четыре характеристики транзакций: атомарность, согласованность, изоляция и долговечность, то есть ACID. С точки зрения непрофессионала, для любой работы, выполняемой в рамках транзакции, даже если она выполняется поэтапно, существует гарантия, что работа будет безопасно применена к базе данных и на нее не повлияют запросы от других соединений во время отправки работы. . влияние. Транзакционная работа может быть автоматически отменена по запросу (при условии, что вы еще не зафиксировали ее), что значительно упрощает обработку ошибок в сценариях.
Транзакции обычно реализуются путем накопления пакета изменений и одновременного повышения их эффективности. Преимущество этого в том, что это может значительно повысить эффективность этих обновлений. Другими словами, транзакции могут сделать сценарии быстрее и потенциально более надежными (хотя для получения таких преимуществ транзакции необходимо использовать правильно).
К сожалению, не каждая база данных поддерживает транзакции (Mysql5 поддерживает транзакции, mysql4 — я не знаю), поэтому при первом открытии соединения PDO должен работать в так называемом режиме «автоматической фиксации». Режим автофиксации означает, что если база данных поддерживает транзакции, то каждый выполняемый вами запрос имеет свою собственную неявную транзакцию, а если база данных не поддерживает транзакции, каждый запрос не имеет такой транзакции. Если вам требуется транзакция, вы должны использовать метод PDO::beginTransaction() для запуска транзакции. Если базовый драйвер не поддерживает транзакции, будет выдано исключение PDOException (независимо от настроек обработки ошибок: это всегда фатальная ошибка). Внутри транзакции вы можете использовать PDO::commit() или PDO::rollBack() для завершения транзакции, в зависимости от того, был ли код, выполняющийся в транзакции, успешным.
Когда сценарий завершается или когда соединение вот-вот будет закрыто, если есть невыполненная транзакция, PDO автоматически откатит транзакцию. Это мера безопасности, помогающая избежать несоответствий в случае аварийного завершения сценария — если транзакция не зафиксирована явно, то предполагается, что где-то будет несогласованность, поэтому для сохранения безопасности данных будет выполнен откат.
//Пример из http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505furlong/index.html.
пытаться{
$dbh=new PDO('odbc:SAMPLE','db2inst1','ibmdb2',
массив (PDO_ATTR_PERSISTENT => true));
echo "Подключеноn";
$dbh->setAttribute(PDO_ATTR_ERRMODE,PDO_ERRMODE_EXCEPTION);
$dbh->beginTransaction();
$dbh->exec("вставить в штатные (id, first, Last) значения (23, 'Joe', 'Bloggs')");
$dbh->exec("вставить в paychange (id, sum,changedate)
значения (23, 50000, СЕЙЧАС())");
$dbh->коммит();
}catch(Исключение $e){
$dbh->rollBack();
echo "Ошибка: ".$e->getMessage();
}
Предположим, в приведенном выше примере мы создаем набор записей для нового сотрудника с идентификационным номером 23. Помимо ввода основных данных о человеке, нам также необходимо записать зарплату сотрудника. Оба обновления легко выполнить по отдельности, но, включив оба обновления в вызовы BeginTransaction() и commit(), вы гарантируете, что никто другой не сможет увидеть изменения, пока они не будут завершены. В случае возникновения ошибки блок catch может откатить все изменения, произошедшие с момента начала транзакции, и распечатать сообщение об ошибке.
Обновления не обязательно должны производиться внутри транзакции. Вы также можете выполнять сложные запросы для извлечения данных и создания дальнейших обновлений и запросов, используя эту информацию. Когда транзакция активна, гарантируется, что другие не смогут вносить изменения во время работы. На самом деле, это не на 100% верно, но это хорошее введение, если вы раньше не слышали о транзакциях.
★Подготовленные операторы и хранимые процедуры. Многие более зрелые базы данных поддерживают концепцию подготовленных операторов. Что такое подготовленные заявления? Вы можете думать о подготовленных операторах как о скомпилированном шаблоне SQL, который вы хотите запустить, который можно настроить с помощью переменных параметров. Подготовленные операторы предоставляют два основных преимущества:
запрос необходимо проанализировать (или подготовить) только один раз, но он может выполняться несколько раз с одинаковыми или разными параметрами. Когда запрос готов, база данных анализирует, компилирует и оптимизирует план выполнения запроса. Этот процесс занимает больше времени для сложных запросов и может значительно замедлить работу вашего приложения, если вам нужно повторить один и тот же запрос несколько раз с разными параметрами. Используя подготовленные операторы, вы можете избежать повторных циклов анализа/компиляции/оптимизации. Проще говоря, подготовленные операторы используют меньше ресурсов и, следовательно, выполняются быстрее.
Параметры, передаваемые в подготовленные операторы, не обязательно заключать в кавычки; их обрабатывает драйвер; Если ваше приложение использует исключительно подготовленные операторы, вы можете быть уверены, что никаких вторжений SQL не произойдет. (Однако риск по-прежнему существует, если вы по-прежнему основываете другие части запроса на ненадежных входных данных).
Подготовленные операторы настолько полезны, что PDO фактически нарушает правило, установленное в цели 4: если драйвер не поддерживает подготовленные операторы, PDO будет эмулировать подготовленные операторы.
Пример: пример приложения PDO:
<?php
$dbms='mysql';//Тип базы данных Oracle использует ODI. Для разработчиков, использующих разные базы данных, если вы измените это, вам не придется запоминать так много функций.
//Database. имя хоста
$dbName='test';//Используемая база данных
$user='root';//Имя пользователя подключения к базе данных
$pass='';//Соответствующий пароль
$dsn="$dbms:host=$host;dbname= $имя_базы_данных";
classdbextendsPDO{
общественная функция__construct(){
пытаться{
родитель::__construct("$GLOBALS[dsn]",$GLOBALS['user'],$GLOBALS['pass']);
}catch(PDOException$e){
die("Ошибка: ".$e->__toString()."<br/>");
}
}
publicfinalfunctionquery($sql){
пытаться{
returnparent::query($this->setString($sql));
}catch(PDOException$e){
die("Ошибка: ".$e->__toString()."<br/>");
}
}
PrivatefinalfunctionsetString($sql){
echo "Я хочу обработать $sql";
вернуть $SQL;
}
}
$db=newdb();
$db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER);
foreach($db->query('SELECT * from xxxx_menu')as$row){
print_r ($ строка);
}
$db->exec('УДАЛЕНИЕ ИЗ `xxxx_menu`, где Mid=43');
?>