简体   繁体   中英

Can I get PHP's PDO to return MySQL warnings, instead of only error messages?

I'm trying to get as much information back to my users as possible, and I would like to be able to tell them if there has been a warning from one of the operations they have just performed, for example if data has been truncated because it has been stuffed into a field that is too short, or they've tried to put letters or a decimal into an integer field.

For testing purposes I have reduced my code to this on a page on it's own:

<?php
        error_reporting(E_ALL);
        ini_set('display_errors', True);
        session_start();
        include '../php/security.php';
        sec::dieifnotvalid();
        include '../php/db_connection_params.php';

        $pdo_conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
        $qry_string = "insert into tbl_engine (capacity) values (?)";
        $var_array = array('gfd');
        $q = $pdo_conn->prepare($qry_string);
        $q->execute($var_array);
        $return_arr = $q->fetchAll();


        var_dump($q->errorInfo());
        ?>

if I try to execute something like this,

$qry_string = "insert into tbl_manufacturer_lookup (manufacturer_name) values (?)";
$var_array = array('Audi');

which would be inserting a duplicate entry into a unique column, I get

array(3) { [0]=> string(5) "00000" [1]=> int(1062) [2]=> string(57) "Duplicate entry 'Audi' for key 'manufacturer_name_UNIQUE'" }

printed on the page. which is good.

But if I do something like this,

    $qry_string = "insert into tbl_engine (capacity) values (?)";
    $var_array = array('hjgt');

which is inserting a string into an integer field, the errorinfo is

array(3) { [0]=> string(5) "HY000" [1]=> NULL [2]=> NULL }

which is exactly the same as if I inserted an integer value.

By comparison, MySQL workbench will return something like this:

1 row(s) affected, 1 warning(s): 1366 Incorrect integer value: 'fdd' for column 'capacity' at row 1

I would really like to get my web app to return something useful like this

Execute SHOW WARNINGS query. More on it here .

For those looking, a quick and easy way to do this is with the query SHOW WARNINGS . Here is an easy function to reuse as needed.

function lastWarning($pdo)
{
    var_dump($pdo->query("SHOW WARNINGS")->fetch());
}

You can make this as pretty as you want. For example, in a PDO child class:

namespace Foo;

class PDO extends \PDO 
{
    public function getWarning()
    {
        $warnings = $this->query('SHOW WARNINGS')->fetch();
        if ($warning['Level'] == 'Error') {
            return "Warning: {$warning['Message']} [#{$warning['Code']}]\n";
        }
    }

}

If I were you I would simple not rely on such warnings. You should simple in PHP do extra query and validate data and show some warnings (for example for duplicated unique keys) or for fields that should be integer (and they don't).

Otherwise you may insert into database some data that shouldn't be put there (for example 5,52 as decimal would be a problem and maybe you should correct it in PHP or let user to input correct value)

To extract PDO warnings, initialise your PDO object like so:

$pdo_conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass, array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING
));

Note, this should only be used for debugging purposes, as messages often contain sensitive information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM