Accessing an array inside of an array - php

When trying to access an array inside an array, only NULL is output.
My Code:
$aStats = array();
$aStats['hd'] = array();
$aStats['hd'][] = array
(
'dev' => $device,
'total' => $total,
'used' => $used,
'free' => $free,
'used_perc' => $used_perc,
'mount' => $folder
);
echo $aStats['hd']['free'];
When using json_encode, the values are displayed correctly:
die( json_encode( $aStats ) );
Where is my mistake?

Replace these lines:
$aStats['hd'] = array();
$aStats['hd'][] = array
With this:
$aStats['hd'] = array
You appear to be accessing your array ($aStats['hd']['free'];) as if the value of hd is an associated array, but using [] creates a new integer index in the array, and stores the value in that index. Joe Walker's answer shows what happens instead, that you have an associative array pointing to an indexed array pointing to another associative array, rather than the associative to associative array you suggest you're trying to use in your echo statement.

This is a practical tip that will let you find out where is the issue easly, all you need to do is:
var_dump($aStats);
This will output:
array (size=1)
'hd' =>
array (size=1)
0 =>
array (size=6)
'dev' => string 'SomeDevice' (length=10)
'total' => string '10000' (length=5)
'used' => boolean true
'free' => boolean false
'used_perc' => string 'none' (length=4)
'mount' => string '/some/directory/here/' (length=21)
Now you know you can access this element using
$aStats['hd'][0]['free'];
This will return null in your question because your variables are not yet initialized, but I guess you do have them initialized in your code, hope this helps.

Related

Extract just the strings from an array_column array return

