error on second foreach loop in php - php

i have an array containing query results to wordpress db:
$query = $wpdb->get_results("SELECT id, user_login, date, data1, data2 FROM table WHERE date >= 'date1' AND date <= 'date2'");
foreach ($query as $a) {
$array[] = array('id'=>$a->id, 'user_login'=>$a->user_login, 'date'=>$a->date, 'data1'=>$a->data1, 'data2'=>$a->data2);
}
next foreach loop to make strings for my needs i'm getting nothing, even
foreach ($array as $c) {
$d = $c->id;
}
echo $d;
returns Null. what am i doing wrong ?

$c is an array not an object.
Try $d = $c["id"];

Wrong
$d = $c->id;
Right
$d = $c["id"];

Related

Counting values in the same level of a multidemensional array

I'm trying to count how many of the same calendar weeks I have inside the same level of a multidimensional array. My start array can be seen on the picture on the left part, my output is composed of an ID [0] and the rest are the dates corresponding to that ID.
On my code I convert these dates to calendar weeks and then try to count them with a foreach loop and then unset the last values if they are identical to the newest ones, so that I only have the final count. My Problem is that as you can see on the last array [1975]->1->1 the count is not right, it is taking in count also the same weeks from the other ID.
Any kind of help is much appreciated!
My code looks like this:
$array= array();
$arrayCount=array();
$j=0;
foreach ($sorted as $value) {
$k=1;
foreach ($value[1] as $match) {
$time = strtotime($match);
$Calendar_Week = date('W',$time);
$Year = date('Y',$time);
if(!array_key_exists($Calendar_Week , $array)){
$i=1;
$array[$Calendar_Week][$j]=$match;
}
$arrayCount[$sorted[$j][0]][1][0]=$sorted[$j][0];
$arrayCount[$sorted[$j][0]][1][$k][]=$i;
$arrayCount[$sorted[$j][0]][1][$k][]=$Calendar_Week;
$arrayCount[$sorted[$j][0]][1][$k][]=$Year;
// Delete previous counts of the same value
if ($arrayCount[$sorted[$j][0]][1][$k-1][1]==$Calendar_Week & $arrayCount[$sorted[$j][0]][1][$k-1][2]==$Year) {
unset($arrayCount[$sorted[$j][0]][1][$k-1]);
}
$i++;
$k++;
}
$j++;
}
dd($sorted, $arrayCount);
You just need to reset the $i and $array inside the foreach loop
$i=1;
$array = array();
Please check this code
$array= array();
$arrayCount=array();
$j=0;
foreach ($sorted as $value) {
$k=1;
$i=1;
$array = array();
foreach ($value[1] as $match) {
$time = strtotime($match);
$Calendar_Week = date('W',$time);
$Year = date('Y',$time);
if(!array_key_exists($Calendar_Week , $array)){
$i=1;
$array[$Calendar_Week][$j]=$match;
}
$arrayCount[$sorted[$j][0]][1][0]=$sorted[$j][0];
$arrayCount[$sorted[$j][0]][1][$k][]=$i;
$arrayCount[$sorted[$j][0]][1][$k][]=$Calendar_Week;
$arrayCount[$sorted[$j][0]][1][$k][]=$Year;
// Delete previous counts of the same value
if ($arrayCount[$sorted[$j][0]][1][$k-1][1]==$Calendar_Week & $arrayCount[$sorted[$j][0]][1][$k-1][2]==$Year) {
unset($arrayCount[$sorted[$j][0]][1][$k-1]);
}
$i++;
$k++;
}
$j++;
}
dd($sorted, $arrayCount);

Group same date and count together

