I have problem connected with function returning array from sql query. The problem is that I want to return category as string and amount as float. I think the best solution is to set in while loop to write that i want category as string and amount as float. But I don't know which function can I use to make this ?
I was thinking to write something like this in while loop
while (($row = $stmt->fetch(PDO::FETCH_ASSOC)))
{
$data[] = [(string)$row['Category'],(float)$row['Amount']];
}
But there is no result, that I expected.
public static function getPieChartIncomes()
{
if (empty(Income::$this->errors)) {
$sql = "SELECT income_category_assigned_to_user_id as Category, SUM(amount) as Amount FROM incomes WHERE user_id = :userId GROUP BY income_category_assigned_to_user_id ORDER BY SUM(amount) DESC ";
$db = static::getDB();
$stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $_SESSION['user_id'], PDO::PARAM_INT);
$stmt->execute();
$data=array();
while (($row = $stmt->fetch(PDO::FETCH_ASSOC)))
{
$data[] = $row;
}
return $data;
}
return false;
}
public static function convertDataToChartForm($data)
{
$newData = array();
$firstLine = true;
foreach ($data as $dataRow)
{
if ($firstLine)
{
$newData[] = array_keys($dataRow);
$firstLine = false;
}
$newData[] = array_values($dataRow);
}
return $newData;
}
Finally I wanted to achieve Array for google charts like this one:
$chartIncomesArray = Income::convertDataToChartForm($incomesArray);
json_encode($chartIncomesArray) =
['Category']['Amount']
['wynagrodzenie'][12.00]
['odsetki'][50.00]
etc.
Can anybody help me with this ?
I solved my problem, deleting convertDataToChartForm($data) and changing getPieChartIncomes function to this:
public static function getPieChartIncomes()
{
if (empty(Income::$this->errors)) {
$sql = "SELECT income_category_assigned_to_user_id as Category, SUM(amount) as Amount FROM incomes WHERE user_id = :userId GROUP BY income_category_assigned_to_user_id ORDER BY SUM(amount) DESC ";
$db = static::getDB();
$stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $_SESSION['user_id'], PDO::PARAM_INT);
$i = 1;
$stmt->execute();
$tablica = array();
while (($row = $stmt->fetch(PDO::FETCH_ASSOC)))
{
$firstLine = true;
if ($firstLine)
{
$tablica[0] = array_keys($row);
$firstLine = false;
}
$category = $row['Category'];
$amount = $row['Amount'];
$tablica[$i]=array(strval($category),floatval($amount));
$i++;
}
return $tablica;
}
Thanks to while loop like now i can get table, where array keys are strings and another rows are : category as string and amount as int like this
['Category']['Amount']
['wynagrodzenie'][12.00]
['odsetki'][50.00]
Related
I am changing mysqli connections to prepared statements, I always come across this issue, when I am putting values in an array, I'm wondering if someone could explain why I do this incorrectly every time. When I print the returned array from the function it only shows me the last stored values in the array, as opposed to every row in the array.
function getResults($db) {
$statement = $db->prepare("SELECT inv_id, serial_num, equip_id, equip_title, equip_cat, input_date, date_modified FROM equip_inv");
$statement->execute();
$statement->store_result();
$num_of_rows = $statement->num_rows;
$statement->bind_result($invId, $serial, $equipId, $equipTitle, $equipCat, $inputDate, $dateMod);
while ($statement->fetch()) {
$resultArray = array();
$resultArray['inv_id'] = $invId;
$resultArray['serial_num'] = $serial;
$resultArray['equip_id'] = $equipId;
$resultArray['equip_title'] = $equipTitle;
$resultArray['equip_cat'] = $equipCat;
$resultArray['input_date'] = $inputDate;
$resultArray['date_modified'] = $dateMod;
}
return $resultArray;
}
You're reseting $resultArray in each loop. You can create a new array $results = array(); and push $resultArray to it in each loop. Try :
function getResults($db){
$statement = $db->prepare("SELECT inv_id, serial_num, equip_id, equip_title, equip_cat, input_date, date_modified FROM equip_inv");
$statement->execute();
$statement->store_result();
$num_of_rows = $statement->num_rows;
$statement->bind_result($invId, $serial, $equipId, $equipTitle, $equipCat, $inputDate, $dateMod);
$results = array();
while ($statement->fetch()){
$resultArray = array();
$resultArray['inv_id'] = $invId;
$resultArray['serial_num'] = $serial;
$resultArray['equip_id'] = $equipId;
$resultArray['equip_title'] = $equipTitle;
$resultArray['equip_cat'] = $equipCat;
$resultArray['input_date'] = $inputDate;
$resultArray['date_modified'] = $dateMod;
$results[] = $resultArray;
}
return $results;
}
I have a getData() function, and a database with two tables: employers and members.
I would like to pass a variable containing the table name, so inside an "if" I could execute the appropriate SELECT statement. My problem I believe that after the "if" the $stmt->bind_param(); doesn't know which $stmt to bind the take.
Any ideas on how I could achieve this?
Thanks
public function getData($table)
{
if ($table == "employers")
{
$stmt = $this->link->prepare("SELECT * FROM employers ");
}
else
{
$stmt = $this->link->prepare("SELECT * FROM members ");
}
$stmt->bind_param();
if ($stmt->execute())
{
$result = $stmt->get_result();
while($row = $result->fetch_array(MYSQLI_ASSOC))
{
$row = array_map('stripslashes', $row);
$dataArray[] = $row;
}
}
return $dataArray;
}
No, since you aren't binding anything, that ->bind_param method is superfluous. Just take that off.
public function getData($table)
{
$dataArray = array();
$t = ($table === 'employers') ? 'employers' : 'members';
$query = "SELECT * FROM $t";
$stmt = $this->link->prepare($query);
if($stmt->execute()) {
$result = $stmt->get_result();
while($row = $result->fetch_assoc()) {
$row = array_map('stripslashes', $row);
$dataArray[] = $row;
}
}
return $dataArray;
}
Sample Usage:
$data = $aministrator_query->getData('members');
$tbody = '';
foreach($data as $row) {
$tbody .= "<tr><td>{$row['user_id']}</td><td>{$row['user_password']}</td><td>{$row['user_first_name']}</td><td>{$row['user_last_name']}</td></tr>";
}
$table = sprintf('<table><thead><tr><th>ID</th><th>Password</th><th>First Name</th><th>Last Name</th></tr></thead><tbody>%s</tbody></table>', $tbody);
echo $table;
I'm currently trying to fetch two images location from my database, how do I return both columns and if both empty then echo another image. This is what I've got so far.
How do I return both photo and photo_small so that I may echo them in a php file.
PUBLIC FUNCTION Profile_Pic($uiD) {
$sth = $this->db->prepare("SELECT photo,photo_small FROM users WHERE uiD = :id");
$sth->execute(array(':id' => $uiD));
if ($sth->rowCount() > 0) {
$data = $row['photo'];
return $data;
} else {
$data = './icons/users.png';
return $data;
}
}
PUBLIC FUNCTION Profile_Pic($uiD) {
$sql = "SELECT photo,photo_small FROM users WHERE uiD = ?";
$sth = $this->db->prepare($sql);
$sth->execute(array($uiD));
$data = $sth->fetch();
if (empty($data['photo'])) {
$data['photo'] = './icons/users.png';
}
if (empty($data['photo_small'])) {
$data['photo_small'] = './icons/users.png';
}
return $data;
}
if you want to replace both images if even one is absent
PUBLIC FUNCTION Profile_Pic($uiD) {
$sql = "SELECT photo,photo_small FROM users WHERE uiD = ?";
$sth = $this->db->prepare($sql);
$sth->execute(array($uiD));
$data = $sth->fetch();
if (empty($data['photo']) || empty($data['photo_small'])) {
$data['photo'] = './icons/users.png';
$data['photo_small'] = './icons/users.png';
}
return $data;
}
Just return all of the values you want in an array.
You can ensure that both photo and photo_small are not empty strings or NULL by using empty().
Don't forget to retrieve your row using PDOStatement::fetch().
You should not use rowCount() to determine the number of rows returned in a SELECT statement. According to the documentation for PDOStatement::rowCount():
For most databases, PDOStatement::rowCount() does not return the number of rows affected by a SELECT statement.
Try this:
$row = $sth->fetch(PDO::FETCH_ASSOC);
if ($row && !empty($row['photo']) && !empty($row['photo_small'])) {
$data = array('photo' => $row['photo'], 'photo_small' => $row['photo_small']);
return $data;
} else {
$data = array('photo' => './icons/users.png', 'photo_small' => './icons/users.png');
return $data;
}
Then when you call the function, your returned result can be used like this:
$uiD = 1;
$result = Profile_Pic($uiD);
$photo = $result['photo'];
$photo_small = $result['photo_small'];
So I have this function that takes all the users from an MySql table and stores them in an array:
public function graphVals() {
$sql = "SELECT user_username FROM users WHERE user_register_date > CURDATE() - 2592000";
if ($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->bind_result($username);
while ($row = $stmt->fetch()) {
$stmt->bind_result($username);
$data[] = $username;
}
$stmt->close();
foreach($data as $key) {
$length[] = sizeof($key);
}
print_r($data);
} else {
$error = true;
$message['error'] = true;
$message['message'] = CANNOT_PREPARE_DATABASE_CONNECTION_MESSAGE;
return json_encode($message);
}
}
After that, as you can see I want to return an array which contains the length of the usernames array.
But my question is, as you can see I'm fetching an array with all usernames, each one at one index, what I actually want to do is take all users registered on one date and store them in a single index, all users registered on the date after the previous one and store them in the next index, etc.
How would I do that ? Can I adjust this function to do that ?
This is easy to do :
public function graphVals() {
$sql = "SELECT user_username FROM users WHERE user_register_date > CURDATE() - 2592000 ORDER BY user_register_date ASC";
$data = array();
if ($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->bind_result($username);
$stmt->bind_result($date);
while ($row = $stmt->fetch()) {
$stmt->bind_result($username);
if (!isset($data[$date])) {
// when the date is the first time in the array. Add that date as index for the array
$data[$date] = array();
}
$data[$date][] = $username;
}
$stmt->close();
foreach($data as $key) {
$length[] = sizeof($key);
}
print_r($data);
} else {
$error = true;
$message['error'] = true;
$message['message'] = CANNOT_PREPARE_DATABASE_CONNECTION_MESSAGE;
return json_encode($message);
}
}
Hope this helps :)
Start by adding an ORDER BY to your query. This isn't mandatory but will simplify things for you
SELECT user_username FROM users
WHERE user_register_date > CURDATE() - 2592000
ORDER BY user_register_date
Then check the date in your loop iteration, like so:
while ($row = $stmt->fetch()) {
$stmt->bind_result($username);
$stmt->bind_result($date);
if (!isset($data[$date])) {
// first time we encounter this date, creating a new array for it
$data[$date] = array();
}
$data[$date][] = $username;
}
So this is what I came up with after seeing your example code. Now I get it by date, as date the index, the only thing is that I had before NOW() instead of CURDATE() when registering, and I get the hour, min and sec too. But I think this is the solution. Let me know what you think, if I should do anything else.
$sql = "SELECT user_username, user_register_date FROM users WHERE user_register_date > CURDATE() - 2592000 ORDER BY user_register_date";
if ($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->bind_result($username,$date);
while ($row = $stmt->fetch()) {
$stmt->bind_result($username, $date);
if (!isset($data[$date])) {
$data[$date] = array();
}
$data[$date][] = $username;
}
$stmt->close();
foreach($data as $key) {
$length[] = sizeof($key);
}
print_r($data);
} else {
$error = true;
$message['error'] = true;
$message['message'] = CANNOT_PREPARE_DATABASE_CONNECTION_MESSAGE;
return json_encode($message);
}
I want to return a set of values from function till the point they exist....
for example....
function abc($i="3"){
for($a=1;$a<=$i;$a++) {
$name='t'.$i;
$$name = "ae".$a;
}
//now i am returning values
return array($t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9,$t10);
//but i only want to return $t1,$t2,$t3 depending on $i
}
Thanks....
#therefromhere
I am also creating an array in the loop , I'll paste the original code so that you can understand it in a better way
function extracting_comments($table, $fields,$condition,$order,$limit){
$query="SELECT ".$fields."
FROM ".$table."
WHERE ".$condition."
ORDER BY ".$order."
LIMIT ".$limit." ";
if($stmt = $this->conn->prepare($query)) {
$stmt->execute();
$row = array_pad(array(), $stmt->field_count, '');
$params = array();
foreach($row as $k=>$v) {
$params[] = &$row[$k];
echo $params[0];
}
call_user_func_array(array($stmt,'bind_result'),$params);
$i=0;
while($stmt->fetch()) {
$i++;
$name='t'.$i;
$$name = array();
foreach ($row as $b=>$elem) {
$atul[$b]=$row[$b];
}
$$name=$atul;
}
return array($t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9,$t10);
$stmt->close();
}
}
now their are only 5 rows of data so their is no point returning $t6,$t7,$t8,$t9,$t10
and i want to fix it ,and i am calling the function using
$extract=extracting_comments($table, $fields,$condition,$order,$limit);
please help...thanks
Just build the array in your for loop:
function abc($i=3) {
$array = array();
for ($a=1; $a<=$i; $a++) {
$array[] = "ae".$a;
}
return $array;
}
After you edited your question an revealed us your actual problem, see here my proposal:
function extracting_comments($table, $fields, $condition, $order, $limit) {
$retVal = array();
$query = "SELECT ".$fields."
FROM ".$table."
WHERE ".$condition."
ORDER BY ".$order."
LIMIT ".$limit." ";
if ($stmt = $this->conn->prepare($query)) {
$stmt->execute();
$row = array_pad(array(), $stmt->field_count, '');
call_user_func_array(array($stmt, 'bind_result'), $row);
while ($stmt->fetch()) {
$retVal[] = $row;
}
$stmt->close();
return $retVal;
}
}
I believe this will help you. You have very complicated code with a lot of side effects and bug, you'd better to consider to redisgn it. Also putting statements after return will no have any effect, since it wouldn't be invoked.
function extracting_comments($table, $fields,$condition,$order,$limit){
$query="SELECT ".$fields."
FROM ".$table."
WHERE ".$condition."
ORDER BY ".$order."
LIMIT ".$limit." ";
if($stmt = $this->conn->prepare($query)) {
$stmt->execute();
$row = array_pad(array(), $stmt->field_count, '');
$params = array();
foreach($row as $k=>$v) {
$params[] = &$row[$k];
echo $params[0];
}
call_user_func_array(array($stmt,'bind_result'),$params);
$i=0;
$result = array();
while($stmt->fetch()) {
$i++;
foreach ($row as $b=>$elem) {
$atul[$b]=$row[$b];
}
$result[]=$atul;
}
$stmt->close();
return $result;
}
}
It'd be cleaner to build the array as you go along, then you wouldn't need the temporary variables:
function abc($i="3") {
$myArray = array();
for($a=1;$a<=$i;$a++) {
$myArray[] = "ae" . $a; // add new values to the end of the array
}
return $myArray;
}
If you want to check if the variables exist (and are not null), use isset().