In my database I have a table of "weeks" and a table of "workouts". I would like to achieve something like the following:
Week 1
workout 1 title
workout 1 content
workout 2 title
workout 2 content
workout 3......
week 2
workout 1 title
workout 1 content
workout 2 title
workout 2 content
workout 3......
week 3.....
I've trying something like:
function get_weekly_content() {
$user_id = $this->session->userdata('id');
$weeks = $this->db->select('week_no')->where('user_id', $user_id)->get('weeks');
if($weeks->num_rows > 0) {
foreach($weeks->result() as $row) {
$week_no = $row->week_no;
$workouts = $this->db->where('user_id', $user_id)->where('week_no', $week_no)->get('workouts');
if($workouts->num_rows > 0) {
foreach($workouts as $workout) {
$workout_data[] = $workout;
}
}
$weekly_data[] = $workout_data;
}
return $weekly_data;
}
}
but maybe I have the wrong idea. I would then also need to display the data.
EDIT my question is, what would be the best way to achieve the above and get and array/object to loop through on a view page?
Thanks
Looping with in a loop is just fine, and your approach is appropirate. However!
Generally speaking you shouldn't run mysql queries inside of loops if there is any way to avoid it because queries are quite slow this will really degrade the performance of your script. Otherwise, the idea is correct. Try to write a query outside of the loops that puts all the relevant user data into a keyed array and then pull the information from the array while you're looping.
You're going to see problems with this line: $weekly_data[] = $workout_data; if $workouts->num_rows > 0... if it's the first loop, it will throw an error because $workout_data won't be set, and if it's subsequent loops then on any week that doesn't have results, it will display the previous week's data. You can fix this by setting/resetting $workout_data at the top of the inner loop:
$workout_data = array();
if($workouts->num_rows > 0) {
foreach($workouts as $workout) {
$workout_data[] = $workout;
}
}
function get_weekly_content() {
$user_id = $this->session->userdata('id');
$weeks = $this->db->select('week_no')->where('user_id', $user_id)->get('weeks');
$weekly_data = array();
if($weeks->num_rows > 0) {
foreach($weeks->result() as $row) {
$workout_data = array();
$week_no = $row->week_no;
$workouts = $this->db->where('user_id', $user_id)->where('week_no', $week_no)->get('workouts');
if($workouts->num_rows > 0) {
foreach($workouts as $workout) {
$workout_data[] = $workout;
}
}
$weekly_data[$week_no] = $workout_data;
}
}
return $weekly_data;
}
Then access the data:
$weekly_data = get_weekly_content();
foreach( $weekly_data as $week_no => $workout_data){
// do something with it.
}
That being said, I agree with #Ben D, you should think about your query and create one that can return all the results at once.
Related
We have a PHP script that loops through many XML / CSV files from different websites. Right now we manage to build a good XML / CSV parser script.
The PHP script we wrote is looping though some BIG XML or CSV files. In these XML or CVS files contains Barcodes from different products.
Right now before the script starts I fill an array with the Product ID + Barcode from the MySQL like this:
function Barcodes_Array() {
$sql = "SELECT ProductId, Barcode FROM Products WHERE (Barcode <> '') ";
$res = mysql_query($sql);
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][] = $rijen;
}
}
Each time we loop through the XML (or CSV) files we have to check if the Barcode exists in the array and return the Product ID.
For searching in the function:
$ProductId = SearchBarcodeProduct($EanNr, 'Barcode');
And yet the function:
function SearchBarcodeProduct($elem, $field)
{
$top = sizeof($GLOBALS['arrBarcodes']) - 1;
$bottom = 0;
$ProductId = 0;
while($bottom <= $top)
{
if($GLOBALS['arrBarcodes'][$bottom][$field] == $elem) {
return $GLOBALS['arrBarcodes'][$bottom]['ProductId'];
}
else {
if (is_array($GLOBALS['arrBarcodes'][$bottom][$field])) {
if (in_multiarray($elem, ($GLOBALS['arrBarcodes'][$bottom][$field]))) {
return $GLOBALS['arrBarcodes'][$bottom]['ProductId'];
}
}
}
$bottom++;
}
return $ProductId;
}
We fill in the array because it took forever each time we ask the MySQL Products Table.
My Question is now:
It still takes a VERY long time each time looping through the array of the barcodes. Is there a faster way for any other solutions maybe a different way then a array?
Can someone help please i am working like weeks on this stupid :) thing!
Why do you need 2 functions?
Try just one
function itemBarcode($id) {
$id = intval($id);
$sql = "SELECT ProductId, Barcode FROM Products WHERE ProductId = $id Barcode <> '') ";
$res = mysql_query($sql);
if ($row = mysql_fetch_assoc($res)) {
return $row['barcode'];
} else {
return 0;
}
}
Update if you need to search by barcode you can create another function:
function itemProduct($barcode) {
$sql = "SELECT ProductId, Barcode FROM Products WHERE Barcode = $barcode ";
$res = mysql_query($sql);
if ($row = mysql_fetch_assoc($res)) {
return $row['ProductId'];
} else {
return 0;
}
}
Sounds like you are missing an index on your Barcode column in your database.. A single row lookup using a presumably unique single indexed column should be blisteringly fast.
CREATE INDEX Barcode_Index ON Products (Barcode)
Then simply:
SELECT ProductId FROM Products WHERE Barcode = *INPUT*
You could also make the index UNIQUE if you NULL the Barcode where they currently = '' if there are more than one of these.
Another option is keying the array you have with the Barcode:
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][$rijen['Barcode']] = $rijen;
}
or even just:
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][$rijen['Barcode']] = $rijen['ProductId'];
}
Then you can do a straight look up:
$ProductId = isset($GLOBALS['arrBarcodes'][$Barcode])
?$GLOBALS['arrBarcodes'][$Barcode]['ProductId']
:0;
or:
$ProductId = isset($GLOBALS['arrBarcodes'][$Barcode])
?$GLOBALS['arrBarcodes'][$Barcode]
:0;
N.B Please read the warnings in the comments about use of $GLOBALS and mysql_query.
If you need it, store the barcodes array in an object or variable instead.
PDO is pretty handy, and I think it can also key your returned array for you on fetch.
I have a table in my database. I want to get ltotal value from leave table, and then count all of ltotal. Here are my query and code I use:
$annual_query = pg_query("select ltotal from leave where lapplicant='adam' and ltype=2");
$annual_result = pg_fetch_array($annual_query);
if (pg_num_rows($annual_query) > 0) {
foreach ($annual_result as $data) {
$total_annual = $total_annual + $data;
}
print($total_annual);
}
There are 3 records in the table leave where lapplicant='adam' and ltype=2.
Each ltotal is 1.
When I tried to runprint($total_annual) the result is 2 (it must be 3).
Then I tried to print_r($annual_result['ltotal']), the results is just 1 (it must be 1,1,1).
Can anyone help me? Thank you.
pg_fetch_array() returns just one row with numeric and associative keys (same value twice when traversed). You should use pg_fetch_all() and traverse or use while loop on consecutive rows.
$total_annual = 0;
$annual_query = pg_query("select ltotal from leave where lapplicant='adam' and ltype=2");
while ($row = pg_fetch_array($annual_query)) {
$total_annual = $total_annual + $row['ltotal'];
}
print($total_annual);
or
$total_annual = 0;
$annual_query = pg_query("select ltotal from leave where lapplicant='adam' and ltype=2");
$annual_result = pg_fetch_all($annual_query);
foreach ($annual_result as $row) {
$total_annual = $total_annual + $row['ltotal'];
}
print($total_annual);
Tamil pointed out the immediate problem. However - why don't you just do this in SQL?
select sum(ltotal)
from leave
where lapplicant='adam' and ltype=2
Hello i'm trying to make a post count function based on the codeigniter framework and what i done so far works great looking by my side. The function is complete and everything works fine.
But i have a question here from some experts to tell me that this is the correct ussage of the function and non of the above will harm my page loading. The function is accesed by jQuery get function on every click on the post.
First i'm checking if there is an ip address and if the ip address date inserted is more then 24 hours if its more i'm deleting the current row and then checking again becuase of the previous select its still remembering the last ip address and inserting again with new datime.
And other question should i make cleanjob every week or similar for all ip addreses ?
Here is my code:
function show_count($post_id){
$ip = $this->input->ip_address();
$this->db->select('ip_address,data');
$this->db->from('post_views');
$this->db->where('ip_address',$ip);
$query = $this->db->get();
foreach ($query->result() as $row){
$ip_address = $row->ip_address;
$data = $row->data;
}
if(isset($ip_address) && time() >= strtotime($data) + 8640){
$this->db->where('ip_address',$ip);
$this->db->delete('post_views');
}
$this->db->select('ip_address');
$this->db->from('post_views');
$this->db->where('ip_address',$ip);
$query = $this->db->get();
foreach ($query->result() as $row){
$ip_address_new = $row->ip_address;
}
if(!isset($ip_address_new) && $ip_address_new == false){
$date = new DateTime('now', new DateTimeZone('Europe/Skopje'));
$this->db->set('views', 'views+ 1', false);
$this->db->where('post_id',$post_id);
$this->db->update('posts');
$data = array(
'ip_address'=>$ip,
'data'=>$date->format("Y-m-d H:i:s")
);
$this->db->insert('post_views',$data);
}
}
Thanks, any suggestions will be appreciate.
Instead of doing lots of queries to increment unique views on your posts, you should use and set cookies and have a fallback method if cookies are not enabled.
$post_id = "???"
if(isset($_COOKIE['read_articles'])) {
//grab the JSON encoded data from the cookie and decode into PHP Array
$read_articles = json_decode($_COOKIE['read_articles'], true);
if(isset($read_articles[$post_id]) AND $read_articles[$post_id] == 1) {
//this post has already been read
} else {
//increment the post view count by 1 using update queries
$read_articles[$post_id] = 1;
//set the cookie again with the new article ID set to 1
setcookie("read_articles",json_encode($read_articles),time()+60*60*24);
}
} else {
//hasn't read an article in 24 hours?
//increment the post view count
$read_articles = Array();
$read_articles[$post_id] = 1;
setcookie("read_articles",json_encode($read_articles),time()+60*60*24);
}
Code is below if I run one value in the array the results are correct if I run more than one value the results are of the price is incorrect its like it has messed around with the values somewhere ?? help appreciated
$dido=array('42204131','22204131');
foreach($dido as $did):
$query = "select * from dispatch,link where lid=dlid and did=$did";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$vanc1=$row['vanc1'];
$vanc2=$row['vanc2'];
$vanc3=$row['vanc3'];
$vanc4=$row['vanc4'];
$vanc5=$row['vanc5'];
$anc1=$row['anc1'];
$anc2=$row['anc2'];
$anc3=$row['anc3'];
$anc4=$row['anc4'];
$anc5=$row['anc5'];
// price anc1
$querypanc1 = "select pprice from products where pid=$anc1";
$resultpanc1 = mysql_query($querypanc1);
while($row = mysql_fetch_array($resultpanc1))
{
$priceanc1=$row[pprice];
$tpriceanc1=$vanc1*$priceanc1;
}
// price anc2
$querypanc2 = "select pprice from products where pid=$anc2";
$resultpanc2 = mysql_query($querypanc2);
while($row = mysql_fetch_array($resultpanc2))
{
$priceanc2=$row[pprice];
$tpriceanc2=$vanc2*$priceanc2;
}
// price anc3
$querypanc3 = "select pprice from products where pid=$anc3";
$resultpanc3 = mysql_query($querypanc3);
while($row = mysql_fetch_array($resultpanc3))
{
$priceanc3=$row[pprice];
$tpriceanc3=$vanc3*$priceanc3;
}
// price anc4
$querypanc4 = "select pprice from products where pid=$anc4";
$resultpanc4 = mysql_query($querypanc4);
while($row = mysql_fetch_array($resultpanc4))
{
$priceanc4=$row[pprice];
$tpriceanc4=$vanc4*$priceanc4;
}
// price anc5
$querypanc5 = "select pprice from products where pid=$anc5";
$resultpanc5 = mysql_query($querypanc5);
while($row = mysql_fetch_array($resultpanc5))
{
$priceanc5=$row[pprice];
$tpriceanc5=$vanc5*$priceanc5;
}
$gtprice=$tpriceanc1+$tpriceanc2+$tpriceanc3+$tpriceanc4+$tpriceanc5;
$qrygt="UPDATE dispatch SET gtprice=$gtprice WHERE did=$did";
$resultgt=#mysql_query($qrygt);
}
endforeach;
1) The only possible issue I could spot in your code, is that when some of your select pprice from products where pid ... queries do not return any data, you retain value of $tpriceancX from previous iteration.
2) Also (out of topic) you can replace your 5 blocks of repeated code with for loop.
$gtprice = 0;
for ($i = 1; $i <= 5; $i++)
{
$querypanc = "select pprice from products where pid=".$row["anc$i"];
$resultpanc = mysql_query($querypanc);
while($pancrow = mysql_fetch_array($resultpanc))
{
$priceanc=$pancrow[pprice];
$tpriceanc=$row["vanc$i"]*$priceanc;
$gtprice += $tpriceanc;
}
}
Your first and biggest problem is the copy-pasta nature of your code. Let's try and break down what you're doing:
Setting up a list of ids
Running a query on those ids
Putting the results into an array
Running a separate query on each of those results
You are also using some very janky syntax. (ie foreach($foo as $bar):).
Break these things down into methods. What is a method? It takes an input and transforms it into an output.
//returns an array of price information
public function getPrices($idArray) { //note the good method and parameter names!
//do stuff
}
Now that we know what we are doing, we can start to fill in the implementation details:
public function getPrices($idArray) {
foreach($idArray as $id) {
//somehow get the gross-scale information
//then put it in a data object
//then call a function to get specific information
}
}
What should that sub-method do? Lets look at your current code snippet:
// price anc1
$querypanc1 = "select pprice from products where pid=$anc1";//sets up sql query
$resultpanc1 = mysql_query($querypanc1); //runs the query
while($row = mysql_fetch_array($resultpanc1)) { //for each result
$priceanc1=$row[pprice]; //gets the price
$tpriceanc1=$vanc1*$priceanc1; //calculates some other price
}
Those last two lines really suggest an object but maybe that's too heavyweight for your purpose. The first two lines are boiler plate you repeat endlessly. Lets write a function!
public function getPrices($name, $pid, $multiplier) {
$sqlQuery = "SELECT pprice FROM products WHERE pid=$pid";
$result = mysql_query($sqlQuery);
$prices = array();
while ($row = mysql_fetch_array($result) {
$key = "price".$name;//$key will be something like 'priceanc1'
$prices[$key] = $row[pprice];
$tkey = "tprice".$name;
$prices[$tkey] = $prices[$key] * $multiplier;
}
}
Now, this function is a bit unclean because it tries to do two things at once (queries the database and then massages the data into a usable array) but I wanted it to resemble what you were doing. With this function written we can go back to our higher level function an call it:
public function getPrices($idArray) {
foreach($idArray as $id) {
$sqlQuery = "SELECT * from dispatch, link WHERE lid=dlid and did=$id";
$prices = array();
while ($row = mysql_fetch_array($result) {
for ($idx = 1; $idx <= 5; $idx++) {
$name = "anc".$idx;
$pid = $row[$name];
$multiplier = $row["vanc".$idx];
$priceArray = getPrices($name, $pid, $multiplier);
$prices = array_merge($prices, $priceArray);
}
}
}
//put a var_dump here to check to see if you're getting good results!
return $prices;//Should be the aggregated prices you've gotten from the db
}
Now, that is what you're attempting to do, but I admit I don't understand how your database is set up or what your variables actually mean. Pressing on! We also note that unnecessary massaging of data falls away.
You can call this like so:
$ids = array();
$ids[] = 42204131;
$ids[] = 22204131;
$prices = getPrices($ids);
var_dump($prices);//shows the result of your work
Now that you have the prices, you can pass them to another function to run the update:
updatePrices($prices);
I'll let you write that part on your own. But remember; break down what you're doing and have repeated elements be handled by the same function. The real lesson to learn here is that programming is really communicating: your code doesn't communicate anything because there is so much repeated noise. Use good variable names. Tighten what you're doing down to functions with single tasks. This way anyone reading your code (including you!) will know what you're trying to do and where you've gone wrong.
How can I get the record values in the database to be sorted like this in an array. Supose I am adding the day no.
array
[0] => array=>'id'=>'26' 'date'=>'26'
[1] => array=>'id'=>'27' 'date'=>'27',
array=>'id'=>'28' 'date'=>'27',
array=>'id'=>'29' 'date'=>'27'
[2] => array=>'id'=>'30' 'date'=>'29'
[3] => array=>'id'=>'31' 'date'=>'31',
array=>'id'=>'32' 'date'=>'31',
array=>'id'=>'33' 'date'=>'31'
Basically, I want to add an array to the same index if the next id contains a record with the same date (day no) of the month. Otherwise add it normally.
Right now, My function is adding the rows of the record without sorting it in the format I want it to be in.
The reason I want it to be in this format is because, I need to run the foreach, and if 1 day contains 2 records, then it will append another <li> into my unordered list.
public function getArticles()
{
$sql = 'CALL getArticles()';
$articles = Array();
if (Model::getConnection()->multi_query($sql)) {
do {
if ($result = Model::getConnection()->store_result()) {
while ($row = $result->fetch_assoc()) {
array_push($articles,$row);
}
$result->free();
}
} while (Model::getConnection()->next_result());
}
return $articles;
}
I don't recognize what some of your code is doing, but I think this is the important part.
while ($row = $result->fetch_assoc()) {
if (!isset($articles[$row['date']])) {
$articles[$row['date']] = array();
}
$articles[$row['date']][] = $row;
}
The only difference will be that your array will be keyed on the date instead of incrementing from zero. If you really want it reindexed, you can do...
array_values($articles);
As savinger pointed out, there is alot of functionality in your code which I don't really know, so I've included comments to indicate whereabouts the process is:
// Start of your loop
// $value is what you're getting from the DB...
$array_search = array_search($value,$main_array);
if($array_search)
{
// If this value already exists, we need to add
// this value in +1 of its current value
$main_array[$array_search][] = $value + 1;
}
else
{
// Make a new array key and add in the value
$main_array[] = $value;
}
// End of your loop