How to make an array with only 1 index to top level? - php

I have an array like so:
Array
(
[0] => stdClass Object
(
[id] => 12
[name] => Business
)
)
But since it only has 1 index element, how can I make it top level removing the zero index? Because I want to reference this array like so $category->name instead of $category[0]->name
I know I can re-build this with a foreach loop but I was hoping there might be a PHP builtin function that does this?

Do you mean something like this?
$category = $category[0];
echo $category->name;
Instead of the first line, you could also do
$category = reset($category);
reset() will reset the array pointer to the first element and return that element. So this will also work with an associative array (which might have elements but not one with the index 0).

You can use current:
$category = current($category);
echo $category->name;
or
echo current($category)->name;
Using current solves the problem of the index not actually being 0. Another advantage to current is that it doesn't affect the array's internal pointer in any way.

$category = $category[0];

Related

how can i print a specific portion of array in php?

I am trying to print a number from an array. But when i do this:
echo $results[0][0];
i get error.I tried to print the whole array using print_r() function
echo print_r($results);
Then i get this result:
Array ( [0] => stdClass Object ( [lastOrderProcessedNumber] => 109089875875875 ) ) 1
I just need to print "109089875875875" this number
How can i do that?
Thank you in advance
print_r() is a great way to inspect the contents of a variable. What it is showing you is that your variable holds an array whose first element (at index 0) is an object with an lastOrderProcessedNumber attribute. In PHP, you use -> to access object properties, so you should be able to retrieve the 109089875875875 value like this:
$results[0]->lastOrderProcessedNumber
As you can see from the print_r result, the indexed result is an object:
// $results is an 'Array' (access with square brackets)
Array
(
// Index 0 is an Object (access with arrow operator)
[0] => stdClass Object
(
[lastOrderProcessedNumber] => 109089875875875
)
)
This means you have to access the property through the arrow operator, like so:
$results[0]->lastOrderProcessedNumber
If you're expecting to only have one result, or to grab the first result from $results, you can make use of reset:
reset($results)->lastOrderProcessedNumber
If you see $results is an array of objects, that means that $results[0] is an object, not an array, so you can't access its attributes as an array but instead as an object. Like this:
$results[0]->lastOrderProcessedNumber;

array_walk not changing value

function values($id,$col)
{
$vals = [1=>['name'=>'Lifting Heavy Boxes']];
return $vals[$id][$col];
}
$complete = [1=>["id"=>"2","sid"=>"35","material_completed"=>"1","date"=>"2017-12-18"]];
$form = 'my_form';
array_walk($complete, function(&$d,$k) use($form) {
$k = values($k, 'name').' ['.date('m/d/y',strtotime($d['date'])).'] ('.$form.')';
echo 'in walk '.$k."\n";
});
print_r($complete);
the echo outputs:
in walk Lifting Heavy Boxes [12/18/17] (my_form)
the print_r outputs:
Array
(
[1] => Array
(
[id] => 2
[sid] => 35
[material_completed] => 1
[date] => 2017-12-18
)
)
I have another array walk that is very similar that is doing just fine. The only difference I can perceive between them is in the one that's working, the value $d is already a string before it goes through the walk, whereas in the one that's not working, $d is an array that is converted to a string inside the walk (successfully, but ultimately unsuccessfully).
Something I'm missing?
And here's the fixed version:
array_walk($complete, function(&$d,$k) use($form) {
$d = values($k, 'name').' ['.date('m/d/y',strtotime($d['date'])).'] ('.$form.')';
});
That's what I was trying to do anyway. I wasn't trying to change the key. I was under the mistaken impression that to change the value you had to set the key to the new value.
You cannot change the key of the array inside the callback of array_walk():
Only the values of the array may potentially be changed; its structure cannot be altered, i.e., the programmer cannot add, unset or reorder elements. If the callback does not respect this requirement, the behavior of this function is undefined, and unpredictable.
This is also mentioned in the first comment:
It's worth nothing that array_walk can not be used to change keys in the array.
The function may be defined as (&$value, $key) but not (&$value, &$key).
Even though PHP does not complain/warn, it does not modify the key.

Array item call

