hi,
ich hoffe der beitrag passt hier her.
es geht um das verhalten von PDO und mysqli bei prepared statements. Sie unterscheiden sich was das binden und casten der parameter angeht und ich habe mich gefragt, welche der beiden vorgehensweisen wohl richtiger ist.
folgende zwei codes
das ist zwei mal das selbe statement. beide male soll '789jkl' an das statement als integer gebunden werden. eingetragen werden soll das in das id-feld der tabelle welches den datentyp INT hat.
strict_all_tables bewirkt dass warnungen der datenbank zu fehlern werden. und ein fehler wird hier auch erwartet:
oder wenn wir 'jkl' einfügen wollen:
bei dem code von PDO wird der fehler geworfen, denn PDO ist die angabe des data types anscheinend egal und es schickt den Parameter unverändert an die datenbank.
bei mysqli wird erst ein typecast zu int durchgeführt und dann ein integer an die datenbank geschickt. so erkennt die datenbank gar nicht das falsche werte angekommen sind. nur bei sehr großen zahlen wird nicht gecastet.
nun frage ich mich welche schnittstelle sich hier richtiger verhält.
ich denke PDO. es ist nicht aufgabe der datenbankschnittstelle zu casten. dadurch dass die daten wie sie sind bei der datenbank ankommen ist es möglich überhaupt den fehler zu sehen. mysqli "versteckt" den fehler.
andererseits sollte so ein fehler vielleicht gar nicht erst bei der datenbank ankommen? ist es nicht aufgabe des programms die daten auf korrektheit zu prüfen und ja nach fall zu entscheiden ob ein typecast ok ist oder ob die daten zurückgewiesen werden sollen?
in dem fall wäre es allerdings auch wieder nicht aufgabe der datenbankschnittstelle sondern schon davor. was mich zu meiner nächsten frage bringt: warum kann bzw muss man überhaupt datentypen angeben beim binden der parameter? (außer bei LOBs)
eventuell ist es dann doch besser immer als datatype string anzugeben. wobei hier PDO auch wieder was komisches macht und castet
man muss in dem fall aufpassen, dass man die variable $id erst nach bindParam definiert. dann wird auch nicht gecastet.
lg
dingsda
ich hoffe der beitrag passt hier her.
es geht um das verhalten von PDO und mysqli bei prepared statements. Sie unterscheiden sich was das binden und casten der parameter angeht und ich habe mich gefragt, welche der beiden vorgehensweisen wohl richtiger ist.
folgende zwei codes
PHP-Code:
$mysql=new mysqli('localhost','root','', 'test2');
$driver=new mysqli_driver();
$driver->report_mode=MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT;
$mysql->real_query('SET SESSION sql_mode = \'STRICT_ALL_TABLES\';');
$stmt=$mysql->prepare('insert into testtabelle (id) values (?)');
$stmt->bind_param('i',$id);
$id='789jkl';
$stmt->execute();
PHP-Code:
$pdo=new PDO('mysql:host=localhost;dbname=test2','root');
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
$pdo->exec('SET SESSION sql_mode = \'STRICT_ALL_TABLES\';');
$stmt=$pdo->prepare('insert into testtabelle (id) values (?)');
$id='789jkl';
$stmt->bindParam(1,$id,PDO::PARAM_INT);
$stmt->execute();
strict_all_tables bewirkt dass warnungen der datenbank zu fehlern werden. und ein fehler wird hier auch erwartet:
Data truncated for column 'id' at row 1
Incorrect integer value: 'jkl' for column 'id' at row 1
bei mysqli wird erst ein typecast zu int durchgeführt und dann ein integer an die datenbank geschickt. so erkennt die datenbank gar nicht das falsche werte angekommen sind. nur bei sehr großen zahlen wird nicht gecastet.
nun frage ich mich welche schnittstelle sich hier richtiger verhält.
ich denke PDO. es ist nicht aufgabe der datenbankschnittstelle zu casten. dadurch dass die daten wie sie sind bei der datenbank ankommen ist es möglich überhaupt den fehler zu sehen. mysqli "versteckt" den fehler.
andererseits sollte so ein fehler vielleicht gar nicht erst bei der datenbank ankommen? ist es nicht aufgabe des programms die daten auf korrektheit zu prüfen und ja nach fall zu entscheiden ob ein typecast ok ist oder ob die daten zurückgewiesen werden sollen?
in dem fall wäre es allerdings auch wieder nicht aufgabe der datenbankschnittstelle sondern schon davor. was mich zu meiner nächsten frage bringt: warum kann bzw muss man überhaupt datentypen angeben beim binden der parameter? (außer bei LOBs)
eventuell ist es dann doch besser immer als datatype string anzugeben. wobei hier PDO auch wieder was komisches macht und castet
PHP-Code:
$id=789;
$stmt->bindParam(1,$id,PDO::PARAM_STR);
$stmt->execute();
var_dump($id); // ergibt string '789'
lg
dingsda
Kommentar