php - foreach() Invalid argument
Hello i keep getting this error Invalid argument supplied for foreach() on this loop below, i get two errors
Warning: Invalid argument supplied for foreach() in /home/xxx/xx.php on line 36
Warning: Cannot modify header information - headers already sent by (output started at /home/xxx/xx.php:36) in /home/xxx/xx.php on line 100 {"status":"success","count":0,"data":[]}
<?php
require('../../../../wp-blog-header.php');
header("HTTP/1.1 200 OK");
//$condition = isset($_REQUEST['condition']) ? $_REQUEST['condition'] : '';
//$condition = str_replace('\\','',$condition);
//$condition = '{"id":200,"items":[{"size":"m","color":"green"}]}';
$condition = isset($_REQUEST['condition'])? stripslashes( $_REQUEST['condition']) : '';
$search_condition = json_decode($condition,true);
/*
$search_condition = array(
'id'=>194,
'items'=>array(
array(
'size'=>'xl',
'color'=>'blue',
),
)
);
*/
$id = $search_condition['id'];
$items= $search_condition['items'];
$condition_pair =array();
global $wpdb;
$table_posts = $wpdb->prefix . 'posts';
$table_post_meta = $wpdb->prefix . 'postmeta';
$string = 'product-'.$id.'-variation';
$posts = $wpdb->get_results("select * from $table_posts WHERE post_name LIKE '%$string%' ");
//echo "select * from $table_posts p INNER JOIN $table_post_meta pm ON pm.post_id = p.ID WHERE p.post_name LIKE '%$string%'";exit;
$extra_attribute_records = get_post_meta($id, '_product_attributes', TRUE);
$attribute_names = array();
foreach($extra_attribute_records as $key => $value)
{
$attribute_names[] = $key;
}
$list_product = array();
$i= 0;
foreach($posts as $post)
{
$image_url = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID));
$price = get_post_meta($post->ID, '_regular_price', TRUE);
$promotion = get_post_meta($post->ID, '_sale_price', TRUE);
$weight = get_post_meta($post->ID, '_weight', TRUE);
$height = get_post_meta($post->ID, '_height', TRUE);
$width = get_post_meta($post->ID, '_width', TRUE);
$length = get_post_meta($post->ID, '_length', TRUE);
$quantity = get_post_meta($post->ID, '_stock', TRUE);
$quantity = (int)$quantity;
$sku = get_post_meta($post->ID, '_sku', TRUE);
$stock_status = get_post_meta($post->ID, '_stock_status', TRUE);
$extra_attribute_records = array();
foreach($attribute_names as $att_name)
{
$extra_attribute_records[$att_name] = strtolower(get_post_meta($post->ID, 'attribute_'.$att_name, TRUE));
}
if(in_array($extra_attribute_records,$items))
{
$title = get_the_title($id).' '.strtoupper(implode('/', $extra_attribute_records)).'';
$arr = array(
'id' => $post->ID,
'title' => $title,
'description' => get_post_field('post_content', $id),
'excerpt' => get_post_field('post_excerpt', $id),
'price' => $price,
'currency' => get_woocommerce_currency(),
'weight' => $weight,
'sku' => $sku,
'quantity' => $quantity,
'featured' => 0,
'mark_as_new' => $post->mark_as_new,
'width' => $width,
'height' => $height,
'length' => $length,
'sort_order' => $post->sort_order,
'promotion_price'=>(int)$promotion,
'thumbnail' => $image_url[0],
'category_slug'=>$post->slug,
'extra_attributes' => array(),//'$extra_attribute_records,
'categories'=>get_the_product_category(),
'stock_status'=>$stock_status,
'post_date' => $post->post_date,
);
$list_product[] = $arr;
$i++;
}
}
header('Content-type: text/json');
echo json_encode(
array(
"status" => "success",
'count' => $i,
"data" => $list_product,
));
exit();
What seems to be the problem?
Answer
Solution:
To fix the issue please set the 3rd paramter in the
get_post_meta()
method to FALSE. Optionaly you could remove the 3rd param altogether as the defualt value is also FALSE. You should now get an array returned. See https://developer.wordpress.org/reference/functions/get_post_meta/Replace the following line in the example:
With this line of code:
To prevent the "Warning: Invalid argument supplied for foreach()" error from happening if for any reason you where not to get an array back put an if statment around your foreach loop to check that
$extra_attribute_records
contains an array.The PHP error "Warning: Invalid argument supplied for foreach()" is being output to the page which is the reason why your headers are already sent by the time you get to "header('Content-type: text/json');". Fixing the above issue should hopfully allow you to send the Content-type header.