Yii: Using GROUP BY Clause - php

I want to implement GROUP BY clause of SQL using Yii. Here I faced problem of returning only first row instead of all rows.
$connection = Yii::app()->db;
$sql = "SELECT group_name FROM `authitem` GROUP BY group_name";
$command = $connection->createCommand($sql);
$row = $command->queryRow();
print_r($row);
$res = array();
foreach ($row as $key => $val) {
$res[] = array('label' => $key, 'value' => $val);
}
print_r($res);

instead of
$row = $command->queryRow();
try like this,
$row = $command->queryAll();

Related

array_push in PHP seems to get into infinite loop

I am new to PHP. I am trying to read MySQL with this PHP code.
....
$sql = "select * from GameMaster where UserId = '".$_POST["UserId"]."'";
$result = mysqli_query($link, $sql);
$rows = array();
$return = array();
while($row = mysqli_fetch_array($result)) {
$rows['UserId'] = $row['UserId'];
$rows['Nick'] = $row['Nick'];
$rows['Items'] = $row['Items'];
$rows['Skills'] = $row['Skills'];
...
$rows['LastUpdate'] = $row['LastUpdate'];
array_push($return, $rows);
}
header("Content-type:application/json");
echo json_encode($return);
Soon after runnning this code, it gets into infinite loop.
When I deleted the array_push line, it did not go into infinite loop.
So I guess that'd be the problem, but I can't find out why.
Is there something wrong with my code?
The MySQL database is in Amazon lightsail.
Please help me. Thanks in advance for any comments.
if you want to fetch all rows from database, and get data array of specific fields
<?php
$sql = "select * from GameMaster where UserId = '".$_POST["UserId"]."'";
$result = mysqli_query($link, $sql);
$filtered = [];
while($row = mysqli_fetch_all($result)) {
$filtered[] = [
'UserId' => $row['UserId'],
'Nick' => $row['Nick'],
'Items' => $row['Items'],
'Items' => $row['Items'],
'Skills' => $row['Skills'],
'Items' => $row['Items'],
'LastUpdate' => $row['LastUpdate'],
];
}
header("Content-type:application/json");
echo json_encode($filtered);
foreach record of your database information you are entering new data to rows array
while($row = mysqli_fetch_array($result)) {
// Logic of you application here
array_push($return, $row);
}
this pushes fetched row into rows array
how ever if you are not modifying database fetched information. you can fetch information as associative array and simply store it in variable. there will be no need for loop and storing in new array
$sql = "select * from GameMaster where UserId = '".$_POST["UserId"]."'";
$result = mysqli_query($link, $sql);
$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
header("Content-type:application/json");
echo json_encode($rows);

Queries in loop taking too much time to execute

