SQL/PHP Database Connection to Client Side Display - php

I've been starting to program in PHP, and I want to create a program that allows any visitor to click a button and have it increment a universal counter. Eg, a user clicks the button, the counter increments by 1, and you can refresh the page and that new number will have "stuck".
My thought was to use a database that would hold the current number of "clicks" and display it, then use a client-side JavaScript button to increment the database's value. I am able to access my database and get the current number of clicks held there statically, but I'm at a loss as to having the counter be interactional. I've tried googling around to see how to do this in JavaScript, and the results have been minimal. Are my goals even achievable in JavaScript? Or should I use a different language to connect my server-side ops with my client-side ones?
// connects to the database using hostname, user, pass, db name
$connect = mysqli_connect('HOSTNAME','USER','PASSWORD','epiz_33276135_ducks');
if (!$connect) {
echo 'problem connecting to database';
}
//takes the query
$query = "SELECT Count,ID,AnimalName FROM ducks WHERE ID=1";
//connects result adn records it
$result = mysqli_query( $connect, $query);
$record = mysqli_fetch_assoc( $result);
if (!$result) {
echo 'smthin weird';
}
echo '<h2>'.$record['Count'].'</h2>';
From my understanding, PHP is for server-side operations, and Javascript is for client-side work. Googling hasn't generated any answers, and I haven't been able to find a way that can edit hte

Typically, you'd have your client-side code make a request to a PHP script that increments the count and responds with the new value. You can either use a form which results in a full page load or use an asynchronous request for a more seamless experience.
On the front-end, you'd use something like this
<button id="increment-counter" type="button">Increment Counter</button>
// Add a "click" event listener to the button
document
.getElementById("increment-counter")
.addEventListener("click", async () => {
// Make a PUT request to your PHP
// The `method` probably isn't important but a GET request seemed wrong
const res = await fetch("increment-counter.php", { method: "PUT" });
// Check for any errors
if (!res.ok) {
throw new Error(
`Increment counter failed: ${res.statusText} - ${await res.text()}`
);
}
// now update the current count in-place
document.querySelector("h2").textContent = (await res.json()).Count;
});
On the server-side, something like this (and I'm using PDO because it's more beginner-friendly than MySQLi)
// increment-counter.php
if ($_SERVER['REQUEST_METHOD'] !== 'PUT') {
// Only allow PUT requests
http_response_code(405);
exit;
}
// Connect to your DB
$pdo = new \PDO(
'mysql:host=HOSTNAME;dbname=epiz_33276135_ducks',
'USER',
'PASSWORD',
[
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
     \PDO::ATTR_EMULATE_PREPARES   => false,
]
);
$pdo->beginTransaction(); // atomic updates are important
try {
// Select the current Count
$count = $pdo
->query('SELECT `Count` FROM ducks WHERE ID = 1 FOR UPDATE')
->fetchColumn();
// Update your Count column
$pdo->exec('UPDATE ducks SET `Count` = `Count` + 1 WHERE ID = 1');
$pdo->commit();
// Respond with a JSON object containing the updated count
header('content-type: application/json');
echo json_encode(['Count' => $count + 1]);
exit;
} catch ($err) {
$pdo->rollBack();
throw $err;
}

Learn one language at a time. PHP in this context writes HTML so you simply need to implement a page transition - i.e. fetch new html from the server....
<?php
$connect = mysqli_connect('HOSTNAME','USER','PASSWORD','epiz_33276135_ducks');
if (!$connect) {
echo 'problem connecting to database';
}
//takes the query
$query = "SELECT Count,ID,AnimalName FROM ducks WHERE ID=1";
//connects result adn records it
$result = mysqli_query( $connect, $query);
$record = mysqli_fetch_assoc( $result);
if ($result) {
$query="UPDATE ducks SET `Count`=`Count`+1";
mysqli_query( $connect, $query);
} else {
echo 'smthin weird: ' mysqli_error($result);
}
echo "<h2>$record[Count]</h2>";
echo "<a href='$_SERVER[REQUEST_URI]'>next</a>";
Once you've got this working, have a look at HTML forms.
BTW its bad practice to use reserved words (Count) for attribute names.

Related

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."'");

PHP login script using bind_result in subsequent query mysqli

