I am trying to do transactions in PHP . I have a class:
public function grabar($fecha) {
try {
$sql = "INSERT INTO tabla1 (cod, nom, :fecha)
SELECT cod, nom
FROM tabla2
WHERE flag1 IS NULL AND flag2 IS NULL";
$dbh = new ConnectDB();
$dbh->beginTransaction();
$dbh->bindParam(':fecha', $fecha, PDO::PARAM_STR); //-- AQUI SALE EL PROBLEMA
$dbh->query($sql);
$dbh->commit();
} catch (Exception $e) {
echo "Se produjo un error: ". $e->getMessage();
$dbh->rollback();
}
My connection to the database, ConnectDB is:
class ConnectDB extends PDO {
public function __construct () {
try {
parent:: __construct('mysql:host='.aa.';dbname='.bb.'; charset=utf8', user, pass);
parent:: setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
parent:: setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $ex) {
die ('La Base de Datos no Existe');
}
The invocation to the class:
$ClaseDAO->grabar($fecha);
And $date is in the format YYYY-MM-DD.
The error it shows me is: Fatal error:Fatal error: Uncaught Error: Call to undefined method ConexionDB::bindParam() in C:\ruta... \ClaseDAO.class.php:21 Stack trace: #0 C:\ruta... \controlador.php(216): ClaseDAO->grabar('2021-10-31') #1 C:\ruta... \index.php(12): include('C:\\ruta \\...') #2 {main} thrown in C:\ruta... \ClaseDAO.class.php on line 21
Note: To test I removed $fecha
from the class and it works. So apparently the problem is with $fecha
, but I don't understand why.
The error
Call to undefined method ConexionDB::bindParam()
is happening because the methodbindParam()
belongs to the objectPDOStatement
and that object is obtained withprepare()
or withquery()
.Therefore, you must first prepare the query and call
bindParam()
on the object resulting from the preparation.You are doing it backwards, calling this at the very end:
Also, you can't use
query()
with prepared queries (with bookmarks). And even if they were not with markers, since you are in a transaction context, it is always convenient to useprepare()
, which would be faster, because itprepare()
traces a query execution plan, making successive queries much faster, whichquery()
it does not do . .Finally, you have to conclude with a
execute()
.Applying what was said, the code would look like this:
Apart from that, it is worth taking into account the following, in order to improve the code...
Your three calls to
:.parent
I'm not convinced. I have not verified it, but it seems to me that you can only make a call to the parent, to pass what you cannot assign to the child.I'm also not convinced by the white spaces you leave between
parent::
and the method. Neither in the Manual nor in any code do I see that blank spaces are left.Since the PDO constructor supports a last parameter where you can pass it an array of configurations, try this:
In case that is not possible, you could assign those attributes to the child. As I said before, I haven't confirmed it, but, thinking about Java,
super()
(the constructor of the parent), it is always called only once, not several times... Multiple calls would not make sense.