PHP PDO prepared statment - unable to insert boolen value of false - php

I am trying to insert a boolean value with PDO into MySQLdatabase. If $data['age2'] is false the insertion doesn't take place but if true then it works. If I use the ->bindParam() method it works again. But if it was possible I would pass my variables in an associative array. Do you have an idea what I am doing wrong. at the bottom of the code I have inserted the code for the creation of the table (I want to insert into) as well. thanks
<?php
$host = 'localhost';
$user = 'root';
$password = '12345';
$dbName = 'pdo';
// set DSN data sorce name
$dsn = "mysql:host={$host};dbname={$dbName}";
// create pdo instance
$pdoConn = new PDO($dsn, $user, $password);
$pdoConn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$data = [
':fname' => 'Bob',
':sname' => 'Desaunois',
':age' => '18',
':age2' => true
];
$sql = 'INSERT INTO posts (title, body, author, is_published) VALUES (:fname, :sname, :age, :age2)';
$statement = $pdoConn->prepare($sql);
$statement->execute($data);
/*
SHOW CREATE TABLE posts;
'posts', 'CREATE TABLE `posts` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `title` char(255) NOT NULL,\n `body` text NOT NULL,\n `author` char(255) NOT NULL,\n `is_published` tinyint(1) DEFAULT \'0\',\n `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=150 DEFAULT CHARSET=latin1'
posts, CREATE TABLE `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` char(255) NOT NULL,
`body` text NOT NULL,
`author` char(255) NOT NULL,
`is_published` tinyint(1) DEFAULT '0',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=150 DEFAULT CHARSET=latin1
*/

Related

PDO query updating a datetime column not in query