I have done a code to call an array of a value based on each date. My code is below:
$matchs = DiraChatLog::where('status','=','Match')->whereBetween('date_access', [$request->from, $request->to])->get();
$array[] = [];
foreach ($matchs as $key => $match) {
$array[$match->date_access] = $match->status;
}
dd($array);
Using this I try and dd(); I get output like this:
What I'm trying to do now is to first group the same dates together and also I want to then count the total for that dates. how can I do this?
Not sure what you mean with "date". But if you mean the same day it would be this:
$matchs = DiraChatLog::where('status','=','Match')->whereBetween('date_access', [$request->from, $request->to])->get();
$array[] = [];
foreach ($matchs as $key => $match) {
$day = substr($match->date_access, 0, 10);
if(isset($array[$day])){
$array[$day]++;
}else{
$array[$day] = 1;
}
}
dd($array);
$array= array();
$arrayCount=array();
foreach ($matchs as $key => $match) {
$time = strtotime($match->date_access);
$newformat = date('Y-m-d',$time);
if(!array_key_exists($newformat , $array)){
$i=1;
$array[$newformat]=$match->status;
}
//$array[$newformat]=$i; remove this comment if you want the count inside
$arrayCount[$newformat]=$i;
$i++;
}
in the event you want to maintain the "match" value in your array if not just un-comment the code and remover $arrayCount occurrences

Laravel monthly count record

I want to create monthly statistics using Chartjs by Laravel.
$monthly_uploaded_product = DB::table('author_product')
->select(DB::raw('count(id) as total'), DB::raw('MONTH(created_at) as month'))
->groupBy('month')
->get();
the result of query is:
[{"total":1,"month":10},{"total":17,"month":11}]
the output of code should be like this to be represented in Javascript (Chartjs):
[0,0,0,0,0,0,0,0,0,1,17,0]
I have wrote code to generate the array, but error Undefined offset: 1 :
$statistics_monthly_product = array();
foreach (range(1, 12) as $month) {
foreach ($monthly_uploaded_product as $key) {
if ($statistics_monthly_product[$month] == $key->month){
$statistics_monthly_product[$month] = $key->total;
}else{
$statistics_monthly_product[$month] = 0;
}
}
}
You can try something like this:
$year = [0,0,0,0,0,0,0,0,0,0,0,0];//initialize all months to 0
foreach($monthly_uploaded_product as $key)
$year[$key->month-1] = $key->total;//update each month with the total value
}
This code returns your expected array
$data = [["total" => 1,"month" => 10],["total" => 17,"month" => 11]];
$monthTotals = [];
foreach($data as $item){
$monthTotals[$item["month"]] = $item["total"];
}
$chartJSCompat = [];
for($i = 0;$i < 12;$i++){
if(isset($monthTotals[$i+1]))
$chartJSCompat[$i] = $monthTotals[$i+1];
else
$chartJSCompat[$i] = 0;
}
var_dump($chartJSCompat);
The line $statistics_monthly_product = array(); creates a new array. Meaning that when you loop later on and try to do $statistics_monthly_product[$month] you are trying to access the index $month of an empty array. This will always give you the error of undefined index, since there is nothing in the array at all.
Perhaps you can initialize the array first with some default values:
$statistics_monthly_product = [0,0,0,0,0,0,0,0,0,0,0,0];

php arrays, timestamps and loops

I have the following code. The $results array outputs like so
[1] => stdClass Object ( [ID] => 4429 [post_date_gmt] => 2015-03-05 11:04:18 )
In the second loop I'm calculating the difference between todays time and the postdate. The right results are returned in the IF statement, however to get here I've lost the ID from the original $results array. I need to change a value in the database based on ID if $difference < 72
So the question is - Is it possible to get to the IF statement whilst keeping the ID and post_date_gmt together?
<?php
global $wpdb;
$results = $wpdb->get_results(
"SELECT ID, post_date_gmt
FROM wp_posts
WHERE post_type = 'job_listing'"
);
print_r($results);
$jobids = array();
$jobdates = array();
foreach($results as $oneitem) {
$jobids[]=$oneitem->ID;
$jobdates[]=$oneitem->post_date_gmt;
}
foreach($jobdates as $value) {
$postdate = $value;
$today = time();
$postdate = strtotime($postdate);
//echo $postdate;
$difference = round(abs($today-$postdate)/60/60);
if($difference < 72) {
echo $difference;
//change a value in the database where the id matches the id from the $results array
}
}
?>
Thanks for any suggestions!
When you are building your arrays, why not use the job ID as the key for the jobdates array?
foreach($results as $oneitem) {
$jobdates[$oneitem->ID]=$oneitem->post_date_gmt;
}
Then when you call that array for the second foreach loop, call the key as well foreach($jobdates as $key => $value) and it will be available to use and properly associated.

foreach php statement