I've got told many times, if there is a new question even on the same code to just create a new thread so here I am. Thanks to the guys for helping me with the previous question.
I have the following code:
/* Return an array of _octopus_ids */
$offices = array_map(
function($post) {
return array(
'id' => get_post_meta($post->ID, '_octopus_id', true),
);
},
$query->posts
);
/* Dump out all the multi-dimensional arrays */
var_dump($offices);
$test = array_column($offices, 'id');
var_dump($test);
var_dump($offices) dumps the following:
array (size=10)
0 =>
array (size=1)
'id' => string '1382' (length=4)
1 =>
array (size=1)
'id' => string '1330' (length=4)
var_dump($test) dumps the following:
array (size=10)
0 => string '1382' (length=4)
1 => string '1330' (length=4)
Problem:
How can I use the following code:
$results = $octopus->get_all('employees/' . $test; which results in an Notice: Array to string conversion error.
I want to be able to make a results call such as this $results = $octopus->get_all('employees/1382'); - So I want just the numeric string of $test to be appended to the end of employees/
If I hardcode the 1382 after employees/, I get the following result:
object(stdClass)[1325]
public 'id' => int 1382
What's the proper way to array of strings into just strings?

PHP. How to get the position of an element inside an unidimensional and multidimensional array? [duplicate]

This question already has answers here:
php - get numeric index of associative array
(7 answers)
Closed 3 years ago.
For instance, in the following code, how to get the position -order- of a given element inside the array:
<?php
$cars=array("Volvo","BMW","Toyota","Tesla","Volkswagen");
//for Volvo, an echo statement should return 1
//for BMW, an echo statement should return 2
//for Toyota, an echo statement should return 3 ... and so on ...
?>
Update: After receiving some useful contributions regarding the implementation of search_array(), I was wondering if I can apply the same for arrays contained inside another array. vardump() for a multidimensional array shows me the following:
array (size=3)
'home' =>
array (size=6)
'label' =>
object(Magento\Framework\Phrase)[5814]
private 'text' => string 'Home' (length=4)
private 'arguments' =>
array (size=0)
...
'title' =>
object(Magento\Framework\Phrase)[5815]
private 'text' => string 'Go to Home Page' (length=15)
private 'arguments' =>
array (size=0)
...
'link' => string 'http://example.com/example.html' (length=23)
'first' => boolean true
'last' => null
'readonly' => null
'category4' =>
array (size=6)
'label' => string 'Transport' (length=9)
'link' => string 'http://example.com/example.html' (length=23)
'title' => null
'first' => null
'last' => null
'readonly' => null
'category686' =>
array (size=6)
'label' => string 'Transport' (length=15)
'link' => string '' (length=0)
'title' => null
'first' => null
'last' => boolean true
'readonly' => null
How to get in this case the position of category4 in regard to the array of size=3?
array_search() will let you find the position of an element or it returns FALSE if the element was not found. Read more about it at http://php.net/manual/en/function.array-search.php
From the documentation, this is what can be returned from this function:
Return Values
Returns the key for needle if it is found in the array, FALSE otherwise.
And here is an example:
<?php
$cars=array("Volvo","BMW","Toyota","Tesla","Volkswagen");
//for Volvo, an echo statement should return 1
//for BMW, an echo statement should return 2
//for Toyota, an echo statement should return 3 ... and so on ...
$volvoPosition = array_search("Volvo", $cars);
if ($volvoPosition !== false) {
// Volvo position was found at index/position 0 of the array.
print $volvoPosition; // This gives the value 0
} else {
// "Volvo" was never found in the array.
}
?>
As the example is very simple, meaning, is just an array of strings, then you may use array_flip, which is going to return an array that flips the keys with the values, so we can do:
$cars = ["Volvo","BMW","Toyota","Tesla","Volkswagen"];
$flipped = array_flip($cars);
//for Volvo, => int(0)
var_dump($flipped['Volvo']);
//for BMW, => int(1)
var_dump($flipped['BMW']);
Also remember that the array start with 0 and not with 1, then the index of "Volvo" is 0 and not 1.
Yes you can use array_search(), but array_search() returns the index of the element which is start from 0, so you can do like below,
this is your array
$cars=array("Volvo","BMW","Toyota","Tesla","Volkswagen");
echo (array_search("Volvo",$cars)) + 1; //you can getting 1 as output

2-dimensional array to 1-dimensional array convertion

With my code:
$sql = "SELECT number.phone_number FROM number, ordered_number WHERE ordered_number.number_id=number.id AND ordered_number.order_id=$id";
$connection = \Yii::$app->getDb();
$command = $connection->createCommand($sql);
$numery = $command->queryAll();
I get array that looks like this:
array (size=3)
0 =>
array (size=1)
'phone_number' => string '546732354' (length=9)
1 =>
array (size=1)
'phone_number' => string '565345456' (length=9)
2 =>
array (size=1)
'phone_number' => string '456557546' (length=9)
I want to get simple array, where the first element is just the number (here - the string), without name 'phone_number' and additional 1-element arrays inside the main array. When I try to do foreach on this array, it tells me that I use "Illegal offset type". I found that it means I'm using object, instead of an array, but that's an array, not an object and I have no idea what to do.
Even simplier (but for php5.5 and php7):
$numery = array_column(
$command->queryAll(),
'phone_number'
);
Use below loop to get desired result
$numery = $command->queryAll();
$number_arr = array();
foreach($numery as $number)
{
array_push($number_arr,$number['phone_number']);
}
print_r($number_arr);

php json_decode return [object Object]

I have a problem with JSON data in PHP. I need to use data from this JSON in my SQL statement. When I'm trying to debug it with echo(var_dump, or print_r is not working too) command the output with is
{"records":"tekst","name":"[object Object]"}
This is a JSON structre:
{
records: 'tekst',
name: {
imie: 'imie1',
nazwisko: 'nazwisko1'
}
}
I'm trying to decode this by json_decode(), but I have an error
"Warning: json_decode() expects parameter 1 to be string, array
given".
Does anyone know what's wrong?
PHP manual about JSON and the format required: function.json-decode. basically, double quotes only and names must be quoted.
a demonstration of conversion using PHP.
So, you supply the json string that looks like, with the whitespace removed, like this:
{records:[{id:1,name:'n1'},{id:2,name:'n2'}]}
Which is an object containing an array with two entries that could be arrays or objects.
Except, it is not a valid JSON string as it contains single quotes. And PHP wants all the names in double quotes, as in "id":1.
So, possible PHP code to recreate that, assuming arrays as the inner entries is:
$json = new stdClass();
$records = array();
$entry = array('id' => 1, 'name' => 'n1');
$records[] = $entry;
$entry = array('id' => 2, 'name' => 'n2');
$records[] = $entry;
$json->records = $records;
$jsonEncoded = json_encode($json);
Which, when 'dump'ed looks like:
object(stdClass)[1]
public 'records' =>
array
0 =>
array
'id' => int 1
'name' => string 'n1' (length=2)
1 =>
array
'id' => int 2
'name' => string 'n2' (length=2)
Now, the string that structure produces is:
{"records":[{"id":1,"name":"n1"},{"id":2,"name":"n2"}]}
Which looks similar to yours but is not quite the same. Note the names in double quotes.
However, if your json string looked the same then PHP could decode it, as is shown below:
$jsonDecoded = json_decode($jsonEncoded);
var_dump($jsonDecoded, 'decoded');
Output: Note all objects...
object(stdClass)[2]
public 'records' =>
array
0 =>
object(stdClass)[3]
public 'id' => int 1
public 'name' => string 'n1' (length=2)
1 =>
object(stdClass)[4]
public 'id' => int 2
public 'name' => string 'n2' (length=2)
We may want arrays instead so use the true as the second parameter in the 'decode'
$jsonDecoded = json_decode($jsonEncoded, true);
var_dump($jsonDecoded, 'decoded with true switch');
Output: with arrays rather than objects.
array
'records' =>
array
0 =>
array
'id' => int 1
'name' => string 'n1' (length=2)
1 =>
array
'id' => int 2
'name' => string 'n2' (length=2)
string 'decoded with true switch' (length=24)

Iterator that assigns subvalue as key

Currently I'm looping through a quite large data set. This multidimensional array needs to be grouped by specific array values of its sub arrays. As this is a holiday project, I want to do deepen my knowledge and make more use of PHPs Iterators. Point is, that I don't know how to transform a numeric multi-dimensional Array into a multi-dimensional array with associative keys.
Shortened example (GeoJSON to Array)
array (size=4)
'type' => string 'FeatureCollection' (length=17)
'features' => // THIS is the actual array
array (size=207)
0 => // Sub-Arrays like this one are repeating
array (size=5)
'type' => string 'Feature' (length=7)
'geometry' =>
array (size=2)
'type' => string 'LineString' (length=10)
'coordinates' =>
array (size=410)
0 =>
array (size=2)
0 => float 16.359980888872
1 => float 48.208437070943
// etc.
'geometry_name' => string 'SHAPE' (length=5)
'properties' =>
array (size=5)
'OBJECTID' => int 273
// This/"LBEZEICHNUNG" is the part I want to order/summon
// all further "geometry"-parts by
'LBEZEICHNUNG' => string '13A, 2, 86, U3' (length=1)
'LTYP' => string '1' (length=1)
'LTYPTXT' => string 'Tramway' (length=12)
'SE_ANNO_CAD_DATA' => null
'id' => int 1
The features array is what holds the actually looped datasets. And LBEZEICHNUNG are the values (single or comma separated) I want to sort/order by.
To make an example:
// Original values:
'LBEZEICHNUNG' => string '13A, 2, 86, U3'
// Now split them and push the features into new keys that have those values:
'13A' => array(
0 => // Sub-Arrays like this one are repeating
array (size=5)
'type' => string 'Feature' (length=7)
'geometry' =>
array (size=2)
'type' => string 'LineString' (length=10)
'coordinates' =>
array (size=410)
0 =>
array (size=2)
0 => float 16.359980888872
1 => float 48.208437070943
// etc.
'geometry_name' => string 'SHAPE' (length=5)
'properties' =>
array (size=5)
// "OBJECTID" now is obsolete
// "LBEZEICHNUNG" is now obsolete
'LTYP' => string '1' (length=1)
'LTYPTXT' => string 'Tramway' (length=12)
'SE_ANNO_CAD_DATA' => null
// "id" now is obsolete as well
),
"2" => // gets the same values as "13A"
// same goes for "86" and "U3"
Now every sub array that would have either 13A, 2, 86 or U3 in ["properties"]["LBEZEICHNUNG"], would push its geometry to the end of the already existing subarray/sub-Iterator.
So far I only got a basic recursive Iterator set up, that runs through all leaves.
$data = new \RecursiveArrayIterator( $fileContents );
foreach( new \RecursiveIteratorIterator( $data ) as $key => $value )
{
// foo. bar. dragons.
}
Point is that I can't really figure out how to assign new keys from values in the Iterator. I already tried using a RecursiveFilterIterator and failed gracefully as its simply not intended to do this. Quite frankly: I'm lost as I either can't find the right Iterator to use or I simply ain't know enough about Iterators yet.
I got a working solution with nested foreach-es pushing into another Array. As this is my holiday project I want to learn, hence the Iterator solution, which I hope is more maintainable in the long turn.
Edit: Link to the original Geo-JSON data set CC-BY-SA 3.0/AUT - Data provided by the City of Vienna. Other formats can be found here.
If I understood correctly, you want to sort/ or group the array based on that "LBEZEICHNUNG" key, and use PHP iterators. In order to do that, you have to traverse the entire array, and build a new one that holds the values grouped by that key. This is simple foreach logic.
Iterators shine when you want to traverse a data collection and fetch the data during traversal (or alter it).
In this case, you are fetching the data outside of the iterator (json_decode ?), so that makes iterators kind of pointless - unless you need to do more than just sorting. If you do, I'd suggest you store that data in a format that allows you to easily fetch sorted sets, like a database, then you can use iterators to their full potential.
One way to group the routes is to use basic OOP:
class Route{
protected $trams = array();
// add other route properties (type, geometry etc.)
public function assignTo(Tram $line){
if(!in_array($line, $this->trams, true))
$this->trams[] = $line;
}
public function getTrams(){
return $this->trams;
}
}
class Tram{
public $name;
protected $routes = array();
public function __construct($name){
$this->name= $name;
}
public function addRoute(Route $route){
$this->routes[] = $route;
$route->assignTo($this);
}
public function getRoutes(){
return $this->routes;
}
}
Example:
$trams = array();
foreach($data as $routeData){
$route = new Route();
$tramNames = explode(', ', $routeData['features']['properties']['LBEZEICHNUNG']);
foreach($tramNames as $name){
if(!isset($trams[$name]))
$trams[$name] = new Tram($name);
$trams[$name]->addRoute($route);
// set other route properties...
}
}
You can use usort to sort your multi-dimensional array based on sub-values:
$JSON = iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode(file_get_contents("http://data.wien.gv.at/daten/geoserver/ows?service=WFS&request=GetFeature&version=1.1.0&srsName=EPSG:4326&outputFormat=json&typeName=ogdwien:OEFFLINIENOGD")));
$geoarray = json_decode($JSON, true);
$myarray = $geoarray["features"];
function cmp($a, $b) {
return $a["properties"]["LBEZEICHNUNG"] - $b["properties"]["LBEZEICHNUNG"];
}
usort($myarray, "cmp");
print_r($myarray);

Categories