PHP - Subtracting a number from mysql table values - php

This may seem like a bit of an odd request, but it's important that I get this working. It's for a game i'm making. So basically, my users have their own accounts on my website. I have different plans that they can select and each plan costs a different amount every month.
What I want to do is have 4 seperate PHP crons that automatically subtract a certain amount from their accounts each month based on the plan they have selected. For example, if a user has the "Ultimate" plan, and currently has $1,049.99 in their account, I want it to subtract 49.99 from the "balance" row in the database, and then update the table to 1000.00 (as it has subtracted the plan amount).
At registration, the database is loaded with the value "chargeday" which is basically the day of the month that the user registered. I want the cron to run every day (which I know how to do) and only run this code if the current day equals the chargeday listed on the database. (I've been running this code with the if ($chargeday == date("d")) { and } lines removed.
I've tried the following but I can't get it to work the way I want:
<?php
$servername = "localhost";
$username = "myusername";
$password = "mypassword";
$dbname = "advenaio_myaccount";
$chargeday = date("d");
if ($chargeday == date("d")) {
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT email, plan, balance FROM advaccounts WHERE plan='ultimate'";
$result = $conn->query($sql);
$ultimateplan = "49.99";
$currentbalance = $row['balance'];
$newbalance = $currentbalance-$ultimateplan;
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "plan: " . $row["plan"]. "<br>balance: " . $row['balance'] . "<br>new balance: " . $newbalance . "<br>email address: " . $row['email'] . "<br><br> ";
}
} else {
echo "0 results";
}
$sql = "UPDATE advaccounts SET balance=$newbalance WHERE plan='ultimate'";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . $conn->error;
}
$conn->close();
?>
I'm sorry if my question doesn't make sense, I just really need this to work and I'm sort of desperate for it to work. Here is the structure of the database:
id_user | name | email | domain | username | password | plan | balance | joindate | chargeday | substatus | cic

you can use below sql to update the balance directly using one sql. No need to write php logic.
$sql = "UPDATE advaccounts SET balance=balance-49.99 WHERE plan='ultimate' and chargeday = '" . date('d'). "'";

Related

How do you display one row in in a html table using php at random?

