I'm currently attempting to produce a progress bar which shows how much a user has spent in comparison to their maximum allowance.
I have calculated the sum of the user's costs, as given by $sumOfCosts, however, I'm attempting to subtract the $sum of costs from the user's maximum allowance however, the code below doesn't work. Does anyone have any advice?
appQueries.php
<?php
class appQueries {
protected $db = null;
public function __construct($db){
$this->db = $db;
}
public function costsSum($user_id){
$query = "SELECT SUM(value) AS costSum FROM costs";
$pdo = $this->db->prepare($query);
$pdo->bindParam(':user_id', $user_id);
$pdo->execute();
return $pdo->fetch(PDO::FETCH_ASSOC);
}
public function getMaxAmount($userid){
$query = "SELECT maxAmount FROM users WHERE user_id = :userid";
$pdo = $this->db->prepare($query);
$pdo->bindParam(':userid', $userid);
$pdo->execute();
return $pdo->fetch(PDO::FETCH_ASSOC);
}
}
homepage.php
$appQueriesObject = new appQueries($DBH);
$maximumCost = $appQueriesObject->getMaxAmount($_SESSION['userData']['user_id']);
$sumOfCosts = $appQueriesObject->costsSum($_SESSION['userData']['user_id']);
$amountRemaining = array($maximumCost + $sumOfCosts);
echo $maximumCost['user_max_amount'];
echo array_sum($sumOfCosts);
echo $amountRemaining;
Your not referencing your $maximumCost or $sumOfCosts variables correctly. It should be $maximumCost['maxAmount'] and $sumOfCosts['costSum'] respectively.
echo $maximumCost['maxAmount'] - $sumOfCosts['costSum'];
You query for the cost sum is also missing an userId param. Try:
$query = "SELECT SUM(value) AS costSum FROM costs WHERE user_id = :user_id";
Related
I'm making a function that i have to check if a userid is in this table already: if not he has to get into another page yet. But for some reason I get "NULL" back instead of the number of the userID.
my class:
public function countHobbies($userID){
try{
$conn = Db::getConnection();
$statement = $conn->prepare("select * from hobby where userID = '".$userID."'");
$userID = $this->getUserID();
$statement->execute();
$aantal = $statement->fetchAll(PDO::FETCH_ASSOC); //
$aantal->execute();
}
catch(throwable $e){
$error = "Something went wrong";
}
}
and this is on my html page:
$userArray = $_SESSION['user_id'];
$userID = implode(" ", $userArray);
$hobby = new Hobby();
$count = $hobby->countHobbies($userID);
if($count == false){
echo "no";
//header('Location: hobby.php');
}
else{
echo "yes";
}
There are at least two things you need to fix:
Always use parameter binding on the SQL statement. It may not be a security problem in this particular instance, but do get into the habit of using prepared statements. Because otherwise you'll find yourself in situations where you should've but didn't. https://www.php.net/manual/en/security.database.sql-injection.php
The $userID variable must be assigned before it is used.
In the end, it could look like this:
$userID = $this->getUserID();
$statement = $conn->prepare("select * from hobby where userID = ?");
$statement->bind_param("s", $userID);
I want to make a class which will show random data from database and counts how many times it was shown.
The sequence is next.
I take random data from database.
I increase its view count.
I show taken (and increased) data on the page.
My code:
class Translate
private $db ;
private $result ;
private $foreign;
private $translation;
function __construct()
{
$this->db = new PDO('mysql:host=localhost;dbname=translate;charset=utf8', 'root', '');
}
private function increaseView($word)
{
$sql = $this->db->prepare("UPDATE admin_words SET was_shown = was_shown + 1 WHERE in_english= ' " . $word . " ' ");
$sql->execute();
}
public function getNewWord()
{
$this->result = $this->db->query('SELECT * FROM admin_words ORDER BY RAND() LIMIT 1');
$this->result = $this->result->fetchAll();
// next string is not working
$this->increaseView('book');
return $this->result;
}
I use it in next way:
$word = new Translate();
$texts = $word->getNewWord();
The trouble is not with $texts. It work great. But I can not send a parameter to
private function increaseView($word)
{
$sql = $this->db->prepare("UPDATE admin_words SET was_shown = was_shown + 1 WHERE in_english= ' " . $word . " ' ");
$sql->execute();
}
by
// next string is not working
$this->increaseView('book');
The current behavior:
My random data is shown as well but increasing of count is not happening.
Any errors are shown.
But if I use $sql = $this->db->prepare("UPDATE admin_words SET was_shown = was_shown + 1 WHERE in_english= 'book' ");
'book' instead of variable it updates a table.(work well)
What I do wrong?
Firstly you might want to use the prepared statement with bindParam as opposed to embedding variables directly in the sql - though there may be little opportunity for sql injection. The update method increaseView should use the value returned from the select query should it not - perhaps like this?
class Translate{
private $db;
private $result;
private $foreign;
private $translation;
function __construct()
{
$this->db = new PDO('mysql:host=localhost;dbname=translate;charset=utf8', 'root', '');
}
private function increaseView($word)
{
$sql = $this->db->prepare("UPDATE admin_words SET was_shown = was_shown + 1 WHERE in_english=:word");
$sql->bindParam( ':word', $word );
$sql->execute();
}
public function getNewWord()
{
$this->result = $this->db->query('SELECT * FROM admin_words ORDER BY RAND() LIMIT 1');
$this->result = $this->result->fetchAll();
$this->increaseView( $this->result['in_english'] ); /* is this the field / column ?? */
return $this->result;
}
}
$word = new Translate;
$texts = $word->getNewWord();
Why is this not working:
function listOrderComments ($factnr){
global $connection;
//$factnr = 123; //or $factnr = "123"; (Both work)
$query = "SELECT * FROM orderstatus WHERE factuurnummer = '$factnr'";
$result = mysqli_query($connection, $query);
When I echo $factnr I get "123" back.
When I uncommented //$factnr = 123; my function is working.
Looked everywhere for a solution. check the type $factnr is (string).
Well if you're using a variable in your query you're opening yourself up to an injection attack for one.
If you're going to be using that variable I would recommend you use bind_param for your query
Read the PHP manual link below and you will be able to figure out the issue
http://php.net/manual/en/mysqli-stmt.bind-param.php
If you're passing in a variable to your function it should already be set so I don't understand why you're setting it to 123 anyway. So execute the sql statement and bind the parameter following the first example on the PHP docs page.
public function listOrderComments ($factnr)
{
global $connection;
$query = "SELECT * FROM orderstatus WHERE factuurnummer = ?";
$sql->prepare($query);
$sql->bind_param("s", $factnr);
$sql->execute();
$result = $sql->get_result();
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);
foreach ($data as $row) {
print_r($row);
}
}
Then do what you want with the result
You can go with:
$query = "SELECT * FROM orderstatus WHERE factuurnummer = ". $factnr;
Concatenating your code is not good practise. Your best solution is to use PDO statements. It means that your code is easier to look at and this prevents SQL injection from occuring if malice code slipped through your validation.
Here is an example of the code you would use.
<?php
// START ESTABLISHING CONNECTION...
$dsn = 'mysql:host=host_name_here;dbname=db_name_here';
//DB username
$uname = 'username_here';
//DB password
$pass = 'password_here';
try
{
$db = new PDO($dsn, $uname, $pass);
$db->setAttribute(PDO::ERRMODE_SILENT, PDO::ATTR_EMULATE_PREPARES);
error_reporting(0);
} catch (PDOException $ex)
{
echo "Database error:" . $ex->getMessage();
}
// END ESTABLISHING CONNECTION - CONNECTION IS MADE.
$factnr = "123" // or where-ever you get your input from.
$query = "SELECT * FROM orderstatus WHERE factuurnummer = :factnr";
$statement = $db->prepare($query);
// The values you wish to put in.
$statementInputs = array("factnr" => $factnr);
$statement->execute($statementInputs);
//Returns results as an associative array.
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
$statement->closeCursor();
//Shows array of results.
print_r($result);
?>
Use it correctly over "doted" concat. Following will just work fine:
$factnr = 123;
$query = "SELECT * FROM orderstatus WHERE factuurnummer = " . $factnr;
UPDATE:
here is $factnr is passing as argument that supposed to be integer. Safe code way is DO NOT use havvy functions even going over more complicated PDO, but just verify, is this variable integer or not before any operation with it, and return some error code by function if not integer. Here is no danger of code injection into SQL query then.
function listOrderComments ($factnr){
global $connection;
if (!is_int($factnr)) return -1
//$factnr = 123; //or $factnr = "123"; (Both work)
$query = "SELECT * FROM orderstatus WHERE factuurnummer = " . $factnr;
$result = mysqli_query($connection, $query);
I'm using PDO to connect the database and using OOP method in coding
this is how to get the posts and comments
class MyWeb{
public function SelectStatus($user_id){
try{
$DBC = new DBConnector();
$query = "SELECT * FROM users U, posts P where P.user_id_fk=U.user_id and U.user_id=:user_id_fk";
$params = array(":user_id_fk"=>$user_id);
$result = $DBC->SelectArray($query,$params);
if($result){
return $result;
} else throw new Exception("Post not selected!");
}catch(Exception $e){
echo "Caught Exception: ".$e->getMessage();
return null;
}
}
public function SelectComment($post_id){
try{
$DBC = new DBConnector();
$query = "SELECT * FROM comments C, users U WHERE C.user_id_fk = U.user_id and C.post_id_fk = :post_id_fk";
$params = array(":post_id_fk"=>$post_id);
$result = $DBC->SelectArray($query,$params);
if($result){
return $result;
} else throw new Exception("Comment not selected!");
}catch(Exception $e){
echo "Caught Exception: ".$e->getMessage();
return null;
}
}
}
and this how to call the functions and display posts and comments
<?php
$NewStatus = $session->SelectStatus($user_id);
if(!empty($NewStatus)){
foreach($NewStatus as $data){
$username = $data->username;
$post = $data->post;
$post_id = $data->post_id;
echo "".$username." | ".$post."";
$NewComment = $session->SelectComment($post_id);
if(!empty($NewComment)){
foreach($NewComment as $cdata){
echo $cdata->comment;
}
}
}
}
?>
But sadly I always get error -> Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\RIO\RIO\RAI\session_rai\includes\db.php on line 14
So, Any solutions for this case?
Thanks.
Your class structure is wrong.
You don't need DBConnector class
Never create more than one connection to database with same credentials
Most of code in MyWeb class is useless too
So, create a PDO connection, then instantiate MyWeb class and then get your data
class MyWeb{
function __construct($dbc)
{
$this->dbc = $dbc;
}
public function SelectStatus($user_id)
{
$query = "SELECT * FROM users U, posts P
WHERE P.user_id_fk=U.user_id and U.user_id=?";
$stmt = $this->dbc->prepare($query);
$stmt->execute(array($user_id));
return $stmt->fetchAll();
}
public function SelectComment($post_id)
{
$query = "SELECT * FROM comments C, users U
WHERE C.user_id_fk = U.user_id and C.post_id_fk = ?";
$stmt = $this->dbc->prepare($query);
$stmt->execute(array($user_id));
return $stmt->fetchAll();
}
}
same with output
<?php
$pdo = new PDO(... params);
$myweb = new MyWeb($pdo);
$NewStatus = $myweb->SelectStatus($user_id);
foreach($NewStatus as $row)
{
echo $row['username']." | ".$row['post'];
$NewComment = $myweb->SelectComment($post_id);
foreach($NewComment as $cdata){
echo $cdata['comment'];
}
}
OR
if you make selectArray function this way
public function selectArray()
{
$args = func_get_args();
$sql = array_shift($args);
$stmt = $this->pdo->prepare($sql);
$stmt->execute($args);
return $stmt->fetchAll();
}
you can save yourself a line or two:
public function SelectStatus($user_id)
{
$query = "SELECT * FROM users U, posts P
WHERE P.user_id_fk=U.user_id and U.user_id=?";
return $this->dbc->selectArray($query, $user_id);
}
You have a syntax error here
$query = "SELECT * FROM comments C, users U WHERE C.user_id_fk = U.user_id and C.post_id_fk = :post_id_fk";";
While it should be
$query = "SELECT * FROM comments C, users U WHERE C.user_id_fk = U.user_id and C.post_id_fk = :post_id_fk";
I have a php function that interogates a table and gets all the fields in a column if a condition is fulfield. So the function returns a collection of elements.
The problem is that i want this function to return an array that i can parse and display.
The code below:
function get_approved_pictures(){
$con = mysql_connect("localhost","valentinesapp","fBsKAd8RXrfQvBcn");
if (!$con)
{
echo 'eroare de conexiune';
die('Could not connect: ' . mysql_error());
}
mysql_select_db("mynameisbrand_valentineapp", $con);
$all = (mysql_query("SELECT picture FROM users WHERE approved = 1"));
$row=mysql_fetch_assoc($all);
// mysql_close($con);
return $row['picture'];
}
Where am I wrong?
You need to use the loop for traversing all the data fetched by the query:
$pictures=array();
while($row=mysql_fetch_assoc($all))
{
$pictures[]=$row['picture'];
}
return $pictures;
Do it like this
$all = mysql_query("SELECT picture FROM users WHERE approved = 1");
$arr = array(); // Array to hold the datas
while($row = mysql_fetch_array($all)) {
$data = $row['picture'];
array_push($arr,$data);
}
return $arr;
You can now insert it into a function and return the values.
Note : mysql_* functions are being depreciated. Try to avoid them.
For the sake of diversity and to give you some sense of how to use PDO instead of deprecated mysql_*, this is how your function might look like:
function get_approved_pictures(){
$db = new PDO('mysql:host=localhost;dbname=mynameisbrand_valentineapp;charset=UTF-8',
'valentinesapp', 'password');
$query = $db->prepare("SELECT picture FROM users WHERE approved = 1");
$query->execute();
$pictures = $query->fetchAll(PDO::FETCH_ASSOC);
$db = null;
return $pictures;
}
Disclaimer: all error handling intentionally omitted for brevity
For the sake of diversity and to give you some sense of how the things have to be instead of inconvenient and wordy PDO, this is how your function might look like:
function get_approved_pictures(){
global $db;
return $db->getCol("SELECT picture FROM users WHERE approved = 1");
}
Disclaimer: all error handling is up and running but intentionally encapsulated into private methods for invisibility.