Wordpress PHP MySQL query with a multidimensional array - php

When I run the below PHP in WordPress without the foreach I successfully get printed a multidimensional array. When I use the foreach it returns an error 500 I am just trying to loop through the results so I am able to select each name and then push it to another array.
If someone could assist me with looping through this array, that would be great!
Array
(
[0] => stdClass Object
(
[term_taxonomy_id] => 26
[taxonomy] => product_brand
[name] => Authentic Cheese
[slug] => authentic-cheese
)
[1] => stdClass Object
(
[term_taxonomy_id] => 27
[taxonomy] => product_brand
[name] => Robot
[slug] => robot
)
)
PHP
$q2 = "SELECT t.term_taxonomy_id, t.taxonomy, e.name, e.slug
FROM wp_term_taxonomy t
INNER JOIN wp_terms e ON t.term_taxonomy_id = e.term_id
WHERE taxonomy = 'product_brand'";
$r2 = $wpdb->get_results($q2);
print_r($r2);
foreach ($r2 as $row) {
echo $row['name'];
}

You have an array of objects in the result. So use:
foreach ($r2 as $row) {
echo $row->name;
}

You have a 1 dimensional array of objects, instances of stdClass, to be exact:
Array
(
[0] => stdClass Object //<== stdClass OBJECT!!
That means that you can either use the objects, and access the names like you would with any object:
foreach ($array as $row)
{
echo $row->name, PHP_EOL;
}
Or, if you really want to, you can simply cast the objects to arrays:
foreach ($array as $k => $o)
{
$array[$k] = (array) $o;//cast and re-assign
}
Next time you loop over the $array, the objects will be gone, and you'll get associative arrays instead... really, though, this cast business is just overhead, I'd really just use the objects if I were you.
Of course, if you can change the fetch mode, you could change it so that all results are fetched as associative arrays.
According to the wordpress documentation, you can pass a second argument to the get_results method, that specifies the fetch method:
$r2 = $wpd->get_results($q2, ARRAY_A);
Would be the best way to ensure that $r2 is actually an array of associative arrays
To quote the documentation on which I base this:
Generic, mulitple row results can be pulled from the database with get_results. The function returns the entire query result as an array, or NULL on no result. Each element of this array corresponds to one row of the query result and, like get_row, can be an object, an associative array, or a numbered array.
<?php $wpdb->get_results( 'query', output_type ); ?>
query
(string) The query you wish to run. Setting this parameter to null will return the data from the cached results of the previous query.
output_type
One of four pre-defined constants. Defaults to OBJECT. See SELECT a Row and its examples for more information.
OBJECT - result will be output as a numerically indexed array of row objects.
OBJECT_K - result will be output as an associative array of row objects, using first column's values as keys (duplicates will be discarded).
ARRAY_A - result will be output as an numerically indexed array of associative arrays, using column names as keys.
ARRAY_N - result will be output as a numerically indexed array of numerically indexed arrays.

Note from your print_r that it's an array of objects not an array of arrays. So you need to do
foreach ($r2 as $object) {
echo $object->name;
}

You can use wp_list_pluck in WordPress:
<?php names = wp_list_pluck( $your_array, 'name' ); ?>

Related

FETCH_ASSOC removes indexes in the wrong array

I am creating a small web application and I am running on two arrays - one retrieved by simplexml_load_file and the other generated by query to database. I have a little problem with the latter - I need to create an associative array that I can reference through indexes. For that I do something like that.
$stmt->execute();
$db = $stmt->fetchAll(PDO::FETCH_ASSOC);
The array should therefore look like this:
Array (
['element'] => value,
)
It looks like this:
Array (
[0] => Array (
['element'] => value,
)
)
The only thing I noticed was that in the query the records are created so
Array (
[0] => Array (
['element'] => value,
[0] => value
)
)
My solution removes indexes inside the first array, in this example it will remove the line [0] => value, although the main index will remain. How can I change this to result in a full associative associative array? I mention that I want to display all the records from the query, the same fetch () works, although it displays one record (last) from the query.
Try to change
From
$db = $stmt->fetchAll(PDO::FETCH_ASSOC);
To
$db = $stmt->fetch(PDO::FETCH_ASSOC);
PDOStatement::fetch — Fetches the next row from a result set
While PDOStatement::fetchAll — Returns an array containing all of the result set rows
The 0 means row one. If you want to process only one row use the current function on the array which will give you expected results

How do I reorganize an array in PHP?

I am trying to figure out how to reorganize an array..
I have a multidimensional array(Ill call that original_array) and I would like to take the first array within original_array and set the values as keys in a new array. I also want to take the values of the second array in original_array and make them keys and then set the values of the third array in original_array as the values for those keys.
Here is an example of original_array:
Array (
[id] => Array (
[0] => 1
[1] => 3
)
[reward] => Array (
[0] => Movie
[1] => Trip
)
[cost] => Array (
[0] => 50
[1] => 200
)
)
Basically what I would like to do is look like this:
Array (
[1] => Array (
[Movie] => 50
)
[3] => Array (
[Trip] => 200
)
)
Is there a simple and elegant way to merge these like this?
I have spent hours trying to figure this out using array_merge, array_merge_recursive.. etc. And have search SO far and wide for a similar questions, but I haven't found anything that does what I am after.
I was able to correctly combine the 2nd and 3rd arrays in original_array with array_combine. But, I am at a loss as how to combine that result with the 1st array's values in original_array.
Thanks in advance to any help!
Well, the dirty way would be just use combine array functions like array_combine with the input:
$new_array = array_combine(
$array['id'], // parent keys
// combine chunked combined sub keys :p
array_chunk(array_combine($array['reward'], $array['cost']), 1, true)
);
There may be some incantation of array_*() merging functions that could produce what you're looking for, but it is far easier to just iterate over the original array's [id] sub-array and use its values to create new sub-array keys in a different output array.
// To hold your output
$output = array();
// Iterate the original array's [id] sub-array
foreach ($original['id'] as $idxkey => $newkey) {
// Add a sub-array using $newkey to the output array
$output[$newkey] = array(
// Using the index (not value), retrieve the corresponding reward
// value to use as the new array key
// and corresponding cost to use as the new subarray value
$original['reward'][$idxkey] => $original['cost'][$idxkey]
);
}
Here is a demonstration: https://3v4l.org/2pac3
This should work for you:
First you can get the keys for the main array into a separate variable with array_shift(), which will just remove the first element from your array, which is the array holding the keys.
Then use array_map() to loop through both of your subArrays and use reward as key with the cost values as value and return it in an array. At the end you just have to array_combine() your keys $keys with the new created array.
Code:
<?php
$keys = array_shift($arr);
$result = array_combine($keys, array_map(function($k, $v){
return [$k => $v];
}, $arr["reward"], $arr["cost"]));
print_r($result);
?>
You might wanna take a look at BaseArrayHelper from Yii 2.0 Framework.
Although this file is part of a framework it has only very few dependencies and you should be able to use just this file or parts of it in your code with small modifications.
An example for your use case can be found in the index() method.

How to get the intersection of an array of multidimensional arrays?

I have an array of multidimentional arrays. Each array represents a result set from a search. I am having trying to figure out how to filter this set of data to only include arrays that are present in each array.
Note: The index's shown below each represent multidimentional arrays. Each array has a deeply nested Id key that can be used for comparison.
The Id is located at:
$reference_variable['data']['Id'][0]
For example,
array(
array([0], [19], [21], [148]),
array([2], [21], [32], [44], [432], [549]),
array([13], [21], [148])
)
Should return:
array(
[21]
)
and:
array(
array([0], [12], [15]),
array([2], [21], [32], [44], [432], [549]),
array([13], [21], [148])
)
Should return:
array(
[]
)
What is the best way to handle this? array_intersect does not work well with multidimensional arrays.
I've already tried storing all Ids in an array, and using array_count_values to find duplicate Ids, and then use array_filter to compare if the Id of the current array was equal to any of the duplicate Id's.
But that turned out to be totally wrong since this method would allow:
array(
array([0], [19], [21], [148]),
array([2], [21], [32], [44], [432], [549]),
array([13], [21], [148])
)
To return:
array(
[21, 148]
)
Which is not the intersection of all arrays.
Just store the indexes of the first array in an array. Check for matching indexes on the second array and store those in a second array A2. Check for matches between the second stored array ( A2 ) and the third array. Call it A3 for consistency ( A3 ). This is your answer.
Maybe 10-20 lines of code.
This was the answer in my case:
$params = array_merge($array_of_arrays, array('array_compare'));
$intersection = call_user_func_array('array_uintersect', $params);
function array_compare($a1, $a2)
{
if ($a1 === $a2) {
return 0;
}
if ($a1 > $a2) {
return 1;
}
return -1;
}
Credit: https://stackoverflow.com/a/2020654/1911755

CodeIgniter indexed array on query

How can I receive indexed array after mysql query? Or is there any method to convert $this->db->get() into mysql resource? Or convert associative array to indexed?
PHP has a function array_values() that will return an array of just the values.
http://it.php.net/manual/en/function.array-values.php
Example on converting codeigniter result_array to indexed Array:
$query = $this->db->query("SELECT `tag_id` FROM `tags`");
$arr = $query>result_array();
print_r($arr); //codeigniter default result array
//Output:
Array
(
[0] => Array
(
[tag_id] => 1
)
[1] => Array
(
[tag_id] => 3
)
)
Now If You want to convert above array to indexed Array then you have to use array_column() function which convert it associative array to indexed array by taking array key as argument see Below for example:
$query = $this->db->query("SELECT `tag_id` FROM `tags`");
$tags = $query>result_array();
$arr = array_column($tags, "tag_id");
print_r($arr); //converted indexed array
//Output:
Array
(
[0] => 1
[1] => 3
)
It looks like you might be using PHP CodeIgniter. CodeIgniter's DB implementation doesn't support indexed result arrays, you have to choose between object or associative array.
This is done to make your queries more maintainable, as returning numeric indexes are harder to debug and maintain.
Code Igniter User Guide - database results

PHP - Get values from Array

I am trying to retrieve a value from an Array. Here is the code:
$opt=get_records_sql($sql1);
print_object($opt);
$n = count($opt);
if (empty($opt)){
echo 'No options selected';
}
else{
$optno = $opt["subjectid"];
echo '<br>$optno = '.$optno;
}
I tried to use: $opt["subjectid"] but I get the following error:
Notice: Undefined index: subjectid
Contents of array:
Array
(
[1] => stdClass Object
(
[uname] => JHollands06
[tutor] => M LSt
[subjectid] => 1
[year] => 2010
[optid] => 1
)
)
How to I fetch the data subjectid which has value 1?
Method 1: Convert the object to an array by casting it.
$opt[1] = (array) $opt[1];
echo $opt[1]['subjectid'];
To convert all objects in an array (if there are more than one):
foreach ($opt as $k => $val) {
$opt[$k] = (array) $val;
}
Method 2: Simply call it as an object like it is already assigned.
echo $opt[1]->subjectid
There is a difference between an array and an object. An object contains variables that have to be called using the '->' and an array contains values which are associated with a specific key. As your output states, you have an array containing an stdClass object, not another array.
$opt is an array of rows. So you'd do something like this:
foreach($opt as $row)
{
echo $row['subjectid'];
}
Or just use an index:
$opt[0]['subjectid'];
Your array contains rows. It's not just one row. So you need to index it by row first.
edit: your rows are objects, my bad. So it should be
$opt[1]->subjectid

Categories