A PDO prepared update statement is somehow updating the datetime column for the selected record in the table, even though that particular datetime column is not even in the query.
if(isset($_POST['editCriteria']))
{
$value = $_POST['editCriteria'];
$editusername = $value['editusername'];
$hiddenUsername = $value['hiddenUsername'];
$editfullname = $value['editfullname'];
$editemail = $value['editemail'];
$edituserlevel = $value['edituserlevel'];
$editdivision = $value['editdivision'];
$editdept = $value['editdept'];
$editphone = $value['editphone'];
try
{
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$update = $dbc->prepare("UPDATE users_edi SET username = :uname,
fullname = :fname, userlevel = :ulevel, email = :uemail,
division = :udivision, dept = :udept, phone = :uphone WHERE username = :hname");
$update->execute([
'uname' => $editusername,
'fname' => $editfullname,
'ulevel' => $edituserlevel,
'uemail' => $editemail,
'udivision' => $editdivision,
'udept' => $editdept,
'uphone' => $editphone,
'hname' => $hiddenUsername
]);
if($update)
{
echo "Success: User has been updated.";
}
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
}
In the database table, there is a column called lastLoginDate that is being updated to the current datetime.
If you'll notice in the update statement above, the query does not include lastLoginDate.
How is lastLoginDate being updated when it's not even in the query?
Upon using the SHOW CREATE TABLE command, there was indeed a trigger on the lastLoginDate column.
CREATE TABLE `users_edi` (
`username` varchar(30) NOT NULL DEFAULT '',
`fullname` varchar(50) DEFAULT NULL,
`userlevel` tinyint(1) unsigned NOT NULL,
`ipaddress` varchar(30) DEFAULT NULL,
`email` varchar(150) DEFAULT NULL,
`entrydate` datetime DEFAULT NULL,
`division` varchar(35) DEFAULT NULL,
`password` varchar(32) DEFAULT NULL,
`userid` varchar(32) DEFAULT NULL,
`timestamp` int(11) unsigned NOT NULL,
`job_title` varchar(30) DEFAULT NULL,
`dept` varchar(50) DEFAULT NULL,
`phone` varchar(11) DEFAULT NULL,
`lastLoginDate` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, // <-- here
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I will have to ask another question on how to remove this trigger.

Why is MySql not storing boolean value with php

I have a database table with two columns that have been set as boolean. Whenever I store something in the table everything works correctly except the boolean columns are always false. The columns are featured post and published.
I am using php 7.1.1 and MariaDB 10.1.21 on my xampp local installation.
Output of show table:
CREATE TABLE `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
`seo_description` varchar(255) NOT NULL,
`featured_post` tinyint(1) NOT NULL DEFAULT '0',
`published` tinyint(1) NOT NULL DEFAULT '0',
`seo_title` varchar(255) NOT NULL,
`post_type` enum('blog','product') NOT NULL,
`featured_image_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `title` (`title`),
UNIQUE KEY `seo_title` (`seo_title`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
Php code defining onr of the variables, the other is exactly the same:
if(isset($_POST["published"])){
$published = sanitizeInput($_POST["published"]);
if($published){ //test to see if correct values where being sent and they were
echo json_encode("boolean true");
} else {
echo json_encode("boolean false");
}
} else {
$published = false;
}
$query = "insert into posts "
. "(title, content, seo_description, featured_post, published, seo_title, post_type, category_id) "
. "values "
. "(:title, :content, :seo_description, :featured_post, :published, :seo_title, :post_type, :category_id)";
$stmt = $pdo->prepare($query);
$stmt->bindValue("featured_post", $featuredPost, PDO::PARAM_BOOL);
$stmt->bindValue("published", $published, PDO::PARAM_BOOL);
$stmt->bindValue("title", $title);
$stmt->bindValue("content", $content);
$stmt->bindValue("seo_description", $seoDescription);
$stmt->bindValue("seo_title", $seoTitle);
$stmt->bindValue("post_type", $postType);
$stmt->bindValue("category_id", $categoryId);
$stmt->execute();
Any help would be much appreciated.
Thanks in advance

Mysqli prepared insert with nested selects fails in foreach

I'm trying to insert some date to MySQL table with prepared insert with nested 3 nested selects in it. The thing is that for all nested selects a single variable is used. Actual SQL:
INSERT INTO db_test.offers
(`id`,`catalog_service_id`,`offer_name`,
`offer_description`,`offer_url`,
`offer_interaction_format`,`offer_methods`)
VALUES(1,
(SELECT `catalog_service_id` FROM db_test.catalog_services
WHERE `catalog_service_code` = ?),
(SELECT `catalog_service_name` FROM db_test.catalog_services
WHERE `catalog_service_code` = ?),
(SELECT `catalog_service_name` FROM db_test.catalog_services
WHERE `catalog_service_code` = ?),
'https://url.com', 'json', 'CC');
PHP code:
class test extends mysqli{
function db_action($host = null){
$mysqli = new mysqli($host, MYSQL_USER, MYSQL_PASS, "db_test");
if(!$mysqli){
die ("couldn't connect to mysql host" . mysqli_connect_error());
}
$codes= ["AAAAA005760000000001","ААААА032680000000001","ААААА032680000000002"];
$query="SQL code from above";
$stmt = $mysqli->prepare($query);
$stmt ->bind_param("sss", $offer, $offer, $offer);
foreach ($codes as $k => $offer) {
if($stmt->execute() === false){
print 'Wrong SQL. Error: ' . $stmt->error . "\r\n";
}else{
$last_inserted_id = $mysqli->insert_id;
print "Insert row with id: " . $last_inserted_id . " for service_code: ". $offer . "\r\n";
}
}
$stmt->close();
}
}
First iteration of foreach works fine (1 row is inserted with correct data), but on 2nd and 3rd (just for an example, real number of elements in $codes array is unknown). The The executed statement on the sql-server is executed with question marks instead of actual value. When I go through the function in debugger - the value of $offer var changes on each iteration of for each.
SQL error that comes from the server is obvious: catalog_service_id cannot be null.
table info:
CREATE TABLE `offers` (
`offer_id` int(11) NOT NULL AUTO_INCREMENT,
`id` int(11) NOT NULL,
`catalog_service_id` int(11) NOT NULL,
`offer_name` varchar(255) DEFAULT NULL,
`offer_description` varchar(1000) DEFAULT NULL,
`offer_create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`offer_start_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`offer_stop_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`offer_url` varchar(256) NOT NULL,
`offer_auth` enum('Basic','Digest') DEFAULT NULL,
`offer_auth_name` varchar(255) DEFAULT NULL,
`offer_auth_password` varchar(255) DEFAULT NULL,
`offer_auth_secret` varchar(255) DEFAULT NULL,
`offer_operator_id` int(11) NOT NULL,
`public_offer_url` varchar(1000) NOT NULL,
`offer_interaction_format` enum('urlencoded','json') NOT NULL DEFAULT 'urlencoded',
`offer_methods` enum('CC','MC') NOT NULL DEFAULT 'MC',
`offer_inn` varchar(20) DEFAULT NULL,
`offer_kpp` varchar(20) DEFAULT NULL,
`offer_min` int(11) DEFAULT NULL,
`offer_max` int(11) DEFAULT NULL,
PRIMARY KEY (`offer_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
I'm really stuck...

PDO not inserting more than one row in table

I'm having trouble inserting image data into my database. I have a table called images. When dumped with PHPMyAdmin it looks like this:
CREATE TABLE IF NOT EXISTS `images` (
`id` int(11) NOT NULL,
`orig_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`hash` varchar(6) COLLATE utf8_unicode_ci NOT NULL,
`filename` varchar(12) COLLATE utf8_unicode_ci NOT NULL,
`uploaded` datetime NOT NULL,
`views` int(11) NOT NULL DEFAULT '0',
`album_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`server_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `server_id` (`server_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
This is the code I'm using to insert rows:
// Database connection
$db = new PDO('mysql:host=localhost;dbname=testdb', 'root', '');
// some code...
$st = $db->prepare('INSERT INTO `images` (orig_name, hash, filename, uploaded, server_id)
VALUES (?, ?, ?, ?, (SELECT `id` FROM `servers` WHERE `name` = ?))');
$st->execute(array($origName, $fileHash, $filename, date('c'), $server));
// more code...
// Database cleanup
$st = null;
$db = null;
The script returns no errors, and works flawlessly for the first row inserted. If the script runs again, it fails to insert any more rows in the images table. I see no reason why it'd behave like this, the data going into each field is unique each time (except for the server_id field).
Your id field isn't set to auto_increment.
The first record that you post will be added, with a NULL as id; the second record won't be added because there's already a record with NULL as the primary key, so it'll fail - you don't have any error checking in the code, so it won't be printing out the errors it's getting back.

Why mysql_insert_id returns 0 in my case?

This is my table:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(20) NOT NULL default '',
`pass` varchar(32) NOT NULL default '',
`lang` varchar(2) default NULL,
`locale` varchar(2) default NULL,
`pic` varchar(255) default NULL,
`sex` char(1) default NULL,
`birthday` date default NULL,
`mail` varchar(64) default NULL,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `mail` (`mail`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ;
And this is my query:
$query = "INSERT IGNORE INTO `users` (`name`, `mail`, `birthday`, `lang`, `locale`, `sex`, `pic`) VALUES ('".$name."', '".$email."', '".date_format($birthdaynew, 'Y-m-d H:i:s')."', '".substr($locale, 0, 2)."', '".substr($locale, -2, 2)."', '".$sex."', 'pic/".$uid.".jpg')";
$rows = mysql_query($query) or die("Failed: " . mysql_error());
$_SESSION['id'] = mysql_insert_id(); // I have tryed also mysql_insert_id($db_con) where $db_con is the link to db.
$_SESSION['name'] = $name;
$_SESSION['name'] contains correctly the name but $_SESSION['id'] contains 0.
Why ?
I'm going crazy!
Is there a particular reason why you are using INSERT IGNORE?
If you use INSERT IGNORE, then the row won't actually get inserted if there is a duplicate key (PRIMARY or UNIQUE), or inserting a NULL into a column with a NOT NULL constraint.
Referring to the pass column, as you have not defined anything to insert into it, and it has NOT NULL constraint.
EDIT:
Referring also to the mail column, as you have a UNIQUE constraint on it.

Categories