what is wrong with this loop? - php

$result = mysql_query($query);
$filter = array();
while($r = mysql_fetch_array($result))
{
for ( $i = 0; $i<20; $i++)
{
$filter[] = $r["name"][$i];
}
$name = implode(",", $filter);
}
Above is a portion of main code. I want to restrict loop to run only 20 times. if above 20 it should omit...but this gives me some odd result...I know some where I made a mistake but where?

mysql_fetch_array only fetches a single row of data from the query results. It looks like you're trying to fetch only a single field from the results, so you'd want something like this:
$i = 0;
while($row = $mysql_fetch_assoc($result)) {
$i++
if ($i >= 20) {
break;
}
$filter[] = $row['name'];
}
$name = implode(",", $filter);
But this is very inefficient. Why not have MySQL do the row-limiting itself?
SELECT your,fields,here
FROM yourtable
WHERE ...
ORDER BY ...
LIMIT 20
and then you only get 20 rows to start with, without forcing mysql to fetch all however-many-there-are-beyond-20.

You are not advancing to the next row
$result = mysql_query($query);
$filter = array();
$i = 0;
while($r = mysql_fetch_array($result))
{
$filter[] = $r["name"][$i]; }
$name = implode(",", $filter);
if(++$i == 20)
{
break;
}
}

Related

Bad Gateway issue with PHP API

