PDO offers you a choice of 3 different error handling strategies, to fit
your style of application development.
-
PDO::ERRMODE_SILENT
Prior to PHP 8.0.0, this was the default mode. PDO will simply set the error code for you
to inspect using the PDO::errorCode() and
PDO::errorInfo() methods on both the
statement and database objects; if the error resulted from a call on a
statement object, you would invoke the
PDOStatement::errorCode() or
PDOStatement::errorInfo()
method on that object. If the error resulted from a call on the
database object, you would invoke those methods on the database object
instead. -
PDO::ERRMODE_WARNING
In addition to setting the error code, PDO will emit a traditional
E_WARNING message. This setting is useful during debugging/testing, if
you just want to see what problems occurred without interrupting the
flow of the application. -
PDO::ERRMODE_EXCEPTION
As of PHP 8.0.0, this is the default mode.
In addition to setting the error code, PDO will throw a
PDOException
and set its properties to reflect the error code and error
information. This setting is also useful during debugging, as it will
effectively «blow up» the script at the point of the error, very
quickly pointing a finger at potential problem areas in your code
(remember: transactions are automatically rolled back if the exception
causes the script to terminate).Exception mode is also useful because you can structure your error
handling more clearly than with traditional PHP-style warnings, and
with less code/nesting than by running in silent mode and explicitly
checking the return value of each database call.See Exceptions for more
information about Exceptions in PHP.
PDO standardizes on using SQL-92 SQLSTATE error code strings; individual
PDO drivers are responsible for mapping their native codes to the
appropriate SQLSTATE codes. The PDO::errorCode()
method returns a single SQLSTATE code. If you need more specific
information about an error, PDO also offers an
PDO::errorInfo() method which returns an array
containing the SQLSTATE code, the driver specific error code and driver
specific error string.
Example #1 Create a PDO instance and set the error mode
<?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);// This will cause PDO to throw a PDOException (when the table doesn't exist)
$dbh->query("SELECT wrongcolumn FROM wrongtable");
The above example will output:
Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testdb.wrongtable' doesn't exist in /tmp/pdo_test.php:10 Stack trace: #0 /tmp/pdo_test.php(10): PDO->query('SELECT wrongcol...') #1 {main} thrown in /tmp/pdo_test.php on line 10
Note:
PDO::__construct() will always throw a PDOException if the connection fails
regardless of whichPDO::ATTR_ERRMODE
is currently set.
Example #2 Create a PDO instance and set the error mode from the constructor
<?php
$dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = 'googleguy';
$password = 'googleguy';$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));// This will cause PDO to throw an error of level E_WARNING instead of an exception (when the table doesn't exist)
$dbh->query("SELECT wrongcolumn FROM wrongtable");
The above example will output:
Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.wrongtable' doesn't exist in /tmp/pdo_test.php on line 9
There are no user contributed notes for this page.
Here is a snippet of my code:
$qry = '
INSERT INTO non-existant-table (id, score)
SELECT id, 40
FROM another-non-existant-table
WHERE description LIKE "%:search_string%"
AND available = "yes"
ON DUPLICATE KEY UPDATE score = score + 40
';
$sth = $this->pdo->prepare($qry);
$sth->execute($data);
print_r($this->pdo->errorInfo());
This should give me an error because the tables don’t even exist. All I get however is this:
Array ( [0] => 00000 )
How can I get a better description of the error so I can debug the issue?
asked Oct 22, 2010 at 18:34
JD IsaacksJD Isaacks
55k93 gold badges273 silver badges421 bronze badges
3
Try this instead:
print_r($sth->errorInfo());
Add this before your prepare:
$this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
This will change the PDO error reporting type and cause it to emit a warning whenever there is a PDO error. It should help you track it down, although your errorInfo should have bet set.
Neuron
4,8435 gold badges36 silver badges54 bronze badges
answered Oct 22, 2010 at 18:36
Alan GeleynseAlan Geleynse
24.5k5 gold badges46 silver badges55 bronze badges
6
Old thread, but maybe my answer will help someone. I resolved by executing the query first, then setting an errors variable, then checking if that errors variable array is empty. see simplified example:
$field1 = 'foo';
$field2 = 'bar';
$insert_QUERY = $db->prepare("INSERT INTO table bogus(field1, field2) VALUES (:field1, :field2)");
$insert_QUERY->bindParam(':field1', $field1);
$insert_QUERY->bindParam(':field2', $field2);
$insert_QUERY->execute();
$databaseErrors = $insert_QUERY->errorInfo();
if( !empty($databaseErrors) ){
$errorInfo = print_r($databaseErrors, true); # true flag returns val rather than print
$errorLogMsg = "error info: $errorInfo"; # do what you wish with this var, write to log file etc...
/*
$errorLogMsg will return something like:
error info:
Array(
[0] => 42000
[1] => 1064
[2] => You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'table bogus(field1, field2) VALUES ('bar', NULL)' at line 1
)
*/
} else {
# no SQL errors.
}
answered Nov 20, 2015 at 10:54
1
Maybe this post is too old but it may help as a suggestion for someone looking around on this :
Instead of using:
print_r($this->pdo->errorInfo());
Use PHP implode() function:
echo 'Error occurred:'.implode(":",$this->pdo->errorInfo());
This should print the error code, detailed error information etc. that you would usually get if you were using some SQL User interface.
Hope it helps
uınbɐɥs
7,1265 gold badges25 silver badges42 bronze badges
answered Mar 26, 2012 at 21:37
VikramVikram
4,1428 gold badges42 silver badges65 bronze badges
4
From the manual:
If the database server successfully
prepares the statement, PDO::prepare()
returns a PDOStatement object. If the
database server cannot successfully
prepare the statement, PDO::prepare()
returns FALSE or emits PDOException
(depending on error handling).
The prepare statement likely caused an error because the db would be unable to prepare the statement. Try testing for an error immediately after you prepare your query and before you execute it.
$qry = '
INSERT INTO non-existant-table (id, score)
SELECT id, 40
FROM another-non-existant-table
WHERE description LIKE "%:search_string%"
AND available = "yes"
ON DUPLICATE KEY UPDATE score = score + 40
';
$sth = $this->pdo->prepare($qry);
print_r($this->pdo->errorInfo());
answered Oct 22, 2010 at 18:50
thetaikothetaiko
7,7882 gold badges33 silver badges49 bronze badges
0
Вернуться к: PDO
PDO предлагает на выбор 3 стратегии обработки ошибок в зависимости от вашего
стиля разработки приложений.
-
PDO::ERRMODE_SILENT
Это режим по умолчанию. PDO просто предоставит вам код ошибки, который
можно получить методами PDO::errorCode() и
PDO::errorInfo(). Эти методы реализованы как в объектах
запросов так и в объектах баз данных. Если ошибка вызвана во время выполнения
кода объекта запроса, нужно вызвать метод
PDOStatement::errorCode() или
PDOStatement::errorInfo() этого объекта. Если ошибка
вызова объекта базы данных, нужно вызвать аналогичные методы у этого объекта. -
PDO::ERRMODE_WARNING
Помимо задания кода ошибки PDO выдаст обычное E_WARNING сообщение. Это может
быть полезно при отладке или тестировании, когда нужно видеть, что произошло,
но не нужно прерывать работу приложения. -
PDO::ERRMODE_EXCEPTION
Помимо задания кода ошибки PDO будет выбрасывать исключение
PDOException, свойства которого будут отражать
код ошибки и ее описание. Этот режим также полезен при отладке, так как
сразу известно, где в программе произошла ошибка. Это позволяет быстро
локализовать и решить проблему. (Не забывайте, что если исключение
является причиной завершения работы скрипта, все активные транзакции
будут откачены.)Режим исключений также полезен, так как дает возможность структурировать
обработку ошибок более тщательно, нежели с обычными PHP предупреждениями, а
также с меньшей вложенностью кода, чем в случае работы в тихом режиме с
явной проверкой возвращаемых значений при каждом обращении к базе данных.Подробнее об исключениях в PHP см. в разделе Исключения.
PDO стандартизирован для работы со строковыми кодами ошибок SQL-92 SQLSTATE.
Отдельные PDO драйверы могут задавать соответствия своих собственных кодов
кодам SQLSTATE. Метод PDO::errorCode() возвращает одиночный
SQLSTATE код. Если необходима специфичная информация об ошибке, PDO предлагает
метод PDO::errorInfo(), который возвращает массив, содержащий
SQLSTATE код, код ошибки драйвера, а также строку ошибки драйвера.
Пример #1 Создание PDO объекта и задание режима обработки ошибок
<?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Подключение не удалось: ' . $e->getMessage();
}?>
Замечание:
Метод PDO::__construct() будет всегда бросать исключение PDOException,
если соединение оборвалось, независимо от установленного значенияPDO::ATTR_ERRMODE
.
Непойманные исключения фатальны.
Пример #2 Создание экземпляра класса PDO и задание режима обработки ошибок в конструкторе
<?php
$dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = 'googleguy';
$password = 'googleguy';/*
По прежнему оберните конструктор в блок try/catch, так как, даже при установке ERRMODE в WARNING,
PDO::__construct всегда будет бросать исключение PDOException, если соединение оборвалось.
*/
try {
$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
} catch (PDOException $e) {
echo 'Соединение оборвалось: ' . $e->getMessage();
exit;
}// Следующий запрос приводит к ошибке уровня E_WARNING вместо исключения (когда таблица не существует)
$dbh->query("SELECT wrongcolumn FROM wrongtable");
?>
Результат выполнения данного примера:
Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.wrongtable' doesn't exist in /tmp/pdo_test.php on line 18
Вернуться к: PDO
Содержание
- Ошибки и их обработка
- PDOStatement::errorInfo
- Описание
- Список параметров
- Возвращаемые значения
- Примеры
- Смотрите также
- User Contributed Notes 4 notes
- PDO::query
- Описание
- Список параметров
- Возвращаемые значения
- Примеры
- Смотрите также
- SELECT query with PDO
- SELECT query without parameters
- Getting a single row
- Selecting multiple rows
- SELECT query with parameters
- SELECT query with positional placeholders
- SELECT query with named placeholders
- Selecting multiple rows
- Related articles:
- Got a question?
- SEE ALSO:
- Latest comments:
- Add a comment
- Comments:
- Reply:
- Reply:
- Reply:
- Reply:
- Reply:
- Reply:
- Reply:
- Reply:
- Reply:
- Reply:
- Reply:
- Reply:
Ошибки и их обработка
PDO предлагает на выбор 3 стратегии обработки ошибок в зависимости от вашего стиля разработки приложений.
PDO::ERRMODE_SILENT
До PHP 8.0.0, это был режим по умолчанию. PDO просто предоставит вам код ошибки, который можно получить методами PDO::errorCode() и PDO::errorInfo() . Эти методы реализованы как в объектах запросов, так и в объектах баз данных. Если ошибка вызвана во время выполнения кода объекта запроса, нужно вызвать метод PDOStatement::errorCode() или PDOStatement::errorInfo() этого объекта. Если ошибка вызова объекта базы данных, нужно вызвать аналогичные методы у этого объекта.
PDO::ERRMODE_WARNING
Помимо установки кода ошибки PDO выдаст обычное E_WARNING сообщение. Это может быть полезно при отладке или тестировании, когда нужно видеть, что произошло, но не нужно прерывать работу приложения.
PDO::ERRMODE_EXCEPTION
Начиная с PHP 8.0.0 является режимом по умолчанию. Помимо задания кода ошибки PDO будет выбрасывать исключение PDOException , свойства которого будут отражать код ошибки и её описание. Этот режим также полезен при отладке, так как сразу известно, где в программе произошла ошибка. Это позволяет быстро локализовать и решить проблему. (Не забывайте, что если исключение является причиной завершения работы скрипта, все активные транзакции будут откачены.)
Режим исключений также полезен, так как даёт возможность структурировать обработку ошибок более тщательно, нежели с обычными предупреждениями PHP, а также с меньшей вложенностью кода, чем в случае работы в тихом режиме с явной проверкой возвращаемых значений при каждом обращении к базе данных.
Подробнее об исключениях в PHP смотрите в разделе Исключения.
PDO стандартизирован для работы со строковыми кодами ошибок SQL-92 SQLSTATE. Отдельные драйверы PDO могут задавать соответствия своих собственных кодов кодам SQLSTATE. Метод PDO::errorCode() возвращает одиночный код SQLSTATE. Если необходима специфичная информация об ошибке, PDO предлагает метод PDO::errorInfo() , который возвращает массив, содержащий код SQLSTATE, код ошибки драйвера, а также строку ошибки драйвера.
Пример #1 Создание PDO объекта и установка режима обработки ошибок
= ‘mysql:dbname=testdb;host=127.0.0.1’ ;
$user = ‘dbuser’ ;
$password = ‘dbpass’ ;
$dbh = new PDO ( $dsn , $user , $password );
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
// PDO выбросит исключение PDOException (если таблица не существует)
$dbh -> query ( «SELECT wrongcolumn FROM wrongtable» );
?>
Результат выполнения данного примера:
Метод PDO::__construct() будет всегда бросать исключение PDOException , если соединение оборвалось, независимо от установленного значения PDO::ATTR_ERRMODE .
Пример #2 Создание экземпляра класса PDO и установка режима обработки ошибок в конструкторе
= ‘mysql:dbname=test;host=127.0.0.1’ ;
$user = ‘googleguy’ ;
$password = ‘googleguy’ ;
$dbh = new PDO ( $dsn , $user , $password , array( PDO :: ATTR_ERRMODE => PDO :: ERRMODE_WARNING ));
// Следующий запрос приводит к ошибке уровня E_WARNING вместо исключения (когда таблица не существует)
$dbh -> query ( «SELECT wrongcolumn FROM wrongtable» );
?>
Источник
PDOStatement::errorInfo
(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.1.0)
PDOStatement::errorInfo — Получение расширенной информации об ошибке, произошедшей в результате работы объекта PDOStatement
Описание
Список параметров
У этой функции нет параметров.
Возвращаемые значения
PDOStatement::errorInfo() возвращает массив с информацией об ошибке, соответствующей последней операции объекта PDOStatement. Массив состоит как минимум из следующих полей:
Элемент | Информация |
---|---|
Код ошибки SQLSTATE (пятисимвольный код состоящий из букв и цифр, определённый в стандарте ANSI SQL). | |
1 | Код ошибки, возвращаемый драйвером. |
2 | Сообщение об ошибке, возвращаемое драйвером. |
Примеры
Пример #1 Вывод полей errorInfo() при PDO_ODBC подключении к DB2
/* Спровоцируем ошибку — таблицы BONES не существует */
$sth = $dbh -> prepare ( ‘SELECT skull FROM bones’ );
$sth -> execute ();
echo «nPDOStatement::errorInfo():n» ;
$arr = $sth -> errorInfo ();
print_r ( $arr );
?>
Результат выполнения данного примера:
Смотрите также
- PDO::errorCode() — Возвращает код SQLSTATE результата последней операции с базой данных
- PDO::errorInfo() — Получает расширенную информацию об ошибке, произошедшей в ходе последнего обращения к базе данных
- PDOStatement::errorCode() — Получает код SQLSTATE, связанный с последней операцией в объекте PDOStatement
User Contributed Notes 4 notes
Seriously errorInfo is your friend. Use it.
If these look like your google searches then you need errorInfo
«no database error showing in php»
«pdo selects from database but wont insert»
«pdo insert not working»
«isnt pdo just a big hype, should I go back to mysql?»
«how much do surgeons make?»
Trust me it will definitely save you hours of insanity if you make it a habit to use it in development. Forget E-ALL, it failed me since well, E-ALL apparently doesn’t know that I didn’t set a default value in my MySQL table and my query wasnt adding anything to it. So always do this
= ‘do something on a mysql table where foo = :bar’ ;
$stmt = prepare ( $sql );
$stmt -> bindValue ( ‘:bar’ , $foo , PDO :: PARAM_ [ DATA TYPE ]);
$stmt -> execute ();
// very important during development. But take it off in production
$foo_arr = $stmt -> errorInfo ();
print_r ( $foo_arr );
//Sample print_r return
/*
Array(
[0] => HY000
[1] => 1364
[2] => Field ‘phone’ doesn’t have a default value
)
Never have I been so happy to see an error
*/
?>
While its common practice for any decent developer to always watch out and try to catch for errors, even the best of us make mistakes. This is not a replacement for exceptions, but the simplicity is priceless.
Источник
PDO::query
(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.2.0)
PDO::query — Подготавливает и выполняет выражение SQL без заполнителей
Описание
PDO::query() подготавливает и выполняет выражение SQL за один вызов функции, возвращая выражение как объект PDOStatement .
Если запрос будет запускаться многократно, для улучшения производительности приложения имеет смысл этот запрос один раз подготовить PDOStatement методом PDO::prepare() , а затем запускать на выполнение методом PDOStatement::execute() столько раз, сколько потребуется.
Если после выполнения предыдущего запроса вы не выбрали все данные из результирующего набора, следующий вызов PDO::query() может потерпеть неудачу. В таких случаях следует вызывать метод PDOStatement::closeCursor() , который освободит ресурсы базы данных, занятые предыдущим объектом PDOStatement . После этого можно безопасно вызывать PDO::query() .
Если query содержит заполнители, выражение должно быть подготовлено и выполнено отдельно с использованием методов PDO::prepare() и PDOStatement::execute() .
Список параметров
SQL-запрос для подготовки и выполнения.
Если SQL содержит заполнители, вместо этого метода следует использовать PDO::prepare() и PDOStatement::execute() . В качестве альтернативы, SQL можно подготовить вручную перед вызовом PDO::query() , при этом данные должны быть правильно отформатированы с использованием PDO::quote() , если драйвер поддерживает это.
Режим выборки по умолчанию для возвращённого PDOStatement . Должен быть одной из констант PDO::FETCH_* .
Если этот аргумент передаётся функции, остальные аргументы будут обрабатываться так, как если бы PDOStatement::setFetchMode() был вызван для полученного объекта выражения. Последующие аргументы зависят от выбранного режима выборки.
Возвращаемые значения
Возвращает объект PDOStatement или false в случае возникновения ошибки.
Примеры
Пример #1 SQL без заполнителей может быть выполнен с использованием PDO::query()
Результат выполнения данного примера:
Смотрите также
- PDO::exec() — Выполняет SQL-запрос и возвращает количество затронутых строк
- PDO::prepare() — Подготавливает запрос к выполнению и возвращает связанный с этим запросом объект
- PDOStatement::execute() — Запускает подготовленный запрос на выполнение
Источник
SELECT query with PDO
There are several ways to run a SELECT query using PDO, that differ mainly by the presence of parameters, type of parameters, and the result type. I will show examples for the every case so you can choose one that suits you best.
Just make sure you’ve got a properly configured PDO connection variable that needs in order to run SQL queries with PDO and to inform you of the possible errors.
SELECT query without parameters
If there are no variables going to be used in the query, we can use a conventional query() method instead of prepare and execute.
This will give us an $stmt object that can be used to fetch the actual rows.
Getting a single row
If a query is supposed to return just a single row, then you can just call fetch() method of the $stmt variable:
Note that in PHP you can «chain» method calls, calling a method of the returned object already, like:
Selecting multiple rows
There are two ways to fetch multiple rows returned by a query. The most traditional way is to use the fetch() method within a while loop:
This method could be recommended if rows have to be processed one by one. For example, if such processing is the only action that needs to be taken, or if the data needs to be pre-processed somehow before use.
But the most preferred way to fetch multiple rows which would to be shown on a web-page is calling the great helper method called fetchAll() . It will put all the rows returned by a query into a PHP array, that later can be used to output the data using a template (which is considered much better than echoing the data right during the fetch process). So the code would be
SELECT query with parameters
But most of time we have to use a variable or two in the query, and in such a case we should use a prepared statement (also called a parameterized query), first preparing a query with parameters (or placeholder marks) and then executing it, sending variables separately.
In PDO we can use both positional and named placeholders. For simple queries, personally I prefer positional placeholders, I find them less verbose, but it’s entirely a matter of taste.
SELECT query with positional placeholders
SELECT query with named placeholders
Selecting multiple rows
Fetching multiple rows from a prepared query would be identical to that from a query without parameters already shown:
Related articles:
Got a question?
I am the only person to hold a gold badge in , and on Stack Overflow and I am eager to show the right way for PHP developers.
Besides, your questions let me make my articles even better, so you are more than welcome to ask any question you have.
SEE ALSO:
- 05.01.23 10:15
Ayuba for Mysqli prepared statement with multiple values for IN clause:
I have bn learning php but still finding it difficult to handle a project can u put me throughplease
read more - 04.01.23 19:55
Anjana for (The only proper) PDO tutorial:
Hello, I have a query regarding PDO and MySQLi. I am creating a project in PHP and I have used.
read more - 03.01.23 15:21
Mange for Do generators really reduce the memory usage? :
In your `while`-example, shouldn’t `if ($item % 2 === 0 )` be `if ($num % 2 === 0 )`?
read more - 02.01.23 07:23
Vern for How to execute 1000s INSERT/UPDATE queries with PDO?:
Is the 9th line correct? An INSERT with a SET in the same statement?
read more - 30.12.22 07:30
Seraphina for Mysqli prepared statement with multiple values for IN clause:
This article accurately and concisely solved the problem that was bugging me for ages. Thank you.
read more
Please refrain from sending spam or advertising of any sort.
Messages with hyperlinks will be pending for moderator’s review.
Markdown is now supported:
- > before and an empty line after for a quote
- four spaces to mark a block of code
How do I add results from a query? array_sum won’t work?
Reply:
You need to use prepared statements and ask your database to to the summing
I have 2 questions for you: (1) How can I find the autoincrement value of a primary key after the last INSERT (i.e. the value of the primary key index after an INSERT), and (2) How can I use a variable tablename in an INSERT. I’ve tried $tablename but it doesn’t work
Reply:
To get the inserted Id you need PDO::lastInsertId(). See https://phpdelusions.net/pdo#affected
You cannot prepare a table name. So you have to put it directly in the query. You have to validate it first: https://phpdelusions.net/pdo_examples/order_by
This not working, no replacing vars limit and offset in query when execute:
Reply:
In order to make it work, you need to turn the emulation off, as explained here https://phpdelusions.net/pdo#limit
Your tutorial on SELECT query with multiple parameters was very useful to me.
Would you please share a tutorial on Pdo multiple parameters pagination?
Many thanks in advance
Can you please do a write up on how to generate PHP code for a *.wsdl file that uses the WS-Security for authentication? There are many simple examples on consuming a web service in php usng a wsdl file but none of them involves security. Thank you.
Dear Sir, Thank you very much for the great help and your precious time. Indeed, I implemented the recommendation fully, as below:
The result?: You searched for: PHP Delusions Q1rows: [PHP Delusions] 0 row(s) found. Actually, the reason I used so many conditions in my prior code was to help me trap the source of the problem. Above code works perfectly in PHPMyAdmin. Please, give it another thought, maybe PHP, PDO settings, etc. relative to the Match()Against() construct.
Dear Sir, Please help me with this code! It is killing me! In my PHP, the $keywords variable comes in via my search field. It is wrapped in single ‘ ‘. I get 1 row. No wrapping, I get 1 row! I ran the code in MySql console successfully & got the 56 rows I expected from my db. Tried ? and :keywords Placeholders, I get 1 row! Did direct binding with both bindParam() and bindValue(), as PARAM_ STR & PARAM_INT respectively, same result, 1 row! Passed $keywords variable as array to execute() method, the same result! What now should I do to survive this, please, help. Also, the pg_desc field is indexed for fulltext search.
Reply:
Hello Ezeribe Adolf!
This issue is very simple. And it is actually a very common mistake. when you run a count(*) query, a database already counts the rectods for you, and therefore you shouldn’t call the rowCount() method. Instead, you need to fetch the result.
And speaking of quotes, there should be NONE of them. I removed all the quotes from your code, as well as all the useless conditions:
Thanks for the excellent site and tutorials, hugely useful resource. I think there maybe a typo on the 2nd to last code snippet above, shouldn’t it be $pdo->prepare in both cases rather than $pdo->query given you are passing parameters?
Reply:
You are absolutely correct, it must be prepare indeed! Fixed.
Thanks for the amazing tutorial. So, I’m having an issue. I trying to fetch posts from a WordPress database table «wp_posts», output the rows as json to be printed through Javascript (I’m using ajax to connect to the api). My code:
Even when I use «while» with the same «array_push($data, $posts)». I get nothing when I check for the response from the api request but if I «$out[‘data’] = var_dump($data) or var_export($data)», I get everything in the response. I don’t know what I’m doing wrong.
Reply:
I am not sure but this is what you probably need
in case it’s still nothing check the connection encoding ash shown in the connection example.
I am trying to select files with owner=’xHswu’ and format=’mkv’. Here’s my $sql:
I don’t see in any of your examples in which the WHERE clause contains more than one field to check against. Or maybe I am doing something wrong there’s is better way to achieve what I am trying to do. -Newbie
Reply:
this is more an SQL related question because PDO only handles placeholders while the rest is just regular SQL. And yes, in SQL you need to use the AND keyword to make your query meed both criteria.
So just remove the second query and everything should work.
I Staff, it is possible something like :
as filter the TABLE_NAME ? always thanks
Reply:
Nope it is not possible.
You must filter the table name manually.
I describe this approach here and here.
I’m trying to display a message when the query get no result from database. But it displaying error. This is my code:
I want to break a text into individual words and search every word that matches in the table. They do not need to be in order.
The execute array doesn’t seem to work. Kindly help or any solution is much appreciated.
If we do this query, will it work slowly?
// $sql = (‘SELECT FROM mother WHERE = $this->connect()->prepare(‘SELECT FROM mother WHERE >execute([‘id’ => $id]); while ($result = $stmt->fetch()) < $show[] = $result; return $show; >return $stmt; >
Please!! answer me!
Reply:
Nope, it will run fast.
The code is not optimal though. It should be just
Thanks for this fantastic tutorial. It is highly appreciated. While working with it, I ran into this challenge: PDOException: SQLSTATE[HY093]: Invalid parameter number in C:newprivatesearch.php on line 68. Here is the code, most of it, please. Kindly help me with what I am doing wrong, please.
Reply:
Hello Ezeribe Adolf!
Just create a separate placeholder for each keyword, and bind the same variable multiple times for them
and it would work
Great help, Execellent and thnaks a lot.
Hello, the following code seems to be OK, but displaying the array with foreach won’t work!
This yielded an ASSOC ARRAY $results.
It strikes me that it is an array within an array.
does not work, it does not display anything at all, although the (inner) array contains the desired filednamens (items) and values from the database as you can see. What do I wrong? Hope you have a solution
Reply:
Yes, fetchAll() returns you an array of arrays, it’s the exact purpose of this function.
When you iterate over its results, you get another array which represents a row from the database. And what we are doing with arrays? Using foreach. So you have to add another foreach inside the first one.
Or you can echo distinct elements without foreach, as shown in the article above:
I hate to be an ass but your code nor anybody I have found code from works that includes php themsleves I think You need to give a proper tutorial not a piece meal of not working code again I know this may anger You but what angers me is when i go to find code and I get half the code and it does not work.
Not a single one of your examples work for selecting anything like you explain I can assure that as I know i’m trying it. for the past week
I wish to change to PDO for inline table edit. I want to use your update query method, but have not been able to transpose it yet. Any help would be great.
Reply:
That’s a very good question.
Given you are updating just a single field, it would be easy to rewrite it to PDO
Note that $columns[$colIndex]’s value is hardcoded in your script and that’s the very right thing you are supposed to do, this part is already safe!
Источник
Uncaught exception ‘PDOException’ with message ‘SQLSTATE[HY093]:
Invalid parameter number: parameter was not defined’ in (строка 118) Stack trace: #0
PDOStatement->execute() #1 {main} thrown in
Строка 118 это $b->execute();
В целом понятно что он говорит что неверное количество параметров и какой-то не определён, но как-то можно заставить его показать какой именно?
Пробовал ставить:
echo $pdo->errorCode();
print_r($pdo->errorInfo());
Но он мне что-то ничего вообще не показывает.
-
Вопрос заданболее трёх лет назад
-
1679 просмотров
Перехватывайте исключение PDOException, в нем «зашита» более подробная инфа по ошибке. Плюс, в блоке catch вы можете обработать объект запроса PDOStatement, из которого можно вытянуть данные методом debugDumpParams(). Например:
try {
$stmt->execute($sq);
} catch (PDOException $e) {
print_r($e->getMessage());
$stmt->debugDumpParams();
}
php.net/manual/ru/class.pdostatement.php
php.net/manual/ru/class.pdoexception.php
Никак. Что разработчики посчитали нужным засунуть в исключение, то и имеем. Если уж сильно хочется, пишите свою обертку над PDO, и сами формируйте сообщение об ошибке. Ну совсем серьёзный вариант: написать pull request.
А вообще исключения не для отладки придумали.
Пригласить эксперта
-
Показать ещё
Загружается…
10 февр. 2023, в 02:20
3000 руб./за проект
10 февр. 2023, в 01:33
1500 руб./за проект
10 февр. 2023, в 00:54
2000 руб./в час
Минуточку внимания
PHP PDO Reference Manual
- PDO :: ERRMODE_SILENT
This is the default mode. PDO will simply set the error code, use the PDO :: errorCode () and PDO :: errorInfo () method to check the statement and database objects. If the error is due to the object of the call statement is generated, then you can call that object PDOStatement :: errorCode () or PDOStatement :: errorInfo () method. If the error resulted from a call on the database object, then invoke those methods on the database object.
- PDO :: ERRMODE_WARNING
In addition to setting the error code addition, PDO will emit a traditional E_WARNING message. If you just want to see what problems occurred without interrupting the flow of the application, so this setting in debugging / testing period is very useful.
- PDO :: ERRMODE_EXCEPTION
In addition to setting the error code addition, PDO will throw an exception PDOException class and set its properties to reflect the error code and error messages. This setting is also useful during debugging, because a wrong point it will effectively enlarge the script, which can very quickly point out potential problem area code (remember: if the exception causes the script to terminate the transaction is automatically back roll).
Another exception mode is very useful, compared to traditional PHP-style warnings, you can build your own error handling more clearly, and the return value of each database call, abnormal pattern code required compared to silent mode and explicitly checking / nesting less.
Create a PDO instance and set error mode
<?php $dsn = 'mysql:dbname=testdb;host=127.0.0.1'; $user = 'dbuser'; $password = 'dbpass'; try { $dbh = new PDO($dsn, $user, $password); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { echo 'Connection failed: ' . $e->getMessage(); } ?>
Note: Regardless of whether the current set PDO :: ATTR_ERRMODE, if the connection fails, PDO :: __ construct () will always throw a PDOException exception. Uncaught exception is fatal.
Create a PDO instance and set error mode in the constructor
<?php $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'googleguy'; $password = 'googleguy'; /* 使用 try/catch 围绕构造函数仍然有效,即使设置了 ERRMODE 为 WARNING, 因为如果连接失败,PDO::__construct 将总是抛出一个 PDOException 异常。 */ try { $dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING)); } catch (PDOException $e) { echo 'Connection failed: ' . $e->getMessage(); exit; } // 这里将导致 PDO 抛出一个 E_WARNING 级别的错误,而不是 一个异常 (当数据表不存在时) $dbh->query("SELECT wrongcolumn FROM wrongtable"); ?>
The above example will output:
Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.wrongtable' doesn't exist in /tmp/pdo_test.php on line 18 add a note add a note
PHP PDO Reference Manual
В этой статье разговор пойдет о PHP Data Objects (PDO) — расширение для PHP, предоставляющее разработчику универсальный интерфейс для доступа к различным базам данных.
В чем преимущество PDO? Этот вопрос можно раскрыть тремя пунктами:
- Универсальный интерфейс для работы с различными базами данных. Разработчик может легко перевести свое веб-приложение на другую СУБД, поменяв при этом всего пару строк кода.
- Высокая скорость работы.
- Подготовленные выражения, о которых мы поговорим чуть позже.
На данный момент расширение PDO может поддерживать СУБД для которой существует PDO-драйвер:
- PDO_CUBRID (CUBRID)
- PDO_DBLIB (FreeTDS, Microsoft SQL Server, Sybase)
- PDO_FIREBIRD (Firebird, Interbase 6)
- PDO_IBM (IBM DB2)
- PDO_INFORMIX (IBM Informix Dynamic Server)
- PDO_MYSQL (MySQL 3.x/4.x/5.x)
- PDO_OCI (Oracle Call Interface)
- PDO_ODBC (ODBC v3 (IBM DB2, unixODBC and win32 ODBC))
- PDO_PGSQL (PostgreSQL)
- PDO_SQLITE (SQLite 3 and SQLite 2)
- PDO_SQLSRV (Microsoft SQL Serve )
- PDO_4D (4D)
Подключение к базе данных
В зависимости от выбранной СУБД, способ подключения может незначительно отличаться. Подключение к популярным СУБД:
// MуSQL $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); // PostgreSQL $DBH = new PDO("pgsql:host=$host;dbname=$dbname", $user, $pass); //MS SQL $DBH = new PDO("mssql:host=$host;dbname=$dbname", $user, $pass); // SQLite $DBH = new PDO("sqlite:my/database/path/database.db");
Обработка ошибок и исключения
Обязательно заключайте подключение к базе данных в блок try/catch:
try { $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); } catch(PDOException $e) { echo "Нет соединения с базой данных"; }
Иначе, в случае ошибки, в браузер будет выкинут Fatal error, в котором будут раскрыты все подробности вашего соединения, с логином и паролем.
PDO умеет выбрасывать исключения при ошибках, поэтому все операции с базой, по хорошему, должны находиться в блоке try/catch.
PDO имеет три режима обработки исключения:
- PDO::ERRMODE_SILENT — режим по умолчанию, ошибки генерируются по такому же принципу, как в расширениях mysql или mysqli. После возникновения ошибки скрипт продолжит работу.
- PDO::ERRMODE_WARNING — режим вызовет стандартное сообщение E_WARNING и позволит скрипту продолжить работу.
- PDO::ERRMODE_EXCEPTION — режим выбрасывает исключение, что позволяет обрабатывать ошибки и скрывать важную информацию от посторонних глаз.
Чтобы установить необходимый уровень контроля ошибок необходимо вызвать метод $this->setAttribute после подключения к базе данных.
try { $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { echo "Нет соединения с базой данных"; }
Подготовленные выражения или Prepared Statements
Подготовленные выражения — это заранее скомпилированное SQL-выражение, которое может быть многократно выполнено путем отправки серверу лишь различных наборов данных. Дополнительным преимуществом является невозможность провести SQL-инъекцию.
За подготовленные выражения отвечает метод $DBH->prepare. Им и рекомендуется всегда пользоваться.
Сразу хочу отметить, что выполнить запрос в PDO можно тремя методами:
- $DBH->exec — используется для запросов, которые не возвращают никаких данных. Метод возвращает количество затронутых им записей, или FALSE в случае ошибки.
$count_row = $DBH->exec("DELETE FROM users");
- $DBH->query – используется выполнения не защищенных запросов, и возвращает результат или FALSE в случаи ошибки. Например, им можно выполнять простые запросы.
$DBH->query("SET NAMES 'cp1251'"); $DBH->query("SELECT * FROM users"); $DBH->query("DELETE FROM users");
- $DBH->prepare + $STH->execute — используется для подготовки выражений и выполнения запроса.
// безымянные placeholders $STH = $DBH->prepare("INSERT INTO users (name, phone, city) values (?, ?, ?)");
// именные placeholders $STH = $DBH->prepare("INSERT INTO users (name, phone, city) values (:name, :phone, :city)");
После подготовки, запрос выполняется методом $STH->execute($data).
// безымянные placeholders $data = array(); $data[] = 'Alersander'; $data[] = '+7 000 123 45 67'; $data[] = 'St. Petersburg'; $STH = $DBH->prepare("INSERT INTO users (name, phone, city) values (?, ?, ?)"); $STH->execute($data);
// именные placeholders $data = array(); $data['name'] = 'Alersander'; $data['phone'] = '+7 000 123 45 67'; $data['city'] = 'St. Petersburg'; $STH = $DBH->prepare("INSERT INTO users (name, phone, city) values (:name, :phone, :city)"); $STH->execute($data);
Выборка данных
Для выборки с произвольными параметрами тоже будем использовать метод $DBH->prepare. Данные выборки можно получить с помощью методов:
- $STH->fetch — выбирает следующую строку и возвращает в необходимом виде.
- $STH->fetchAll — возвращает массив всех выбранных строк.
- $STH->fetchObject — выбирает следующую строку и возвращает ее как объект.
Я буду рассматривать только первый метод, т.к. он универсальный и предоставляет разработчику, всё, что ему необходимо.
Методу $STH->fetch можно указать, в каком виде нам нужно предоставить результат:
- PDO::FETCH_BOTH (по умолчанию) — возвращает числовой и ассоциативный массив;
- PDO::FETCH_ASSOC — возвращает массив ассоциативный с названиями столбцов;
- PDO::FETCH_NUM — возвращает массив числовыми ключами в виде порядковых номеров столбцов;
- PDO::FETCH_OBJ — возвращает анонимный объект со свойствами, соответствующими именам столбцов;
- PDO::FETCH_BOUND — присваивает значения столбцов соответствующим переменным, заданным с помощью метода $STH->bindColumn();
- PDO::FETCH_CLASS — присваивает значения столбцов соответствующим свойствам указанного класса. Если для какого-то столбца свойства нет, оно будет создано;
- PDO::FETCH_INTO — обновляет существующий экземпляр указанного класса;
- PDO::FETCH_LAZY — объединяет в себе PDO::FETCH_BOTH и PDO::FETCH_OBJ.
$STH = $DBH->prepare("SELECT name, phone, city FROM users"); $STH->execute(); while($res = $STH->fetch(PDO::FETCH_ASSOC)) { echo $res['name']; } $STH = $DBH->prepare("SELECT name, phone, city FROM users"); $STH->execute(); while($res = $STH->fetch(PDO::FETCH_OBJ)) { echo $res->name; }
Закрытие соединения и освобождение буфера запроса
В PDO нет специальных методов для этих целей. Закрыть соединение с базой данных можно путем переопределения переменных:
$DBH = null; $STH = null;
Полезные методы
- $DBH->lastInsertId() — возвращает id последней вставленной записи.
- $DBH->query(string) — экранирует специальные символы в строковых данных таким образом, что их становится безопасно использовать в запросах.
- $STH->rowCount() — возвращает количество затронутых записей последним запросом.
Обработка ошибок PDO
Лично мне не нравится, что если я не заключаю все запросы в блок try/catch, то PDO выкидывает Fatal error со всеми интимными подробностями моего запроса. В промышленном приложении заключать каждый запрос в блок try/catch, это идиотизм!
Поэтому мы поступим следующим образом — немного расширим классы PDO и PDOStatement:
class DB extends PDO { public $error = false; // выводить сообщения об ошибках на экран? (true/false) public function __construct($dsn, $username='', $password='', $driver_options=array()) { try { parent::__construct($dsn, $username, $password, $driver_options); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement', array($this))); $this->query("SET NAMES 'cp1251'"); } catch(PDOException $e) { echo "Произошла ошибка в работе с базой данных..."; exit(); } } public function prepare($sql, $driver_options=array()) { try { return parent::prepare($sql, $driver_options); } catch(PDOException $e) { $this->error($e->getMessage()); } } public function query($sql) { try { return parent::query($sql); } catch(PDOException $e) { $this->error($e->getMessage()); } } public function exec($sql) { try { return parent::exec($sql); } catch(PDOException $e) { $this->error($e->getMessage()); } } public function error($msg) { if($this->error) { echo $msg; } else { echo "Произошла ошибка в работе с базой данных..."; } exit(); } }
class DBStatement extends PDOStatement { protected $DBH; protected function __construct($DBH) { $this->DBH = $DBH; } public function execute($data=array()) { try { return parent::execute($data); } catch(PDOException $e) { $this->DBH->error($e->getMessage()); } } }
Как видите, я реализую свои два класса DB и DBStatement, наследуя классы PDO и PDOStatement. Классы реализуют все необходимые мне для работы над ошибками методы, которые обрабатываются блоком try/catch.
$DBH = new DB("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->error = true; // Для отладки выводим сообщения об ошибках на экран. $STH = $DBH->prepare("SELEC * FROM users"); $STH->execute($data);
Как видите, я совершил опечатку в операторе и могу получить всю необходимую информацию об этой ошибке.
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELEC * FROM users' at line 1
Расширение функционала
Также бывает полезно расширить функционал PDO. Например, часто требуется получить количество записей в таблице.
Стандартными методами это можно делать следующим образом:
$data = array(); $data['user_id'] = 1; $STH = $DBH->prepare("SELECT COUNT(*) as count FROM users WHERE user_id=:user_id"); $STH->execute($data); echo $STH->fetch(PDO::FETCH_OBJ)->count;
Не слишком удобно. Поэтому реализуем в нашем классе методом count:
class DB extends PDO { // .................. public function count($sql, $data) { $res = $this->prepare($sql); $res->execute($data); return $res->fetch(PDO::FETCH_OBJ); } // .................. }
Получаем количество записей:
$DBH = new DB("mysql:host=$host;dbname=$dbname", $user, $pass); echo $DBH->count("SELECT COUNT(*) as count FROM users WHERE user_id=:user_id", array('user_id'=>'1'))->count;
Свои методы это конечно хорошо, но мне бы ещё хотелось писать все одной строкой. К сожалению, стандартными возможностями я не могу этого сделать:
$res = $DBH->prepare("SELECT * FROM users WHERE id_user=:id_user") ->execute(array('id_user'=>'1')) ->fetch(PDO::FETCH_ASSOC); echo $res['name']; // или так echo $DBH->prepare("SELECT *FROM users WHERE id_user=:id_user") ->execute(array('id_user'=>'1')) ->fetch(PDO::FETCH_OB) ->name;
Метод execute возвращает бесполезное логическое значение об успехе операции, а не объект DBStatement.
Допиливаем свой метод execute:
public function execute($data=array()) { try { parent::execute($data); return $this; } catch(PDOException $e) { $this->DBH->error($e->getMessage()); } }
Проверяем результат:
echo $DBH->prepare("SELECT COUNT(*) as count FROM users WHERE city=:city") ->execute(array('city'=>'St. Petersburg')) ->fetch(PDO::FETCH_OBJ) ->count;
Источник
Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.