PHP mysql query doesn't work - php

This is the query code:
if (isset($_POST['moduleAction']) && ($_POST['moduleAction'] == 'edit')) {
$date = date('Y-m-d H:i:s', time());
$stmt = $db->prepare('UPDATE todolist SET what = ?, priority = ?, added_on = ? WHERE id = ?');
$stmt->execute(array($what, $priority + 1, $date, $id));
}
My db connection:
<?php
try {
$db = new PDO('mysql:host=' . DB_HOST .';dbname=' . DB_NAME . ';charset=utf8mb4', DB_USER, DB_PASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (Exception $e) {
showDbError('connect', $e->getMessage());
}
The query is not executed on the db, on another page in the same document i am executing queries to the same db without problem. I've tried executing it without a prepared statement, double quotes, restarting te connection,... nothing works.
Anyone who can push me in the right direction?
EDIT
Setting variables:
$priorities = array('low','normal','high'); // The possible priorities of a todo
$formErrors = array(); // The encountered form errors
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0; // The passed in id of the todo
$what = isset($_POST['what']) ? $_POST['what'] : ''; // The todo that was sent in via the form
$priority = isset($_POST['priority']) ? $_POST['priority'] : 'low'; // The priority that was sent in via the form

You should always check for errors, there is so many reason an query fail to work as expected.
Here is the right way to check:
if(isset($_POST['moduleAction']) && ($_POST['moduleAction'] == 'edit')) {
$date = date('Y-m-d H:i:s', time());
$query ='UPDATE todolist SET what = ?, priority = ?, added_on = ? WHERE id = ?';
if($stmt = $db->prepare($query)){
if($stmt->execute(array($what, $priority + 1, $date, $id))){
echo 'execute() successful';
if($stmt->rowCount() > 0){
echo 'Affected a row';
}else{
echo 'No row affected';
}
}else{
echo 'execute() error:';
die($dbh->errorInfo());
}
}else{
echo 'prepare() error:';
die($dbh->errorInfo());
}
}
Edit
One more thing, $priority + 1 seem a little weird.
After your update I see this line:
$priority = isset($_POST['priority']) ? $_POST['priority'] : 'low';
so you try to increment a string by 1?
Anyway what happened to traditional debugging ?
$sql_debug = "UPDATE todolist
SET what = '$what', priority = '$priority', added_on = '$date'
WHERE id = $id";
echo "**************************************<br>";
echo $sql_debug."<br>";
echo "**************************************<br>";
error_log('sql = '.$sql_debug);
Take a look at the query
And run to see what happens

I think update query is correct,please check the date time format,try this code
if (isset($_POST['moduleAction']) && ($_POST['moduleAction'] == 'edit')) {
$date=date_create("2014-10-09");
date_time_set($date,13,24,46);
$datetime =date_format($date,"Y-m-d H:i:s");
$stmt = $db->prepare('UPDATE todolist SET what = ?, priority = ?, added_on = ? WHERE id = ?');
$stmt->execute(array($what, $priority + 1, $datetime, $id));
}

If your query is not execute and you get no error I would say that something is wrong with this
if(isset($_POST['moduleAction']) && ($_POST['moduleAction'] == 'edit')) {
Make sure your moduleAction is set in your post array and is really egal to 'edit'.
Hope this helps

Related

Scraping GPU data seems taking too long

so in my spare time I wanted to make a web to track the GPU price on a e-commerce. I am using PHP and the library Simple HTML DOM to parse the target HTML and it happen every hour from CRON Job.
(Yes, I knew I can make it in Selenium or others to scrape data more efficiently, but in this case just to challenge myself while learning it).
How it work is : Grab data and store it into database. Next, in other table it matches data from database : When the new price of a GPU is the same as latest price, it just update the date and time; If the new price is different with the latest, it make the latest price into old price and update some other things.
The scraping things is coded for a specific e-commerce website;
These variables placement are still scattered a little bit because I tried other
things;
It grab data every hour and logs the seconds on average 40-50, so my assumption is this processing time.
My question is : How can I make the code more efficient compared to my current method?
This is the code to grab the data :
<?php
error_reporting(E_ALL ^ E_WARNING);
require_once 'simple_html_dom.php';
// Database variables here
// ...
try {
$conn = new PDO("mysql:host=$servername;$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Get the URL List
$stmt = $conn->prepare("SELECT id,url FROM url_list");
$stmt->execute();
$url_list = $stmt->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE);
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
// Scrap the data from a website then return as array
function get_gpu_info(string $targeturl, int $gpu_id)
{
$results = array();
$html = new simple_html_dom();
$html->load_file($targeturl);
if (!empty($html)) {
$div_class = $price = $stock = "";
$div_class = $html->find("#main-pdp-container", 0);
$out_of_stock = $html->find(".css-1igct5v-unf-quantity-editor__input[disabled]", 0);
$price = $div_class->find(".price", 0)->innertext;
$price_int = intval(preg_replace('/[^\d\,]+/', '', $price));
$stock = ($div_class->find(".css-1a29oke p b", 0)->innertext) ?: 0;
if (!empty($price)) {
$results = array(
'GPUID' => $gpu_id,
'PRICE' => $price,
'PRICEINT' => $price_int,
'STOCK' => $stock
);
} else {echo "Price not found";}
} else {echo "URL Not Found";}
return $results;
}
// Scrap every single data from the URL list found
$gpu_data = array_map('get_gpu_info', array_values($url_list), array_keys($url_list));
try {
$time = date("H:i:s");
$date = date("Y-m-d");
$stmt = $conn->prepare("INSERT INTO price_history (gpu_id, price, price_int, stock, update_time, update_date)
VALUES (:insert_gpu_id, :insert_price, :insert_price_int, :insert_stock, :insert_update_time, :insert_update_date)");
$stmt->bindParam(':insert_gpu_id', $insert_gpu_id);
$stmt->bindParam(':insert_price', $insert_price);
$stmt->bindParam(':insert_price_int', $insert_price_int);
$stmt->bindParam(':insert_stock', $insert_stock);
$stmt->bindParam(':insert_update_time', $time);
$stmt->bindParam(':insert_update_date', $date);
foreach ($gpu_data as $data => $val) {
$insert_gpu_id = $val['GPUID'];
$insert_price = $val['PRICE'];
$insert_price_int = $val['PRICEINT'];
$insert_stock = $val['STOCK'];
$stmt->execute();
$stmt2 = $conn->prepare("SELECT COUNT(gpu_id) FROM gpu_data WHERE gpu_id = :gpu_id");
$stmt2->bindValue(':gpu_id', $val['GPUID'], PDO::PARAM_INT);
$stmt2->execute();
$count = (int)$stmt2->fetchColumn();
if($count) {
$stmt4 = $conn->prepare("SELECT old_price, old_price_int, latest_price, latest_price_int, latest_update_time, latest_update_date FROM gpu_data WHERE gpu_id = :gpu_id");
$stmt4->bindParam(':gpu_id', $val['GPUID']);
$stmt4->execute();
$old_data = $stmt4->fetch(PDO::FETCH_ASSOC);
$old_price_int = $old_data['old_price_int'];
$old_latest_price_int = $old_data['latest_price_int'];
$old_price = $old_data['old_price'];
$get_date = $old_data['latest_update_date'];
$get_time = $old_data['latest_update_time'];
$combined_old_date_time = date('Y-m-d H:i:s', strtotime("$get_date $get_time"));
if($old_price_int == $insert_price_int) {
//print_r("Same price");
$stmt3 = $conn->prepare("UPDATE gpu_data SET
stock = :stock,
latest_update_time = :update_time,
latest_update_date = :update_date
WHERE gpu_id = :gpu_id");
} else {
//print_r("Different price");
$stmt3 = $conn->prepare("UPDATE gpu_data SET
old_price = :old_price,
old_price_int = :old_price_int,
old_datetime = :old_datetime,
latest_price = :price,
latest_price_int = :price_int,
stock = :stock,
latest_update_time = :update_time,
latest_update_date = :update_date
WHERE gpu_id = :gpu_id");
$stmt3->bindParam(':old_price', $old_price);
$stmt3->bindParam(':old_price_int', $old_price_int);
$stmt3->bindParam(':old_datetime', $combined_old_date_time);
$stmt3->bindParam(':price', $insert_price);
$stmt3->bindParam(':price_int', $insert_price_int);
print_r("Old price updated");
}
$stmt3->bindParam(':update_time', $time);
$stmt3->bindParam(':update_date', $date);
$stmt3->bindParam(':stock', $insert_stock);
$stmt3->bindParam(':gpu_id', $val['GPUID']);
$stmt3->execute();
//print_r("GPU Data with the same record found and has been updated");
} else {//print_r("ERROR: No GPU Data with that GPU ID has been found");
}
}
//print_r("Price record/s updated successfully");
} catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();}
$conn = null;
?>
Thanks in advance!
It's likely you're taking a lot of time to load each page you're scraping. Probably some pages are a lot slower than others. Try doing something like this, to time your load_file() operations, to figure that out.
$loadStartTime = date();
$html->load_file($targeturl);
$loadEndTime = date();
echo $targeturl . ': ' . $loadEndTime - $loadStartTime . ' seconds to load.';
Your dom-romping code looks straightforward enough.
It seems doubtful you have many thousands of rows in your table, so your database stuff should be fast enough.

Prevent null values to being written in SQLite with PDO Php in Online Counter

I have a php script that counts how many users are online at any given time using php, sqlite and PDO. I using apache 2.4.53 and php 8.0.19 both at 64bit. The problem is that null values ​​are often written inside the database which cause the counter to increment unnecessarily and which are not canceled in any way, I have tried everything to eliminate the null values ​​that are written but I have not succeeded:
$deleteNull = $db->prepare('DELETE FROM online WHERE last_activity IS NULL AND id IS NULL');
$deleteNull->execute();
But is not working, I only found a trick that only counts the values ​​that are not null but obviously it is a hack because in the database these null values ​​are there and they remain there without being able to delete them:
$count = $db->query('SELECT COUNT() AS visitors FROM online WHERE last_activity IS NOT NULL AND id IS NOT NULL')->fetch(PDO::FETCH_ASSOC);
In the screenshot you can see 2 columns and 3 rows, 2 rows are legit, the 3rd is fake since is null. The result is that counter counts 3 visitors instead of 2. This happens on Linux machines (CentOS).
Is there any way to modify the script to prevent these null values ​​from being written in database?
<?php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
$_SESSION['id'] = (isset($_SESSION['id'])) ? $_SESSION['id'] : uniqid();
$secondsToConsiderOffline = 60;
$hitonlinedb = "online.sqlite";
try {
if (!file_exists($hitonlinedb)) {
$db = new PDO("sqlite:" . $hitonlinedb);
$db->exec('CREATE TABLE online(id TEXT PRIMARY KEY NOT NULL, last_activity INTEGER)');
} else {
$db = new PDO("sqlite:" . $hitonlinedb);
}
}
catch (PDOException $e) {
die($e->getMessage());
}
$currentTime = time();
$gracePeriod = $currentTime - $secondsToConsiderOffline;
$id = $_SESSION['id'];
$delete = $db->prepare('DELETE FROM online WHERE last_activity < :gracePeriod OR id = :id');
$delete->bindValue(':gracePeriod', $gracePeriod, PDO::PARAM_INT);
$delete->bindValue(':id', $id, PDO::PARAM_STR);
$delete->execute();
$insert = $db->prepare('INSERT INTO online(id, last_activity) VALUES (:id, :currentTime)');
$insert->bindValue(':id', $id, PDO::PARAM_STR);
$insert->bindValue(':currentTime', $currentTime, PDO::PARAM_INT);
$insert->execute();
$count = $db->query('SELECT COUNT() AS visitors FROM online')->fetch(PDO::FETCH_ASSOC);
if ($count['visitors'] <= 1) {
$visitors = 1;
} else {
$visitors = $count['visitors'];
}
echo $visitors;
$db = null;
?>
download the database to see the bug: online.sqlite
I edited the script like below, is there a good chance the following version will work fine?
<?php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
$_SESSION['id'] = (isset($_SESSION['id'])) ? $_SESSION['id'] : uniqid();
$secondsToConsiderOffline = 60;
$hitonlinedb = "online.sqlite";
try {
if (!file_exists($hitonlinedb)) {
$db = new PDO("sqlite:" . $hitonlinedb);
$db->exec('CREATE TABLE online(id TEXT PRIMARY KEY NOT NULL, last_activity INTEGER NOT NULL)');
} else {
$db = new PDO("sqlite:" . $hitonlinedb);
}
}
catch (PDOException $e) {
die($e->getMessage());
}
$currentTime = time();
$gracePeriod = $currentTime - $secondsToConsiderOffline;
$id = $_SESSION['id'];
$delete = $db->prepare('DELETE FROM online WHERE (last_activity < :gracePeriod OR last_activity IS NULL) OR (id = :id OR id IS NULL)');
$delete->bindValue(':gracePeriod', ((is_null($gracePeriod) || empty($gracePeriod)) ? time() - 60 : $gracePeriod), PDO::PARAM_INT);
$delete->bindValue(':id', ((is_null($id) || empty($id)) ? uniqid() : $id), PDO::PARAM_STR);
$delete->execute();
$insert = $db->prepare('INSERT INTO online(id, last_activity) VALUES (:id, :currentTime)');
$insert->bindValue(':id', ((is_null($id) || empty($id)) ? uniqid() : $id), PDO::PARAM_STR);
$insert->bindValue(':currentTime', ((is_null($currentTime) || empty($currentTime)) ? time() : $currentTime), PDO::PARAM_INT);
$insert->execute();
$count = $db->query('SELECT COUNT() AS visitors FROM online')->fetch(PDO::FETCH_ASSOC);
if ($count['visitors'] <= 1) {
$visitors = 1;
} else {
$visitors = $count['visitors'];
}
echo $visitors;
$db = null;
?>

Update an enum type

This is my Code:
public function enUser($userID) {
try {
$userStatus = "Y";
$tokenCode = "";
$sql = ('UPDATE tbl_users SET userStatus = ? AND tokenCode = ? WHERE userID = ?');
$stmt = $this->conn->prepare($sql);
$stmt->bindParam(1, $userStatus);
$stmt->bindParam(2, $tokenCode);
$stmt->bindParam(3, $userID);
$stmt->execute();
} catch (PDOException $e) {
echo $e->getMessage();
}
}
This is my enum in database
I have try more to edit it. But in database always appear nothing. I mean in the field 'userStatus' after running the update script, its just value like "" (empty). Can any one help me? Thanks.
You update must be:
'UPDATE tbl_users SET userStatus = ?, tokenCode = ? WHERE userID = ?
See the comma instead of AND
And make sure that $userID exists in your DB

How do i troubleshoot this MySQL error?

I'm making a simple website for a class, and I am trying to save information to my database. The error is not very specific and I do not know which part of my code I need to fix.
Error message:
check the manual that corresponds to your MariaDB server version for
the right syntax to use near ')' at line 2
My PHP code:
<?php
include 'mysqli.php' ;
$result = $con->query("select * from setList s
left join songTable t on s.SetList_ID = t.Song_ID
left join bands b on s.SetList_ID = b.Band_ID");
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$setList = $_POST['setlist'];
$venue = $_POST['venue'];
$date = $_POST['dateOfShow'];
$band= $_POST['band'];
$set = $result->fetch_object();
//error handling and form
try {
if (empty($setList) || empty($venue) || empty($date) || empty($band)) {
throw new Exception(
"All Fields Required");
}
if (isset($set)) {
$id = $set->SetList_ID;
$q = "update setList set SetList_Name = '$setList',
Venue = '$venue', Show_Date = $date, Band_Name = '$band')";
}
else{
$q = "insert setList (SetList_Name, Venue, Show_Date, Band_Name)
values ('$setList', '$venue', $date, '$band')";
}
$result = $con->query($q);
if (!$result) {
throw new Exception($con->error);
}
header('Location:my_set-lists.php');
} catch(Exception $e) {
echo '<p class ="error">Error: ' .
$e->getMessage() . '</p>';
}
}
?>
The error message tells you exactly where the problem is; you have an extra ). Replace
$q = "update setList set SetList_Name = '$setList',
Venue = '$venue', Show_Date = $date, Band_Name = '$band')";
// extra ) is here ---------------------------------------------^
With
$q = "update setList set SetList_Name = '$setList',
Venue = '$venue', Show_Date = $date, Band_Name = '$band'";
Note: your next query (starting insert setList) is also going to fail; it should be INSERT INTO setList.... A decent IDE (like PHPStorm) would catch these errors for you.
Also, you are wide open to SQL injection. You really need to be using prepared statements.

Why MySQLI prepare is failing but no errors is being reported

I am stuck up as to why my Update prepare statement is failing but though I do not see any SQL error:
<?php
include(dirname(__FILE__).'\config.php' );
$id = $_POST['id'] ;
$value = $_POST['value'] ;
$column = $_POST['columnName'] ;
$columnPosition = $_POST['columnPosition'] ;
$columnId = $_POST['columnId'] ;
$rowId = $_POST['rowId']
$response['status']='';
$mysqli = new mysqli($sql_details['host'],$sql_details['user'],$sql_details['pass'],$sql_details['db']);
$mysqli->autocommit(FALSE);
$stmt = $mysqli->stmt_init();
if ($stmt = $mysqli->prepare("UPDATE users SET ? = ? where id = ?")) {
$response['status']='OK';
//$stmt->bind_param("ssi", $column, $value, intval(ltrim(substr($id, -4),'0')));
//$stmt->execute();
//$response['status'] = $mysqli->affected_rows;
//if ($mysqli->affected_rows == 1 )
//$response['status'] = 'success';
$stmt->close();
//if (!$mysqli->commit())
//$response['status'] = 'fail';
$mysqli->close();
}
else
$response['status']=$mysqli->error;
}
echo json_encode($response);
?>
Even though I have commented most of the lines and expect to the conditional string 'OK' at my UI side - I never ever see that . No errors is also reported - what am I doing wrong?
It seems that the UPDATE prepared statement works fine when in case of column name is present rather than a bind value like the below one works:
if ($stmt = $mysqli->prepare("UPDATE users SET first_name = ? where id = ?"))
Is there any way to have it the way I have requested?

Categories