Hey I made an API in PHP from my MySQL database, It is rather CPU intensive and is being called multiple times a second.
$timer = $candle_time * 60;
$DATABASE_HOST = '';
$DATABASE_USER = '';
$DATABASE_PASS = '';
$DATABASE_NAME = '';
$response = array();
$link = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
$query = "SELECT * FROM table WHERE name LIKE 'name' ORDER BY table.datetime ASC";
$result = mysqli_query($link, $query);
while ($row = mysqli_fetch_row($result)) {
$dates .= $row[1]. ',';
$price .= $row[2]. ",";
$datetime .= $row[3]. ',';
}
$dates = explode(",",$dates);
$price = explode(",",$price);
$datetime = explode(",",$datetime);
for($i = 0; $i < count($dates); $i++){
array_push($response,array(strtotime($datetime[$i]),$dates[$i],$price[$i]));
}
$counting_segments = 0;
$grouped_prices = array();
$final_grouping = array();
$rounded = ceil($response[0][0]/$timer)*$timer;
$counted = count($response)-1;
for($i = 0; $i < count($response); $i++){
if($i == $counted){
$rounded = ceil($previous_time/$timer)*$timer;
array_push($final_grouping,array($rounded,$grouped_prices));
}
if($response[$i][0] > $rounded){
$previous_time = $response[$i][0];
array_push($final_grouping,array($rounded,$grouped_prices));
$grouped_prices = array();
$rounded = ceil($response[$i][0]/$timer)*$timer;
}
if($response[$i][0] < $rounded){
$previous_time = $response[$i][0];
array_push($grouped_prices,$response[$i][2]);
} else {
array_push($grouped_prices,$response[$i][2]);
}
}
$new_array = array();
for($i = 0; $i < count($final_grouping); $i++){
$first_array = $final_grouping[$i][0];
$second_array = $final_grouping[$i][1];
$first_price = $second_array[0];
$last_price = end($second_array);
$high_price = max($second_array);
$low_price = min($second_array);
$final_date = $first_array;
$obj = new StdClass;
$obj->time = $final_date;
$obj->open = $first_price;
$obj->high = $high_price;
$obj->low = $low_price;
$obj->close = $last_price;
array_push($new_array,$obj);
}
$json_api = json_encode($new_array);
echo $json_api
I think the reason for the 503 is the CPU power it is taking to calculate the requests. Is there a way I can have a script or something that pulls the data and saves it to a php file every second to lessen the load or is there a better way of doing this?
I did run this personally and it works perfectly, however with more people requesting from it it provides a 503 often.
Thanks.
The PHP code itself doesn't look like it should overload the CPU. However, there are a lot of things you can do to optimize it
How's the query performing. Execute the query directly and see if you need to add an index. This could be an index on 2 fields: name and datetime.
You're using specific columns date, price, and datetime, but you're getting all rows in the response. It's better to specify the columns you want
SELECT `date`, `price`, `datetime` FROM table WHERE name LIKE 'name' ORDER BY table.datetime ASC
You're building up comma-separated strings and then splitting them right after. That's unnecessary. Instead build-up arrays.
while ($row = mysqli_fetch_row($result)) {
$dates[] = $row[1];
$price[] = $row[2];
$datetime[] = $row[3];
}
In this case, you don't even need separate arrays, but can just build-up $response in the fetch loop.
while ($row = mysqli_fetch_row($result)) {
$response[] = array(strtotime($row[1]), $row[2], $row[3]);
}
P.S. Don't use array_push() unless you care about the inserted index. The $array[] = $value syntax is faster.
Just count once, not every iteration in the loop
$counted = count($response);
for($i = 0; $i < $counted; $i++){
if($i == $counted - 1){

Running mysql query in loop for each entry in array

I am no programmer and could really use some help in configuring a query below such that it will run for each element in an array and finally add the queried data to the 'mArray'.
Below is two examples of the queries I am running. I have many more of these so it would be much more practical to include all of the ID's in an array and run a foreach loop based on the number of array elements.
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'List1'");
$list1Array = array();
while($r = mysqli_fetch_array($sth)) {
For ($n = 1; $n <= $CI_NOYEARS; $n++){
$list1Array['data'][] = $r[$n];
}
}
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'List2'");
$list2Array = array();
while($r = mysqli_fetch_assoc($sth)) {
For ($n = 1; $n <= $CI_NOYEARS; $n++){
$list2Array['data'][] = $r[$n];
}
}
$mArray = array();
$mArray['list1'] = $list1Array;
$mArray['list2'] = $list2Array;
I have been trying to create this using a simple array and foreach statement as below. However, I just can't seem to make this work. Any help is much appreciated.
$idArray = array(
"List1",
"List2",
);
foreach($idArray as $val) {
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = $val");
$yearsArray = array(); // Not sure what to do here
while($r = mysqli_fetch_array($sth)) {
For ($n = 1; $n <= $CI_NOYEARS; $n++){
$yearsArray['data'][] = $r[$n]; // Again not sure what to do here
}
}
}

Using curly brackets in multidimensional array

I have an array of ID's used to execute mysqli queries in a foreach loop (the below code is just an example - the array will contain more than 50+ elements/ID's). For each array element/ID I query an array which I then include in a compData array. However, I am unsure of how to dynamically define the arrays in the foreach loop. I would very much appreciate if you can check whether I am using ${$val} correctly in the below or if something else is wrong. Thanks.
$idArray = array(
"List1",
"List2",
);
$compData = array();
foreach($idArray as $val) {
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = {$val}");
${$val} = array();
while($r = mysqli_fetch_array($sth)) {
For ($n = 1; $n <= $CI_NOYEARS; $n++){
${$val}['data'][] = $r[$n];
}
}
$compData[{$val}] = ${$val}
}
foreach($compData['List1'] as $result) {
For ($n = 0; $n <= $CI_NOYEARS; $n++){
echo $result[$n];
}
}
The above code does not work and does not echo any data from the $compData array. Below is an example that works just fine where I execute the code using the ID's directly.
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'List1'");
$List1 = array();
while($r = mysqli_fetch_array($sth)) {
For ($n = 1; $n <= $CI_NOYEARS; $n++){
$List1['data'][] = $r[$n];
}
}
$companyData = array();
$companyData['List1'] = $List1;
foreach($compData['List1'] as $result) {
For ($n = 0; $n <= $CI_NOYEARS; $n++){
echo $result[$n];
}
}
It's a bit tough figuring out what your goal is based on the code you provided, but it seems far more complicated than it needs to be. I think what I've got here will replicate your desired output.
You should also be using prepared statements; they are safer, and take a lot of the overhead out of database queries when you're going to be repeating the same query multiple times. I've implemented them here.
$idArray = ["List1", "List2"];
$sth = $conn->prepare("SELECT * FROM `$tableName` WHERE ID = ?");
foreach($idArray as $val) {
$data = [];
$sth->bind_param("s", $val);
$sth->execute();
$result = $sth->get_result();
while ($r = $result->fetch_array()) {
$data = array_merge($data, array_splice($r, 1, $CI_NOYEARS));
}
$compData[$val]["data"] = $data;
}
foreach($compData["List1"]["data"] as $result) {
echo $result;
}
I don't understand why you're using that curly-brace notation at all when you're just copying it over into a multidimensional compData array anyway? Why not just directly put the data into the array:
for ($n = 1; $n <= $CI_NOYEARS; $n++) {
$compdata[$val]['data'][] = $r[$n];
}
(You'll also need to declare it as an array at the top level of the foreach of course.)
Side note: I would suggest not interpolating data directly into your query string like that, and instead using bound parameters: http://php.net/manual/en/mysqli-stmt.bind-param.php It's much more secure.

combining values from mysql seperated by comma using explode

I have two columns in my mysql table pro_id and pro_page. Each column contains integer values separated by comma.
example,
pro_id pro_page
-------- ------------
1,2,3 1,1,1
2 1
3,4 2,1
I want to combine first integer value from pro_id and first integer value from pro_page, second integer value from pro_id and second integer value from pro_page and so on.
For example,
from first row, result should be 11 21 31
from second row, result should be 21
from third row, result should be 32 41
I have tried using the below code,
$query = "SELECT pro_id, pro_page from tbl_checkout";
$result = mysqli_query($c,$query)or die(mysqli_error($c));
$length = mysqli_num_rows($result);
while($row = mysqli_fetch_array($result1))
{
$pro_id[] = $row["pro_id"];
$pro_page[] = $row['pro_page'];
}
for($i=0; $i<$length1; $i++)
{
$pro_id = explode(",", #$pro_id[$i]);
$pro_page = explode(",", #$pro_page[$i]);
foreach($pro_id as $product_id) {
$product_id = $product_id;
echo $product_id;
}
foreach($pro_page as $product_page) {
echo $product_page;
}
}
Now the result is,
from first row, 123111
from second row, 21
from third row, 3421
Is there any way to achieve what i want. I have tried a lot.
After fetching the array from database do the following:
$output = array();
while($row = mysqli_fetch_array($result1))
{
$pro_id = explode(',' , $row["pro_id"]);
$pro_page = explode(',' , $row['pro_page']);
for($i = 0; $i< count($pro_id); $i++)
{
$output[$i] = $pro_id[$i] . $pro_page[$i];
}
return $output;
}
You can do it via single foreach if you numbers amount is same in both arrays
$products = explode(",", #$pro_id[$i]);
$pages = explode(",", #$pro_page[$i]);
foreach( $products as $k => $product_id){
$product_page = $pages[$k];
echo $product_id . $product_page . " ";
}
Try below code:
$query = "SELECT pro_id, pro_page from tbl_checkout";
$result = mysqli_query($c,$query)or die(mysqli_error($c));
$length = mysqli_num_rows($result);
while($row = mysqli_fetch_array($result1))
{
$pro_id[] = $row["pro_id"];
$pro_page[] = $row['pro_page'];
}
for($i=0; $i<$length1; $i++){
$pro_id = explode(",", #$pro_id[$i]);
$pro_page = explode(",", #$pro_page[$i]);
$newProduct_id = '';
foreach($pro_id AS $keyIndex => $product_id) {
$newProduct_id = $pro_id[$keyIndex] . $pro_page[$keyIndex] . " ";
echo $newProduct_id;
}
}
You have to loop over both arrays at once. Easiest when using for():
$query = "SELECT pro_id, pro_page from tbl_checkout";
$result = mysqli_query($c,$query)or die(mysqli_error($c));
$length = mysqli_num_rows($result);
while($row = mysqli_fetch_array($result1))
{
$pro_id[] = $row["pro_id"];
$pro_page[] = $row['pro_page'];
}
for($i=0; $i<$length1; $i++)
{
// don't assign to $pro_id and $pro_page as variable name: it will mess up your data!
$tmp_id = explode(",", $pro_id[$i]);
$tmp_page = explode(",", $pro_page[$i]);
for($c=0; $c < count($tmp_id)) {
echo $tmp_id[$c];
echo $tmp_page[$c];
}
}
Another problerm is that you use $pro_id and $pro_page for two different purposes. You use it for storage of db results and to store the exploded numbers from this data. Use different variable names.

array_merge() How can I add a 'range' of an array name

I have a $nr variable that as the number of arrays with the same name that i created in a previous function, something like this:
$var = 'sorteios_'.$nr;
$$var = array($sorteio_id);
I have it in a While function so it was created something like 3 arrays with the names:
$sorteios_1 , $sorteios_2 , $sorteios_3
And i want to add them inside an array_merge, so i have to use the $nr that says how many arrays with the same name were created.
$nr = 3;
i want that the final result looks something like this.
$result = array_merge($sorteios_1, $sorteios_2, $sorteios_3);
That's the whole function if you want to check it (it's not complete because of the problem i'm having):
function check_sorteios(){
global $db;
$id = $_SESSION['userid'];
$query1 = "SELECT * FROM sorteios WHERE userid = $id";
$result1 = $db->query($query1);
$count = $result1->rowCount();
if ($count == 0){ $sorteios = 0; echo "sem sorteios";}
else{
$numero = 0;
$sorteios = 0;
$nr = 0;
while($row1 = $result1->fetch()){
if ( $numero == $count ){ return 0;}
$numero++;
$sorteio_id = $row1['id'];
$query2 = "SELECT * FROM productos WHERE id = $sorteio_id";
$result2 = $db->query($query2);
while($row2 = $result2->fetch()){
$data = $row2['data'];
$titulo = $row2['titulo'];
if (strtotime($data) > time()){
if(!isset($$sorteio_id)){
$$sorteio_id = 1;
}
$nr++;
$var = 'sorteios_'.$nr;
$$var = array($sorteio_id);
}
}
}
}
$result = array_merge($sorteios_1, $sorteios_2, $sorteios_3);
$occurences = array_count_values($result);
print_r($occurences);
}
You could try to create a string containing the code executing array_merge of all your arrays and then pass it to the eval function (http://it1.php.net/manual/it/function.eval.php)...
Something like this:
$str="\$result=array_merge(";
for($i=1;$i<=$nr;$i++){
$str.="\$sorteios_$i,";
}
$str=substr($str,0,-1);
$str.=");";
eval($str);
Then in $result you have what you need.
Is there a reason you can't recursively merge?
if ($nr > 0) {
$result = $sorteios_1;
for ($i = 2; $i <= $nr; ++$i) {
$result = array_merge($result, ${'sorteios_'.$i});
}
} else {
// you might want to handle this case differently
$result = array();
}

Categories