I need to combine two foreach statement into one for example
foreach ($categories_stack as $category)
foreach ($page_name as $value)
I need to add these into the same foreach statement
Is this possible if so how?
(I am not sure I have understood your question completely. I am assuming that you want to iterate through the two lists in parallel)
You can do it using for loop as follows :
$n = min(count($category), count($value));
for($c = 0; $c < $n; $c = $c + 1){
$categories_stack = $category[$c];
$pagename = $value[$c];
...
}
To achieve the same with foreach you need a function similar to Python's zip() function.
In Python, it would be :
for categories_stack, pagename in zip(categories, values):
print categories_stack, pagename
Since PHP doesn't have a standard zip() function, you'll have to write such a function on your own or go with the for loop solution.
You can do nested foreachs if that's what you want. But without knowing more of your data, it's impossible to say if this helps:
foreach ($categories_stack as $category) {
foreach ($page_name as $value) {
}
}
Probably you want to print out all pages in a category? That probably won't work, so can you give a bit more info on how the arrays look like and relate to each other?
This loop will continue to the length of the longest array and return null for where there are no matching elements in either of the arrays. Try it out!
$a = array(1 => "a",25 => "b", 10 => "c",99=>"d");
$b = array(15=>1,5=>2,6=>3);
$ao = new ArrayObject($a);
$bo = new ArrayObject($b);
$ai = $ao->getIterator();
$bi = $bo->getIterator();
for (
$ai->rewind(),$bi->rewind(),$av = $ai->current(),$bv = $bi->current();
list($av,$bv) =
array(
($ai->valid() ? $ai->current() : null),
($bi->valid() ? $bi->current() : null)
),
($ai->valid() || $bi->valid());
($ai->valid() ? $ai->next() : null),($bi->valid() ? $bi->next() : null))
{
echo "\$av = $av\n";
echo "\$bv = $bv\n";
}
I cannot really tell from the question exactly how you want to traverse the two arrays. For a nested foreach you simply write
foreach ($myArray as $k => $v) {
foreach ($mySecondArray as $kb => $vb {
}
}
However you can do all sorts of things with some creative use of callback functions. In this case an anonymous function returning two items from each array on each iteration. It's then easy to use the iteration value as an array or split it into variables using list() as done below.
This also has the added benefit of working regardless of key structure. I's purely based on the ordering of array elements. Just use the appropriate sorting function if the elements are out of order.
It does not worry about the length of the arrays as there is no error reported, so make sure you keep an eye out for empty values.
$a = array("a","b","c");
$b = array(1,2,3);
foreach (
array_map(
create_function(
'$a,$b', 'return array($a,$b);'
)
,$a,$b
)
as $value
)
{
list($a,$b) = $value;
echo "\$a = $a\n";
echo "\$b = $b\n";
}
Output
$a = a
$b = 1
$a = b
$b = 2
$a = c
$b = 3
Here's another one for you that stops on either of the lists ending. Same as using min(count(a),count(b). Useful if you have arrays of same length. If someone can make it continue to the max(count(a),count(b)) let me know.
$ao = new ArrayObject($a);
$bo = new ArrayObject($b);
$ai = $ao->getIterator();
$bi = $bo->getIterator();
for (
$ai->rewind(),$bi->rewind();
$av = $ai->current(),$bv=$bi->current();
$ai->next(),$bi->next())
{
echo "\$av = $av\n";
echo "\$bv = $bv\n";
}
This is where the venerable for loop comes in handy:
for(
$i = 0,
$n = sizeof($categories_stack),
$m = sizeof($page_name);
$i < $n && $i < $m;
$i++
) {
$category = $categories_stack[$i];
$value = $page_name[$i];
// do stuff here ....
}
Surely you can just merge the arrays before looping?
$data = array_merge($categories_stack, $page_name);
foreach($data AS $item){
...
}
Do the array elements have a direct correspondence with one another, i.e. is there an element in $page_name for each element in $categories_stack? If so, just iterate over the keys and values (assuming they have the same keys):
foreach ($categories_stack as $key => $value)
{
$category = $value;
$page = $page_name[$key];
// ...
}
Could you just nest them with variables outside the scope of the foreach, or prehaps store the content as an array similar to a KVP setup? My answer is vague but I'm not really sure why you're trying to accomplish this.

Categories