PDO Ajax updating mysql database - php

I need help in this PHP Ajax updating mysql database using PDO. I wanted to update the database if a user checks the checkbox. Below is my code:
JS:
$('input[name=product_new]').click(function(){
var chkbox_id = $(this).attr('alt');
var chkbox_selected = $(this).is(':checked');
if(chkbox_selected == true)
{
chkbox_selected = "checked";
}
else
{
chkbox_selected = "uncheck";
}
$.post({
url: "../products_listing.php",
type: "POST",
data: {product_id: chkbox_id, product_new: chkbox_selected},
cache: false,
success: function(){}
});
});
PHP page with PDO to update database:
$id = $_POST['product_id'];
$product_new = $_POST['product_new'];
if(isset($_POST['product_new']))
{
try
{
$query = "UPDATE productinfo SET new_arrival=? WHERE id=?";
$stmt_new_chkbox = $conn->prepare($query);
$stmt_new_chkbox->bindParam(1, $product_new, PDO::PARAM_STR);
$stmt_new_chkbox->bindParam(2, $id, PDO::PARAM_INT);
$stmt_new_chkbox->execute();
}
catch(PDOException $e)
{
echo 'ERROR: ' . $e->getMessage();
}
}
It was working when I use mysql but now I've changed it to use PDO, it won't work anymore. I can't find where went wrong. Thanks in advance guys.
Below is the old code from mysql_:
$id = mysql_real_escape_string($_POST['product_id']);
$product_new = mysql_real_escape_string($_POST['product_new']);
if(isset($_POST['product_new']))
{
$upt_new=mysql_query("update products_list set new_arrival='$product_new' where id='$id'");
}
Ok! I know what's wrong already. The damn directory path. I took out ../ and it works! Kinda weird though.
Because my js file is in JS folder and products_listing.php is outside of the js folder. Isn't it supposed to be ../products_listing.php?
Can anyone tell me why it's not working which it is supposed to be?
Thanks in advance guys!

Just split your task into 2 parts: AJAX part and PDO part.
First of all make sure that your PDO part works well. Make a mock $_POST array, and then start playing with PDO calling this script directly, without AJAX. Ask questions here, if something goes wrong. then, as you ret it to work, move to AJAX part, the same way - first, without PDO by just by sending data to server and verifying if it's correct.
Solving 2 problems at once makes things a lot harder. Always split your task into separate parts and solve them one by one.

Related

Implement Ajax for a PHP Function

I am trying to work implement ajax due to maximum site load which PHP causes. But I am not aware of where I am making a mistake here. it is an anchor tag, when it is clicked the status of the particular row should be changed to a string which is hard coded.
PHP WAY
USERDETAIL.PHP
Next
Then it triggers This (IGNORE SQL INJECTION)
if(isset($_GET['changeStatus'])){
$id = $_GET['changeStatus'];
$user=$_SESSION['user'];
$sql = "select * from productOrder where id = ".$id;
$result = mysqli_query($conn, $sql);
if(mysqli_num_rows($result) > 0){
$row = mysqli_fetch_assoc($result);
$sql = "update productOrder set prodStatus = 'Ready', By='".$user."' where id=".$id;
if(mysqli_query($conn, $sql)){
header("Location:USERDETAIL.php");
}
}
}
According to this way, it works neat, but the userdetail.php would refresh anyways which is a lot time consuming. Then tried AJAX way is below.
Next
and that hits to
$(document).ready(function() {
$(".changeStatus").click(function(event){
event.preventDefault();
var status = "Ready";
var id = $(this).attr('data-id');
$.ajax({
url : 'action.php',
method : 'POST',
data : {status : status , id : id},
dataType: 'html',
success : function(response){
console.log(response);
}
});
});
});
and in the action.php it is (IGNORE SQL INJECTION AGAIN)
if(isset($POST['prodStatus'])){
$status = $_POST['prodStatus'];
$id = $_POST['id'];
$sql = "update productOrder set prodStatus= '$status' where id=".$id;
$result = mysqli_query($conn, $sql);
if($result){
return 'Updated';
}
}
The output is nothing happens. in the console it is just adding int values. I know I am making a mistake, or understood AJAX in a wrong way. it is just one button click and the string in SQL should be updated without an input text / modal. Please suggest what should be improved?
Also instead of having a seperate action php for these actions, can I do all these in userdetail.php itself with Ajax? is it possible?
Thanks in advance.
As B_CooperA pointed out, $POST should be $_POST.
Also, in $.ajax script data object your property name is status and in action.php you are checking it by prodStatus.
Furthermore, you should check the errors PHP is throwing in your script by enabling error reporting: error_reporting(E_ALL);
It's better to separate ajax calls from your view files. You can create a Class to handle all of your ajax calls (You should also consider authenticating your calls as per your use cases).