I'm trying to build a relatively simple PHP login script to connect to MySQL database running on my home server. I know the connection works as I've gotten some data returned as I would expect. However, I am having trouble getting the full script to work.
Essentially, I'm taking in a username/password from the user, and I first do a lookup to get the user_id from the users table. I then want to use that user_id value to do a comparison from user_pswd table (i'm storing usernames and passwords in separate database tables). At one point, I was able to echo the correct user_id based on the username input. But I haven't been able to get all the issues worked out, as I'm pretty new to PHP and don't really know where to see errors since I load this onto my server from a remote desktop. Can anyone offer some advice/corrections to my code?
The end result is I want to send the user to another page, but the echo "test" is just to see if I can get this much working. Thanks so much for the help!
<?php
ob_start();
$con = new mysqli("localhost","username","password","database");
// check connection
if (mysqli_connect_errno()) {
trigger_error('Database connection failed: ' . $con->connect_error, E_USER_ERROR);
}
$users_name = $_POST['user'];
$users_pass = $_POST['pass'];
$user_esc = $con->real_escape_string($users_name);
$pass_esc = $con->real_escape_string($users_pass);
$query1 = "SELECT user_id FROM users WHERE username = ?;";
if ($result1 = $con->prepare($query1)) {
$result1->bind_param("s",$user_esc);
$result1->execute();
$result1->bind_result($userid);
$result1->fetch();
$query2 = "SELECT user_pswd_id FROM user_pswd WHERE active = 1 AND user_id = ? AND user_pswd = ?;";
if ($result2 = $con->prepare($query2)) {
$result2->bind_param("is",$userid,$pass_esc);
$result2->execute();
$result2->bind_result($userpswd);
$result2->fetch();
echo "test", $userpswd;
$result2->free_result();
$result2->close();
} else {
echo "failed password";
}
$result1->free_result();
$result1->close();
}
$con->close();
ob_end_clean();
?>

Data Management Issue - How to manage retrieved data from mysql?

I am developing a game(c#) with database(mysql) and web service(php) to retrieving the data. The issue is the data management. There is a table on database with the name of items and it has some columns like id, item_name, item_description, item_prop, update_date, ownerId. I added 70 items to this table manually. The users can also add some items to this table or they can update the items they have already added in the game. My purpose is retrieving the whole affected rows of the table when the user is first logged in and save it as a json file in the game folder. After, read that file to fill the game environment with those items.
I try a way to achieve this. Firstly, i hold an updateDate variable in the game which is past like "1990-05-10 21:15:43". Second, i send this variable to the webservice as '$lastUpdateDate'; and make a query according to that variable at the database. select * from channels where update_date >= '$lastUpdateDate'; and write these rows in a json file as items.json. after that make a second query to retrieve the time and refresh the updateDate variable in the game. select select now() as 'Result';. In this way user would not have to get the whole table and write in json file every login process. So, it would be good for the performance and the internet usage. The problem occurs when the users update an item which is already added before. I can see the updated item, too with the first query, but I wrote it in json file twice in this way.
php code part of the getItems of my loginuser.php :
<?php
include './function.php';
// CONNECTIONS =========================================================
$host = "localhost"; //put your host here
$user = "root"; //in general is root
$password = ""; //use your password here
$dbname = "yourDataBaseName"; //your database
$phpHash = "yourHashCode"; // same code in here as in your Unity game
mysql_connect($host, $user, $password) or die("Cant connect into database");
mysql_select_db($dbname)or die("Cant connect into database");
$op = anti_injection_register($_REQUEST["op"]);
$unityHash = anti_injection_register($_REQUEST["myform_hash"]);
if ($unityHash == $phpHash)
{
if($op == "getItems")
{
$lastUpdateDate = anti_injection_login($_POST["updateDate"]);
if(!$lastUpdateDate)
{
echo "Empty";
}
else
{
$q = "select * from items where update_date >= '$lastUpdateDate';";
$rs = mysql_query($q);
if (!$rs)
{
echo "Could not successfully run query ($q) from DB: " . mysql_error();
exit;
}
if (mysql_num_rows($rs) == 0)
{
echo "No rows found, nothing to print so am exiting";
exit;
}
$arr = array();
while ($row = mysql_fetch_row($rs))
{
$arr = $row;
}
echo json_encode($arr);
}
mysql_close();
}
}
?>
So, how can i solve this problem? Or do you have any better idea for this approach. Help would be much appreciated. Thank you for your time.

PHP login system help needed for deletion

Help with user deletion:
Hello I am creating a user creation system for a project of mine, I am still very new to PHP, my issue is getting the user from the MySQL database and then deleting it, I will show you my code below:
<?php
require_once("config/db.php");
if ($login->isUserLoggedIn() == true) {
if ($_SESSION['user_perm'] == 1) {
//Create Connection
$db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
// Check connection
if ($db_connection->connect_error) {
die("Connection failed: " . $db_connection->connect_error);
}
$sql = "SELECT user_name FROM users";
$result = $db_connection->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo $row["user_name"];
$user_name_delete = $row["user_name"];
$_SESSION['user_name_delete'] = $user_name_delete;
echo 'Delete User<br>';
}
}
}
$db_connection->close(); ?>
On the deleteuser.php page my code is, note this was just a test:
<?php
echo $_SESSION['user_name_delete'];
?>
My issue with this is grabbing the user who you selected to delete as at the moment it only outputs the last user grabbed from the database.
Any help is much appreciated.
This value:
$_SESSION['user_name_delete']
Is going to contain only the last user in your data. Because you keep overwriting it in your loop:
$_SESSION['user_name_delete'] = $user_name_delete;
The short answer is... Don't use session state for this. (Really, you shouldn't use session state for much of anything unless you absolutely have to.) The identity of the user to be deleted should be included in the request to delete the user. In this case, you can add it to the link. Something like this:
echo 'Delete User<br>';
(Or whatever you use to identify the user in the data row.)
Then in deleteuser.php you can get that value from:
$_GET['id']
Validate the inputs, validate that the user is authorized to perform the delete, and then use that value in the WHERE clause of your DELETE query.
Get the users id and insert it into a delete query.
$id = $db->real_escape_string($_GET['id']);
$sql = "delete from users where id = " . $id; and then run the query to delete the user from the database.