Im setting up a website for my home work and I need to display 1 row at random from an sql table in a html table using php. For example, my website is called random data where the website will generate random data for you (except all it is actually doing is displaying data already inserted into a database). So, does anyone know the code required to display 1 row of data from an sql table and display it in a html table using php in each cell of the table to retrieve the data from the database? Here is what I have so far (it works when I don't try to select just one row at random, but when I select all of them, it does work. Pleas Help! :)
<?php
$username = "root";
$password = "root";
$dbname = "fakedeets";
$conn = new mysqli("localhost", $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT FLOOR(RAND()*(10-5+1)+5);";
$result = $conn->query($sql);
if($row = $result-> fetch_assoc()) {
echo "<tr><td>". $row["firstname"].
"</td><td>". $row["lastname"].
"</td><td>". $row["dob"].
"</td><td>". $row["gender"].
"</td><td>". $row["emailaddress"].
"</td><td>". $row["phonenumber"].
"</td><td>". $row["photo"].
"</td></tr>";
echo "</table>";
} else {
echo "0 results";
}
$conn->close();
?>
What I expect to appear is just 1 row of data displayed on a html doc selected at random from an sql database. Instead it just outputs nothin
You can just use SELECT {your columns} FROM {table} ORDER BY RAND() LIMIT 1
This selects the columns from the table you need, orders it randomly and then limits the set to just one entry. Replace the 1 with number of rows you need.

PHP+MySQL script not working

I made this script which is giving me a lot of troubles. I'm not so good at MySQL and maybe I'm trying to do stuff too advanced for my knowledge of SQL, but I would really really really like to make this work.
My php script is:
<?PHP
$getusername=$_GET['user'];
$getpassword=$_GET['pass'];
$getworldname=$_GET['worldname'];
$getblock=$_GET['block'];
$getpos=$_GET['pos'];
$user_name = "asdasdasd";
$password = "asdasd";
$database = "asdasd";
$server = "localhost";
$db_handle = mysql_connect($server, $user_name, $password);
$db_found = mysql_select_db($database, $db_handle);
$SQL="SELECT * FROM accounts WHERE username='$getusername' and password='$getpassword'";
$result=mysql_query($SQL);
$count=mysql_num_rows($result);
if($count==1){
$blockstring=$getpos.'/'.$getblock.'|';
$SQL="SELECT LOCATE('$getpos', blocks) FROM worlds WHERE name='$getworldname'";
$result=mysql_query($SQL);
$count=mysql_num_rows($result);
echo $count;
//if there's already that block
if ($result!=0){
$posUnknown='|'.$getpos.'/';
$posKnown='|'.$getpos.'/'.$getblock;
$SQL="UPDATE worlds SET blocks=replace(blocks,concat('$posUnknown',substring_index(substring_index(blocks, '$posUnknown', 2), '|', 1),'|'),'$posKnown') WHERE name='$getworldname'";
$result=mysql_query($SQL);
}else{
$SQL="UPDATE worlds SET blocks=CONCAT(blocks,'$blockstring') WHERE name='$getworldname'";
$result=mysql_query($SQL);
}
print 'OK';
}else{
print 'NO';
}
?>
I'm sure I made some mistake, also big ones into the queries, but sadly I can't figure out what I'm doing wrong.
An example of the content of blocks could be:
x10y20z30/0|x999y1231z30/1|x3330y4444z0/99999|etc
What this script does, well, what I wanted it to do is:
Check username and password, and that works luckily,
check if the given block already exists in "blocks"
if it does exist replace the value (the one after the /) of the
already existing block with the new one,
if it doesn't exist just add it to "blocks".
But it doesn't work and I know why. I know it's because of the SQL, but I can't figure out how to make it work.
You have some serious issues with your code's security, as pointed out in a comment. I have done what I can without really changing what your code is doing:
<?PHP
$getusername=$_GET['user'];
$getpassword=$_GET['pass'];
$getworldname=$_GET['worldname'];
$getblock=$_GET['block'];
$getpos=$_GET['pos'];
$user_name = "asdasdasd";
$password = "asdasd";
$database = "asdasd";
$server = "localhost";
You should be using mysqli, not mysql:
$db = new mysqli($server, $user_name, $password, $database);
All input needs to be escaped before it is used in a query with real_escape_string:
$SQL="SELECT * FROM accounts WHERE username='" . $db->real_escape_string($getusername) . "' and password='" . $db->real_escape_string($getpassword) . "'";
$result=$db->query($SQL);
$count=$result->num_rows;
if($count==1) {
$blockstring=$getpos.'/'.$getblock.'|';
$SQL="SELECT LOCATE('" . $db->real_escape_string($getpos) . "', blocks) FROM worlds WHERE name='" . $db->real_escape_string($getworldname) . "'";
$result=$db->query($SQL);
$count=$result->num_rows;
echo $count;
//if there's already that block
if ($count!=0) {
$posUnknown='|'.$getpos.'/';
$posKnown='|'.$getpos.'/'.$getblock;
This is probably where you're having trouble, because it looks like you're storing all of this information in a single row:
$SQL="UPDATE worlds SET blocks=replace(blocks,concat('" . $db->real_escape_string($posUnknown) ."',substring_index(substring_index(blocks, '" . $db->real_escape_string($posUnknown). "', 2), '|', 1),'|'),'" . $db->real_escape_string($posKnown) . "') WHERE name='" . $db->real_escape_string($getworldname). "'";
$result=$db->query($SQL);
} else {
$SQL="UPDATE worlds SET blocks=CONCAT(blocks,'" . $db->real_escape_string($blockstring) ."') WHERE name='" . $db->real_escape_string($getworldname) . "'";
$result=$db->query($SQL);
}
print 'OK';
} else {
print 'NO';
}
?>
Since all of your block information is being shoved together in a single column, your database is not normalized at all and appears to be like this:
Worlds
name blocks
Your database should probably be structured a lot more like this:
Worlds
id | name
---------------
1 | demoworld
Blocks
id | WorldID | x | y | z | data
-----------------------------------------
1 | 1 | 10 | 20 | 30 | 0
2 | 1 | 999 | 1231 | 30 | 1
3 | 1 | 33330 | 4444 | 0 | 99999
You can recreate the data layout you provided when you query the data, and when someone tries to add something like x20y30z40/12345, you can parse that to get the x, y, z, and data portions.

Can't get score to update with this mysql statement

I'm guessing that I'm just a little rusty or something because it seems like this should be working. Am I missing something here...
Here is the code I am trying to use...
<?php
echo dbConn();
$existing_time = mysql_result(mysql_query("SELECT p_time FROM scores WHERE p_uid=$uid"), 0);
$existing_category = mysql_result(mysql_query("SELECT p_cat FROM scores WHERE p_uid=$uid AND p_cat=$pieces"), 0);
if ($existing_category == "") {
mysql_query(
"INSERT INTO scores VALUES (
'',
'$uid',
'$pusername',
'$time',
'$pieces'
)");
} elseif ($existing_time <= $time) {
echo "No Change! Old Score Was Better (Lower)";
} elseif ($existing_time > $time) {
mysql_query("UPDATE scores SET p_time = " . $time . " WHERE p_uid = " . $uid . " AND p_cat = " . $pieces . "");
};
?>
Now... Here is what I am trying to do...
I am collecting info from the database where the users username AND category match. If the category for that user does not exist, it inserts the latest score. (This much works.)
Then, if the category does exist but the old score is better, it just does nothing. (This part works too)...
However, what I can't seem to do is get it to update the last score, if the current score is better (lower score, since this is a time based game.) It doesn't update the score.
I am trying it this way: By updating a row in "scores" where the USERNAME and the CATEGORY match at the same time.
Please note... where it says "pieces". this is a category. Where it says "time", this is a score. The score is returned as 00:00:00 for hours minutes and seconds.
EXAMPLE: (in parentheses is the database row name)
id (ID) = just KEY id in sequencial order
user id (p_uid) = 123456789
username (p_username) = somename
score (p_time) = 00:01:03
category (p_cat) = 10
Change you update statement to:
mysql_query("UPDATE scores SET p_time = '" . $time . "' WHERE p_uid = " . $uid . " AND p_cat = " . $pieces . "");
You have missed quotes in the update statement around $time.

Log File With Changes Made to MySQL DB

I would like to create a .txt log file that records changes made to a database. Basically whenever someone adds a record, I want the log to record something like "On 2013-10-03 12:21:43 Smith, Joe added the following appointment: ...some appointment details..."
I have a functions.php file that has the following function (oh, and bear with me for the moment on mysql vs mysqli - that update is in the works, but hasn't happened yet):
function getCalendarChange($id) {
require("db.php"); //database connection
$sql = "SELECT calendar_event.consultant_id, calendar_event.client_id, calendar_event.event_id, calendar_event.billing_id, calendar_event.dates_id, consultant.f_name, consultant.l_name, client.client_name, event_type.event_type, billing_status.billing_type, dates.date FROM calendar_event
INNER JOIN consultant ON calendar_event.consultant_id = consultant.consultant_id
INNER JOIN client ON calendar_event.client_id = client.client_id
INNER JOIN event_type ON calendar_event.event_id = event_type.event_id
INNER JOIN billing_status ON calendar_event.billing_id = billing_status.billing_id
INNER JOIN dates ON calendar_event.dates_id = dates.date_id
WHERE calendar_event_id = '$id'";
$result = mysql_query($sql,$connection) or die (mysql_error());
$results = mysql_fetch_array($result);
$consultant = $results['l_name'] . ", " . $results['f_name'];
$client = $results['client_name'];
$event = $results['event_type'];
$billing = $results['billing_type'];
$eventdate = $results['date'];
echo $consultant . " " . $client . " " . $event . " " . $billing . " " . $eventdate;
}
In the page that processes the form to INSERT a new record, I have the following:
include("functions.php");
$add_appt_query = "INSERT INTO calendar_event (calendar_event_id, consultant_id, client_id, event_id, billing_id, dates_id) VALUES (NULL, '$addee', '$addclient', '$addevent', '$addbilling', '$dt')";
$add_appt_result = mysql_query($add_appt_query,$connection) or die(mysql_error());
$chngid = mysql_insert_id(); //gets the last auto increment id - yes this is set to be an auto increment column
$new_appointment = "<p>Appointments added successfully.</p>"; //everything works up to here - the appointment is added to the db as expected
// start log new appointment
$log_data = "On " . $log_datetime . " " . $ee_log_name . " added the following appointment: "; //$log_datetime and $ee_log_name are defined elsewhere, but work correctly
$log_data .= getCalendarChange($chngid) . "\n";
$log_data .= file_get_contents('mod.txt');
file_put_contents('mod.txt', $log_data); //done this way so the newest change is at the beginning of the file not the end
// end log new appointment
What ends up in mod.txt is something like "On 2013-10-03 12:21:43 Smith, Joe added the following appointment: " it adds everything I want except for the data from getCalendarChange().
I have tried to remove getCalendarChange and just echo $chngid, which produces the id# as you might expect.
I have called the getCalendarChange function with a static number getCalendarChange(100) from within the functions.php file, which displays the correct information for that particular event.
I have replaced $chngid in getCalendarChange($chngid) to getCalendarChange(100), and it still doesn't work. (yes there is a record with id 100).
Why doesn't getCalendarChange($chngid) work outside of the functions.php file?

MYSQL/PHP outputting entire table when I only want to output one row

This is definitely a beginner's question. There are two issues. The id in my MYSQL table (set to autoincrement) keeps going up, even though I delete rows from my table (I'm using phpmyadmin). As for the other issue, I can't seem to find a way to work with the row most recently entered by the user. The code echos all existing rows from MYSQL.
I've bolded the most pertinent section of code.
<?php
//establish connection to mysql
$con = mysql_connect("localhost","root","");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
/*retrieve user input from input form
and initialize variables */
$Word1 = $_POST["Word1"];
$Word2 = $_POST["Word2"];
$Word3 = $_POST["Word3"];
$Word4 = $_POST["Word4"];
$Word5 = $_POST["Word5"];
//select db
mysql_select_db("madlibs", $con);
//insert user input for word 1
$sql = "INSERT INTO test (Word1, Word2, Word3, Word4, Word5)
VALUES
('$Word1', '$Word2', '$Word3', '$Word4', '$Word5')";
if(!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
$result = mysql_query ("SELECT * FROM test");
/* take note here */
while($row = mysql_fetch_array($result))
{
echo $row['Word1'] . " " . $row['Word2'] . " " . $row['Word3'] . " " .
$row['Word4'] . " " . $row['Word5'] . " " . $row['id'];
echo "<br />";
} /* take note here */
mysql_close($con);
?>
$result = mysql_query ("SELECT * FROM test order by id desc limit 1");
As for your id question...that's how ids work. They don't fill in gaps.
On a side note: Never ever put user submitted data directly into the query string. Always escape them with mysql_real_escape_string().
SELECT * FROM test ORDER BY Id DESC LIMIT 1

Categories