I am trying to update data with Ajax and PHP. The following script updating data, But its taking too much time to run.
PHP
$groupId = $_POST['group_id'];
$Id_array = $_POST['Id'];
$result_array = $_POST['result'];
$data = array();
if(count($_POST['data']) > 0 && !empty ($_POST['data'])){
foreach($_POST['data'] as $key => $array){
$row = array();
$row['team_id'] = intval($array['team_id']);
$row['Note'] = strip_tags(trim(strval($array['Note'])));
$data[$key] = $row;
}
for ($i = 0; $i < count($Id_array); $i++) {
$Id = intval($Id_array[$i]);
$result = strip_tags(trim(strval($result_array[$i])));
$sql1 = $db->prepare("UPDATE teams SET result = :result WHERE id = :id ");
foreach($data as $key => $array){
$sql1 ->execute(array(':result' => $result, ':id' => $Id));
}
$sql2 = $db->prepare("UPDATE teams SET note = :note WHERE team_id = :teamid AND group_id = :group_id");
foreach($data as $key => $array){
$sql2->execute(array(':note' => $array['Note'], ':teamid' => $array['team_id'], ':group_id' => $groupId ));
}
Network Timing
You don't need this loop:
foreach($data as $key => $array){
$sql1 ->execute(array(':result' => $result, ':id' => $Id));
}
It's updating the same ID repeatedly, since $Id doesn't change in the loop. Just do:
$sql1->execute(array(':result' => $result, ':id' => $Id));
once.
You can also get some small improvements by doing:
$sql1 = $db->prepare("UPDATE teams SET result = :result WHERE id = :id ");
$sql2 = $db->prepare("UPDATE teams SET note = :note WHERE team_id = :teamid AND group_id = :group_id");
just once, before any of the loops.
Another problem is that you have this loop:
foreach($data as $key => $array){
$sql2->execute(array(':note' => $array['Note'], ':teamid' => $array['team_id'], ':group_id' => $groupId ));
}
inside the for() loop, but it doesn't use any of the variables that change each time through the loop. So it's re-executing all the same queries for each ID in $Id_array.
Take it out of the loop.
With all these changes, the code now looks like:
$groupId = $_POST['group_id'];
$Id_array = $_POST['Id'];
$result_array = $_POST['result'];
$sql1 = $db->prepare("UPDATE teams SET result = :result WHERE id = :id ");
$sql2 = $db->prepare("UPDATE teams SET note = :note WHERE team_id = :teamid AND group_id = :group_id");
$data = array();
if(count($_POST['data']) > 0 && !empty ($_POST['data'])){
foreach($_POST['data'] as $key => $array){
$row = array();
$row['team_id'] = intval($array['team_id']);
$row['Note'] = strip_tags(trim(strval($array['Note'])));
$data[$key] = $row;
}
foreach ($Id_array as $i => $Id) {
$Id = intval($Id);
$result = strip_tags(trim(strval($result_array[$i])));
$sql1 ->execute(array(':result' => $result, ':id' => $Id));
}
foreach($data as $key => $array){
$sql2->execute(array(':note' => $array['Note'], ':teamid' => $array['team_id'], ':group_id' => $groupId ));
}
}
I would use a transaction instead of auto committing in a loop.
So,
//PDO::beginTransaction ( void )
$dbh->beginTransaction();
foreach () {
$smt->exec();
}
//PDO::commit ( void )
$dbh->commit();
Also, you only need to prepare a statement one time since you're binding your variables in the execute function, so try keeping any prepare statements out of a loop.
This should help with some of the overhead of the query in the loop.

Add new array key inside function

I have an array that is populated by a mysql_fetch_assoc. After the array is populated by the columns I want from the database, I would like to add another key to the array, using values that I obtain earlier in the function. I tried to accomplish this with a foreach loop, but my function is not returning the array. Where have I gone wrong?
//calculates payout
function calculate_payout($id){
$result = mysql_query("SELECT `result` FROM `bets` WHERE `id` = {$id}");
echo mysql_error();
$wager_total = mysql_query("SELECT SUM(`wager_amount`) AS `wager_total` FROM `wagers` WHERE `id` = '{$id}'");
$correct_wager_total = mysql_query("SELECT SUM(`wager_amount`) AS `correct_wager_total` FROM `wagers` WHERE `id` = '{$id}' AND `wager_option` = '{$result}'");
echo mysql_error();
$incorrect_wager_total = $wager_total - $correct_wager_total;
$sql = " SELECT * FROM `wagers` WHERE `id` = '{$id}' AND `wager_option` = '{$result}'";
echo mysql_error();
$data = mysql_query($sql);
$rows = array();
while(($row = mysql_fetch_assoc($data)) !== false){
$rows[] = array(
'bet_id' => $row['bet_id'],
'id' => $row['id'],
'wager_amount' => $row['wager_amount']
);
}
foreach ($rows as $p_row){
$payout = $p_row['wager_amount'] / $incorrect_wager_total;
$payout = $p_row['wager_amount'] + $payout;
$p_row['payout'] = $payout;
}
return $p_row;
}
The problem is that $p_row is a copy of the row in the array, so modifying it in the loop doesn't have any effect on the original array.
You can fix this by using a reference in the foreach:
foreach ($rows as &$p_row)
Or you can just do this as you're creating the $rows array in the while loop:
while ($row = mysql_fetch_assoc($data)) {
$new_row = array(
'bet_id' => $row['id'],
'id' => $row['id'],
'wager_amount' => $row['wager_amount'],
'payout' => $row['wager_amount'] / $incorrect_wager_total + $row['wager_amount']
);
Also, your return statement is wrong, it should be return $rows; to return the whole array; return $p_row will just return the last row of the array.

PHP - how to use array in function?

I get an array of values returned from the following function:
function get_subscribitions($user)
{
$user = mysql_real_escape_string ($user);
$sql = "SELECT 'user_id' FROM `subscribe` WHERE subscriber = '$user'";
$result = mysql_query($sql);
$rows = array();
while ($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
mysql_free_result($result);
return $rows;
I now want to use these values in a new function, where each "user_id" is used to collect text from the database through this function:
function get_text($writer) {
$writer = mysql_real_escape_string ($writer);
$sql = "SELECT * FROM `text` WHERE user_id='$writer' ORDER BY timestamp desc";
$result = mysql_query($sql);
$rows = array();
while ($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
mysql_free_result($result);
return $rows;
However the returned value from the first function is an array, and as I've learnt the hard way, arrays cannot be treated by "mysql_real_escape_string".
How can I make the second function handle the values that I got from the first function?
Any responses appreciated.
Thank you in advance.
Your first mistake is to use mysql_fetch_assoc when only selecting one column. You should use mysql_fetch_row for this. This is likely going to fix your primary problem.
Could look like this:
$subs = get_subscribitions($whateverId);
$texts = get_text($subs);
function get_subscribitions($user)
{
$user = mysql_real_escape_string ($user);
$sql = "SELECT 'user_id' FROM `subscribe` WHERE subscriber = '$user'";
$result = mysql_query($sql);
$rows = array();
while ($row = mysql_fetch_row($result)) {
$user_id = $row['user_id'];
$rows[$user_id] = $user_id;
}
mysql_free_result($result);
return $rows;
}
function get_text($writer) {
$writers = implode(",", $writer);
$sql = "SELECT * FROM `text` WHERE user_id IN ({$writers}) ORDER BY timestamp DESC";
$result = mysql_query($sql);
$rows = array();
while ($row = mysql_fetch_array($result)) {
$rows[] = $row;
}
mysql_free_result($result);
return $rows;
}
This will save you a lot of time, because you can get all data from 'text' in one statement.
The solution is to avoid placing arrays in your $rows array in the first function. Instead of:
while ($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
try:
while ($row = mysql_fetch_assoc($result)) {
$rows[] = $row['user_id'];
}
This will place only the value from column 'user_id' in the $rows array.
In order to use the second function you must iterate over the array returned from the first one. Something like this could work for you:
$user_subscriptions = get_subscribitions($user);
foreach($user_subscriptions as $subscription) {
$texts = get_text($subscription['user_id']);
foreach($texts as $text) {
// do something with the fetched text
}
}
As George Cummins says,
while ($row = mysql_fetch_assoc($result)) {
$rows[] = $row['user_id'];
}
and, to speed up the second function:
function get_text($writer)
{
$sql = "SELECT * FROM `text` WHERE user_id in (".implode(',',$writer).") ORDER BY timestamp desc";
$rows = array();
if ($result = mysql_query($sql))
{
while ($row = mysql_fetch_assoc($result))
{
$rows[] = $row;
}
mysql_free_result($result);
}
return $rows;
}
The change to the query means that you only do one in total rather than one for each ID thus removing the time taken to send the query to the server and get a response multiple times. Also, if the query fails, the function returns an empty array
Use :
string implode ( string $glue , array $pieces )
// example, elements separated by a comma :
$arrayasstring = impode(",", $myarray);
function get_subscribitions($user)
{
$user = mysql_real_escape_string ($user);
$sql = "SELECT 'user_id' FROM `subscribe` WHERE subscriber = '$user'";
$result = mysql_query($sql);
$row = mysql_fetch_row($results);
mysql_free_result($result);
return intval($row['user_id']);
}
it return only the user id you can used it in the 2nd function

PHP PDO can't update records in foreach loop

Script searchs through DB and fix broken links. Search and replace functionality works fine, but when trying to save updated data scripts wrights only first raw. I'm stucked! I can use simple mysql_query commands to update data, but needs PDO...
header('Content-Type: text/html; charset=UTF-8');
error_reporting(E_ALL);
echo "Welcome";
$mysql = new PDO('mysql:host=localhost;dbname=db_name;charset=UTF-8','user','12345');
if (!$mysql) die('Can\'t connect');
$tables = array(
'categories',
'news',
'pages'
);
function getContent($table) {
global $mysql;
$fieldnum = 0;
$fields = array();
$vals = array();
$st = $mysql->query("SHOW FIELDS FROM `{$table}`");
while ($row = $st->fetch(PDO::FETCH_ASSOC)) {
$fields[$fieldnum]=$row["Field"];
$fieldnum++;
}
$totalfields=$fieldnum;
$res = $mysql->query("SELECT * FROM `{$table}`");
$sql = "UPDATE `:table` SET :field = ':val' WHERE `:idf` = :id;";
while ($row = $res->fetch(PDO::FETCH_NUM)) {
for ($j=0; $j<$res->columnCount();$j++) {
$rs = str_replace('index.php/','',$row[$j],$m);
if ($rs && $m>0) {
if ($table == 'categories')
$prim= 'cat_id';
elseif($table == 'news') $prim= 'news_id';
elseif($table == 'pages') $prim= 'page_id';
else $prim= $table.'_id';
$upd = $mysql->prepare($sql);
$update = $upd->execute(array(
':table'=>$table,
':field'=>$fields[$j],
':val'=>$rs,
':idf'=>$prim,
':id'=>$row[0]
));
}
}
}
}
foreach ($tables as $t) {
getContent($t);
}
Need help to fix it!
try to fetch all and then go through array
and you do not need to use prepare every time - just once see Example #2
....
$res = $mysql->query("SELECT * FROM `{$table}`");
$rows = $res->fetchAll(PDO::FETCH_NUM);
$sql = "UPDATE `:table` SET :field = ':val' WHERE `:idf` = :id;";
$upd = $mysql->prepare($sql);
foreach ($rows as $row) {
foreach ($row as $col_name => $value) {
......
prepare outside the loop! you are loosing its value this way, also try $upd->debugDumpParams(); and binding before execution, maybe the values u r binding is not right.

Categories