MySQL/PHP check for duplicate before INSERT

I'm trying to check for an existing entry in MySQL before executing the INSERT statement. If the user enters a name already in the database (field is set to unique) then they should be prompted to re-enter the name.
The problem I'm having is that if the new entry matches a record in any form then the error message displays and no INSERT happens.
For example, if the user enters DUMMY_NEW and there is a record DUMMY_OLD they aren't able to add the record even though DUMMY_NEW does not exist in the table.
I've searched and tried other answers already but can't seem to get this to work.
Code with extraneous bits removed for clarity:
//Create connection to database using mysqli
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db);
//Set variables according to user input on previous form
$Server_Name = $_POST['Server_Name'];
//Check for duplicate server name - if exists inform user else run INSERT ($stmt)
$checkdup = "SELECT * FROM dcr_table WHERE SERVER_NAME = '".$Server_Name."'";
$dupresult = $conn->query($checkdup);
if($dupresult = 1)
{
print "<br>Error! <p></p>";
echo "" . $Server_Name . " already exists in the DCR";
print "<p></p>Please check the Server Name and try again";
}
else {
//Define the INSERT statement
$stmt = "INSERT INTO dcr_master (Server_Name, Description,..., ... , ... )";
//Execute the INSERT statement
$conn->query($stmt);
//Success and return new id
echo "<br><p></p>Record Added!<p></p>";
echo "New id: " . mysqli_insert_id($conn);
//Drop the connection
$conn->close();
};
Edit:
I'm aware of the injection vulnerability. The MySQL account only has SELECT, INSERT and UPDATE rights to the table. The end user must supply the password or submit will fail. This is small app with limited user access at the moment. MySQL escape strings will be implemented after current issue is resolved.
Edit 2:
Using Hobo Sapiens method does work in reporting an existing entry however a new (empty) row is still added to the table. The record ID still auto-increments so what I get is id#300 - record, id#301 - blank, id#302 - record. Is this a result of the IGNORE in the INSERT statement?
Your code creates a race condition if two people attempt to create the same ame at the same time and you're not handling the fallout properly.
If you have set the SERVER_NAME column to UNIQUE then you needn't check for the existence of a server name before you perform your INSERT as MySQL will do that for you. Use INSERT IGNORE ad check the number of affected rows after the query has executed to find out if it worked:
//Create connection to database using mysqli
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db);
//Set variables according to user input on previous form
$Server_Name = $_POST['Server_Name'];
//Define the INSERT statement with IGNORE keyword
$stmt = "INSERT IGNORE INTO dcr_master (Server_Name, Description,..., ... , ... )";
if ($conn->query($stmt) === false) {
die("Database error:".$conn->error);
}
// Check for success
if ($conn->affected_rows == 0) {
print "<br>Error! <p></p>";
echo "" . $Server_Name . " already exists in the DCR";
print "<p></p>Please check the Server Name and try again";
} else {
//Success and return new id
echo "<br><p></p>Record Added!<p></p>";
echo "New id: " . $conn->insert_id;
}
This is an atomic operation so no race condition, and it involves only one call to the database.
I recommend you use either the OOP style or the procedural style for mysqli_*() but don't mix them. Usual warnings about SQL injection apply.
Use mysqli_num_rows
$row_cnt = $dupresult->num_rows;
if ($row_cnt > 0) {
echo "There is a matching record";
}else {
//insert into table
}
This statement:
if($dupresult = 1)
will always return 1. You should first retrieve the first query result (if any), like so:
$row=$dupresult->fetch_array(MYSQLI_NUM);
and then compare the result against NULL:
if(!$row)

Categories