PHP MySQL Update after Seconds

I want to update a MySQL field after when the site was opened for X Seconds.
I get the Seconds/Time from MySQL and want to update in MySQL when the seconds are over.
I tried
sleep($adddisplaytime);
but then the site waits complete and does not run the things over first
Is there a way to run my update after some seconds when the site is opened?
$query1 = "UPDATE ads SET views = views+1, costs = costs+price WHERE id = '".$adid."'";
Can be in PHP or MySQL
NOTE: This will do what you want, but could be exploited by someone hitting the AJAX endpoint repeatedly, you would want to build in some protections for that.
You will need an additional PHP file, the job of that PHP is to only update the db. You will need to take that update OUT of your page loading script.
Your HTML / JS / PHP for initial load
<script>
setTimeout(function() {
$.ajax('/your/ajax/endpoint.php', {
data: {
'adid': 'your id'
/*
If this is in your PHP file, you can echo the ID straight there.
Not totally recommended, but that's one way An additional /
better way is to add it to a div with a data attribute and
use jQuery to select the data off of there
*/
}
}); // Probably lots more you can do here, but in this case, for simplicity, just sending and that's it
}, 2000); // This will do a 2 second wait
</script>
Your new additional PHP file that is at /your/ajax/endpoint.php
<?php
// THIS FILE DOES THE UPDATE
$adid = $_POST['adid'];
// As mentioned by tadman in his comment.. I would use prepared statements
$query1 = "UPDATE ads SET views = views+1, costs = costs+price WHERE id = ?";
try {
$dbh = new PDO($dsn, $user, $password);
$sth = $dbh->prepare($query1);
$sth->execute(array($adid));
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
NOTE:
Again, for security's sake, you really want to consider having your first PHP script generate a unique ID (and store it in the db), that is passed to the page, and having the AJAX send that unique ID with the adid, and if the unique ID you gave is in the database only THEN would you know it's a legitimate request. Remove the unique ID from the database and do the update.
If you want to wait for some seconds after a page is opened and then run the update statement , then write the following codes on the top of the page:-
echo "<script> setTimeout(function(){}, 2000) ; </script>" ;
$query1 = mysqli_query($con, "UPDATE ads SET views = views+1, costs = costs+price WHERE id = '".$adid."'");

How to secure PHP/JQuery/Ajax calls?

I'm new to Ajax and PHP in general. So far, I managed to make an Ajax call to my PHP script which fetches data from my database. However, upon testing, I realized that, even if I'm not logged in, I can still access and run the PHP script directly and when that happens, it populates all the data from my table, which I don't want to happen.
Now based on that I see a major security issue where anyone can access and run the script and see user information.
Now I'm not familiar with security and stuff in PHP, kinda new to it. My question is how would I go about to make the script unaccessible directly, or only when the admin is logged in it could be accessible?
I read around that I could check the session, I tried but it didn't work for some reason. So I'll put what I coded below.
Here's the PHP which fetches data, getData.php:
<?php
session_start();
if(isset($_SESSION['id']) && isset($_SESSION['name']) && isset($_SESSION['admin']) && ($_SESSION['admin']==1)){
include_once('config.php');
//Create PDO Object
$con = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
//Set Error Handling for PDO
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
//Query
$sql = "SELECT users.name, users.email, users.admin, stores.admin, stores.name FROM users INNER JOIN stores ON users.id=stores.admin";
//Prepare Statement
$stmt = $con->prepare($sql);
$stmt->execute();
while ($row = $stmt->fetch()){
echo '<tr>';
echo '<td>'.$row[4].'</td>';
echo '<td>'.$row[0].'</td>';
echo '<td>'.$row[1].'</td>';
echo '<td>**********</td>';
if($row[2] == 1){
echo '<td>Yes</td>';
}elseif ($row[2] == 0) {
echo '<td>No</td>';
}
echo '</tr>';
}
$con = null;
}
?>
Here's the ajax that does the call to get the data. It's just a snippet, but it's part of a bigger thing(button on click to be precise), myAjax.js:
$.ajax({ //create an ajax request to getData.php
type: "GET",
url: "includes/getData.php",
dataType: "html", //expect html to be returned
success: function(response){
$("#userInfo > tbody").html("<pre>"+response+"</pre>");
},
error:function (xhr, ajaxOptions, thrownError){
alert(thrownError);
}
});
Finally, this I set the following sessions, when user logs in:
$_SESSION['id']
$_SESSION['name']
$_SESSION['admin']
$_SESSION['admin'] == 1 means the user is an admin. Otherwise it's
not.
Any help is greatly appreciated.
Edit:
Forgot to include what I tried to check the session. I update the PHP.
Thanks
I usually do like this for checking whether the user is loged in or not to display the result or output
use if(!empty($_SESSION['admin'] && $_SESSION['admin']==1 && !empty($_SESSION['name']) && !empty($_SESSION['id']))
using !empty will also check that if the variable is set and has any value or not! using isset shows true even if the value of variable is "null". so It will pass the if conditions argument and show the result.
One More thing:
when you logout you need to unset the session variables using...
<?php
session_destroy();
session_unset();
this technique has worked always with me...thanks

Why does the Jquery in my header prevent my PHP code from working?

I have a series of radio buttons. When I select a button and press submit, I want
two things to happen:
1. checkmarks should appear (done with a Jquery script in the header)
2. a mysql database should update the user's score, which in turn changes the color of the square (done with a PHP script in the body)
The problem is that when the jquery script is present, the checkmarks appear but the database doesn't update. When I remove the jquery script, however, the database successfully updates. They jquery script is preventing the PHP code from running and I'm not sure why
JQUERY SCRIPT:
<script type='text/javascript'>
`$(document).ready(function () {`
$('#questionform').on('submit', function(e) {
e.preventDefault();
$.ajax({
url : $(this).attr('action') || window.location.pathname,
type: "POST",
data: $(this).serialize(),
success: function (data) {
if ($('input[name=functions_question]:checked').val() == 2)
{
$("#correctanswermarkwhengotright").fadeIn('slow');
$(".incorrectanswermark").fadeIn('slow');
// I THINK THIS IS WHERE THE PHP CODE NEEDS TO GO TO FIX THE PROBLEM BUT I DON'T KNOW HOW TO INTEGRATE IT
} else {
$("#correctanswermarkwhengotwrong").fadeIn('slow');
$(".incorrectanswermark").fadeIn('slow');
}
},
});
});
});
</script>
PHP SCRIPT:
<?php
$id = $_SESSION['id'];
$ress = $db->query("SELECT 1 FROM answers WHERE user_id=$id AND question_group='Functions'");
if($ress->num_rows==0){
$db->query("INSERT INTO answers VALUES(NULL, $id, 'Functions', 0)");
}
if(isset($_POST['functions_question'])){
$res = $db->query("SELECT score FROM answers WHERE id=$id AND question_group='Functions'");
$data = $res->fetch_array();
if($_POST['functions_question']==$_SESSION['functions_question']){
if($data['score']<2)$db->query("UPDATE answers SET score = score+1 WHERE id=$id AND question_group='Functions'");
}else{
if($data['score']>-2)$db->query("UPDATE answers SET score = score-1 WHERE id=$id AND question_group='Functions'");
}
}
?>
You can see this code in action here: carouseltest.byethost8.com/onanswersubmittest.php
You can login with the username: mail#test.com and password: test
If someone can explain how to integrate the PHP with the Jquery so that both actions work, I would appreciate it. Thank you!
You're trying to test every logic of your code at once. It's quite complicated. You need to test your code step by step.
1)Try to comment everything inside ajax success handler and see what's happening (fadein and fadout logic).
2) Try to test your ajax handler (the .php file). Comment everything insde this file and echo the $_SESSION['functions_question'] and $_SESSION['id']. If they return values then go to the next step.
3) Uncomment only this chunk of code
$ress = $db->query("SELECT 1 FROM answers WHERE user_id=$id AND question_group='Functions'");
if($ress->num_rows==0){
$db->query("INSERT INTO answers VALUES(NULL, $id, 'Functions', 0)");
}
If it works and returns what you need. And it writes data to your database correctly then go to the next step.
4)Uncomment this code.
if(isset($_POST['functions_question'])){
$res = $db->query("SELECT score FROM answers WHERE id=$id AND question_group='Functions'");
$data = $res->fetch_array();
if($_POST['functions_question']==$_SESSION['functions_question']){
if($data['score']<2)$db->query("UPDATE answers SET score = score+1 WHERE id=$id AND question_group='Functions'");
}
If it returns what you need and update your database table correctly then go to the next step.
5) Uncomment the last chunk of your code
else{
if($data['score']>-2)$db->query("UPDATE answers SET score = score-1 WHERE id=$id AND question_group='Functions'");
}
Test it the same way you tested previous code.
This will help debug your code.

