Using curly brackets in multidimensional array - php

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.

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
}
}
}

Setting up array key/value pairs and accessing

I have set up an array called $compData by importing data from MySql and pushing two separate arrays called $yearsArray and $salesArray into $compData. Before pushing these two arrays to $compData I have first set their ['name'] to 'Year' and 'Sales', respectively. The code for this is included below.
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'ID_YEAR'");
$yearsArray = array();
$yearsArray['name'] = 'Year';
while($r = mysqli_fetch_array($sth)) {
For ($n = 1; $n <= $CI_YEARS; $n++){
$yearsArray['data'][] = $r["Year$n"];
}
}
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'IS_SALES'");
$salesArray = array();
$salesArray['name'] = 'Sales';
while($rr = mysqli_fetch_assoc($sth)) {
For ($n = 1; $n <= $CI_YEARS; $n++){
$salesArray['data'][] = $rr["Year$n"];
}
}
$compData = array();
array_push($compData,$yearsArray); // 0
array_push($compData,$salesArray); // 1
Now I want to access and echo the data in $compData by using the code below, but this doesn't work. I am not very comfortable with PHP and am wondering if I am not using the ['Year'] and ['Sales'] identifiers correctly. Any help is much appreciated.
foreach($compData['Year'] as $result) {
echo $result, '<br>';
}
foreach($compData['Sales'] as $result) {
echo $result, '<br>';
}
You've set 'Year' as the value of key 'name', but try to use it as key (of another array).
Now you have
echo $compData[0]['name']; // -> 'Year'
echo $compData[1]['name']; // -> 'Sales'
You probably want
$compData = array();
$compData['Year'] = $yearsArray;
$compData['Sales'] = $salesArray;
instead of the array_push..

unable to return a value as an array after retriving from mysql using php

I am trying to get a single value or all the values from the table in mysql using php, it works for single value and it is not the case for all the values, please help me.
function displaySitetype() {
$result = array();
$result = site_type_find("all");
print_r($result);
$count = count($result);
for ($iter = 0; $iter < $count; $iter++) {
?> <option value="<?php echo $iter; ?>"><?php echo $result[$iter]; ?></option> <?php }
}
function site_type_find($site_type) {
if ($site_type == "all") {
$result = mysql_query("select * from site_type_table");
$count = count($result);
while ($count) {
$resultarr = mysql_fetch_assoc($result);
$arr = array_push($arr, $resultarr['site_name']);
$count--;
} return $arr;
} else {
$result = mysql_query("select site_name from site_type_table where site_id=$site_type");
$arr = mysql_fetch_array($result);
return $arr[0];
}
}
Minimal fix: try the following (I suppose that you want only values for column site_name)
//...
if ($site_type == "all") {
$result = mysql_query("select site_name from site_type_table");
$arr = array();
while ($resultarr = mysql_fetch_assoc($result)) {
$arr[] = $resultarr['site_name'];
}
return $arr;
} else {
//...
BTW, I would not recommend use of mysql_* functions (deprecated in PHP 5.5+)
Note that you cannot call count() directly on your variable $result (which is a reference to a MySQL query results). To get results count in your situation, you can use mysql_num_rows() (check carefully the red warning box at the beginning on the man page)

what is wrong with this loop?

$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;
}
}

Categories