I have problem with calling Array which are form redux framework to wordpress
when i execute this:
print_r ($ka_opt['theme-order']);
i have this result:
Array ( [nr2] => 1 [nr3] => 1 [nr1] => 1 )
I need to call specific item from this array for example first item, i tryed this to call first possition but dont work:
echo $ka_opt['theme-order'][0];
whats wrong? i dont know how to call variable
That is an associative array, not a numerically keyed array. You can't use numerical keys with associative arrays. You must use their proper keys:
echo $ka_opt['theme-order']['nr2'];
If you want the first item you can us array_shift():
echo array_shift($ka_opt['theme-order']);
If you want a deeper array element you can use array_slice():
// get second element, assuming PHP5.4+
echo array_slice(array_values($ka_opt['theme-order']), 1, 1)[0];
And, of course, you can always loop through it to get the values you seek.

In PHP, how can I access a child object when I don't know it's name?

Using json_decode, I've ended up with an object that looks like this:
$data->foo->bar->1234567->id
I want to access id. There are two problems, both with the number 1234567:
It's an illegal property name.
The number will differ each time, and I can't predict what the number will be. I need a way of accessing id, even when I don't know the number.
I know I can overcome problem (1) with curly braces, but I don't know how to overcome (2). I don't want to use get_object_vars, because the object is likely to be very large, and that function is very slow.
My current solution is simply
foreach ($data->foo->bar as $id); but that feels rather hacky. Is there a better way?
From my comment above, using json_decode(,true) and then resetting.
The example json array looks like:
Array (
[foo] => Array (
[bar] => Array (
[1234567] => Array (
[id] => 1234
)
)
)
)
The code:
<?php
$data = json_decode('{"foo":{"bar":{"1234567":{"id":1234}}}}', true);
reset($data['foo']['bar']);
$number = key($data['foo']['bar']);
echo $data['foo']['bar'][$number]['id'];
Output: 1234
In case you don't need the whole array anymore and only want to get the id you can get it like this:
<?php
$data = json_decode('{"foo":{"bar":{"1234567":{"id":1234}}}}', true);
echo array_shift($data['foo']['bar'])['id'];
Only works if the unknown key is the first element of bar. array_shift removes the element from $data.

Apply function to every array key

I am using Cassandra and I have saved some byte representations as ID. Everything is working fine, however that data (id) is no good for output.
$users = $db->get('1');
echo '<pre>';
print_r($users);
die();
Outputs
Array
(
[��� X��W��c_ ] => Array
(
[id] => ��� X��W��c_
[name] => steve
[surname] => moss
)
[�*B�X��y�~p��~] => Array
(
[id] => �*B�X��y�~p��~
[name] => john
[surname] => doe
)
)
As you can see ID's are some wierd characters, it's because they are byte representations in database. They actually look like \xf5*B\xa0X\x00\x11\xe1\x99y\xbf~p\xbc\xd1~.
In PHPCASSA there is function CassandraUtil::import(); to which I can pass these bytes and it will return guid. It works fine, but I want my array to automatically converted from bytes to guids.
Only option I find is looping through every item in array and assigning new value to it. Somehow I think that it is not the best approach. Is there any other ways to do this?
TL;DR
Have array with bytes like above, need to use CassandraUtil::import(); on array keys and id's to get readable id's. What is the most effective way of doing so.
UPDATE
Sorry, only saw the top level array key, I think you would have to run the function below as well as another one after:
function cassImportWalkRecur(&$item, $key)
{
if ($key == 'id')
$item = CassandraUtil::import();
}
$array = array_walk_recursive($array, 'cassImportWalkRecur');
That should apply it to the ID fields. If you need to check the data first, there maybe a way to detect the encoding, but I am not sure how to do that.
You should be able to create a function and use array_walk to traverse the array and update the keys. Something like:
function cassImportWalk($item, &$key)
{
$key = CassandraUtil::import();
}
$array = array_walk($array, 'cassImportWalk');
Untested (also you may have to change the CassandraUtil usage), but should work.
Unless I am misunderstanding the question this can be done simply and cleanly like so:
$users = $db->get('1');
$keys = array_keys($users);
$readableKeys = array_map("CassandraUtil::import",$keys);
foreach($users as $currentKey => $subArray) {
$readableKey = array_shift($readableKeys);
$subArray['id'] = $readableKey;
$users[$readableKey] = $subArray;
unset($users[$currentKey]);
}
Would array_flip() all keys and values, then array_walk() and apply my function, before doing a final array_flip().

Categories