jQuery AJAX add/edit/delete actions can be hacked?

Just wondering about a security issue. Right now I'm using the following function to delete movies from my database:
function deleteVideo(video_id){
function mycallbackform(v,m,f){
if(v=="yes"){
$.ajax({
type: "POST",
url: "delete.php?action=video",
data: "video_id=" + video_id,
success: function(html){
if(html == "1"){
//$("#result").html(html);
$("#row_"+video_id).fadeOut("slow");
$("#result").show();
$("#result").html("<div class='notification success png_bg'> <div><?php echo $LANG_video_succesfull_delete; ?> </div></div>");
setTimeout(function(){ $('#result').fadeOut('slow'); }, 5000);
}else{
$("#result").show();
$("#result").html(html);
}
}
});
}
}
$.prompt('Are you sure?',{ buttons: { Ok: 'yes', Cancel: 'no'}, callback: mycallbackform});
}
At the back end the following code is executed:
/*** DELETE data ***/
/*** prepare the SQL statement ***/
$stmt = $dbh->prepare("DELETE FROM videos WHERE username=:username AND videos_id=:video_id");
$stmt->bindParam(':username', $currUser);
$stmt->bindParam(':video_id', $video_id);
/*** execute the prepared statement ***/
$stmt->execute();
The username is stored in a session in this case.
Is there any way user A will be able to delete user B data with this code?
I was thinkinig to add a query to check if the current user is the same user who added the video in the database. If not he can't delete the data. But is this necessary or is this code safe enough?
Thanks in advance.
You'd better store a unique user id in the session. What if there are two people with the same username?
Edit: If the username is unique, it is quite safe. It is not possible to change the value of a session variable working the client side, unless you've made a terrible mistake in your PHP code. But if you're sure the session variable is always set correctly, you don't have to worry.

Categories