Getting object into array - php

I'm not so advanced in PHP, just basic I can understand. I was trying an API and it returns it as object, how do I convert it to array? I did searched through stackoverflow and found lots of solution, but none works for me. $array returns empty array. Here is my code:-
while (1) {
$line = '';
$w->pollMessage();
$msgs = $w->getMessages();
foreach ($msgs as $m) {
print_r($msgs);
$array = json_decode(json_encode($msgs), true);
print_r($array);
}
And here is the result I get print_r($msgs):
Array
(
[0] => ProtocolNode Object
(
[tag:ProtocolNode:private] => message
[attributeHash:ProtocolNode:private] => Array
(
[from] => amy
[type] => text
[id] => 3EB0E191F15B831D244E
[t] => 1462939886
[notify] => Nick
)
[children:ProtocolNode:private] => Array
(
[0] => ProtocolNode Object
(
[tag:ProtocolNode:private] => enc
[attributeHash:ProtocolNode:private] => Array
(
[v] => 2
[type] => msg
)
[children:ProtocolNode:private] =>
[data:ProtocolNode:private] => 3
)
[1] => ProtocolNode Object
(
[tag:ProtocolNode:private] => body
[attributeHash:ProtocolNode:private] =>
[children:ProtocolNode:private] =>
[data:ProtocolNode:private] => good
)
)
[data:ProtocolNode:private] =>
)
)

I don't see your problem. You already have an array and do not need to handle with json. If you don't like it as array, you can simply cast it to an object.
$myArray = (object) $myArray;

Requirements: Walk a multiway object tree and apply a callback to each node.
Working demonstration at eval.in
Explanation:
1) There are a lot of private properties and I am not sure 'casting to an array' will let get at them.
2) If you have the original class then you may want to usesome of the methods on it.
The approach I used is:
a) Provide a 'tree walk' that will visit all the nodes in the tree. I am not concerned about order of visiting. Just to visit then all.
b) Rather than provide specific code to process the node. I provide a 'callback' hook.
c) As I don't have the class I create a simple one that will give me easy access to the private properties.
The Tree Walk function:
function walkProtocolNodes(\ProtocolNode $currentNode, /* callable */ $processNode)
{
$processNode($currentNode);
foreach ($currentNode->children as $nextNode) {
walkProtocolNodes($nextNode, $processNode);
}
return;
}
Sample processNode function:
All it does is append the attributesHash to the output array (outputResults)...
$processNode = function (\ProtocolNode $node) use (&$outputResults) {
$outputResults[] = $node->attributeHash;
};
Run the tree walk:
walkProtocolNodes($node1, $processNode);
The 'protocolNode' class I used:
class ProtocolNode {
private $tag = 'message';
private $attributeHash = array();
private $children = array();
private $data = 'good';
public function __construct($attrs = array()) {
$this->attributeHash = $attrs;
}
public function addChild(\ProtocolNode $node) {
$this->children[] = $node;
}
public function __get($propertyName) {
return $this->$propertyName;
}
}
See the demonstration to see the output

Related

How can I fetch the record for 2018 only by php

I want to fetch the list they don't have an action in 2019 (they should have the only action before Jan 2019).
For different list, there is different array with the timestamp.
Here is one array for a list.
(its name list1)
Array
(
[list] => Array
(
[0] => Array
(
[action] => open
[timestamp] => 2019-04-18T18:03:24+00:00
)
[1] => Array
(
[action] => click
[timestamp] => 2018-12-18T18:03:24+00:00
)
)
)
(So, in this case, that record should not print because it has the action in 2019 )
There is a different array for other lists
(its name list2)
Array
(
[list] => Array
(
[0] => Array
(
[action] => open
[timestamp] => 2018-04-18T18:03:24+00:00
)
[1] => Array
(
[action] => open
[timestamp] => 2018-03-1T18:03:24+00:00
)
)
)
(In this case, this record print because it has no action in 2019)
What I am doing to achieve this:
$date1 = "2018-12-31T024:00:00+00:00";
foreach ($list['list'] as $e) {
if($date1<$e['timestamp'])
echo $e['action'];
}
But it is not displaying the records before 2019 only. Please guide me how I achieve this.
The main idea is to use DateTime, not a string here. Finaly, hope I got it right:
$latestDate = new \DateTime('2019-01-01');
records = $api->get("record/members?offset=0&count=20");
foreach ($records['members'] as $member) {
$hash = md5($member['email_address']);
$lists = $api->get("record/members/$hash/list");
foreach ($lists['list'] as $action) {
if(new \DateTime($action['timestamp']) >= $latestDate) {
continue 2;
}
}
var_dump($lists['list']);
}
You can also use array_filter() for this and replace var_dump as you wish.
As you retrieve an array from your API you can simply use the FilterIterator class PHP natively provides. Have a look at the following example.
namespace App\Filter;
use DateTime;
use FilterIterator;
use Iterator;
class DateFilterIterator extends FilterIterator
{
protected $filter;
public function __construct(Iterator $iterator, $filter)
{
parent::__construct($iterator);
$this->filter = $filter;
}
public function accept()
{
$entry = $this->getInnerIterator()->current();
return (new DateTime($entry['timestamp']))->format('Y') !== $this->filter;
}
}
This is our filter, which will iterator over the api response.
$object = new ArrayObject($apiResponse);
$iterator = new DateFilterIterator($object->getIterator(), 2018);
foreach ($iterator as $entry) {
echo "<pre>";
var_dump($entry);
echo "</pre>";
}
As we initialize our filter with the year 2018, we will retrieve the array entries with the timestamp, which fits the year 2018. With the FilterIterator class you can define the year and iterate over the api response over and over for different filter values. The filtering itself is executed in a simple foreach loop / on iteration.
If you want to filter for a specific date, you have to adjust the accept function of the filter class for your needs.
I am not sure but you can try I not tested code
function filterDate($date)
{
$yearDate=date('Y', strtotime ($date['timestamp']));
if($yearDate==2018)
{
return $date;
}
}
$datesOnly2018=array_filter('filterDate',$list['list']);

Custom While in json array

Its My PHP Code:
$res_media=mysql_query("SELECT * FROM mv_media");
$media = array();
while($resualt_media = mysql_fetch_assoc($res_media)) {
$media[]= $resualt_media['title'];
}
echo $media;
And Its My output:
["Test","Test","Test","Test","Test"]
I want Change it to this format :
["Test"],["Test"],["Test"],["Test"],["Test"]
I changed My Code to this code :
$res_media=mysql_query("SELECT * FROM mv_media");
$media = array();
while($resualt_media = mysql_fetch_assoc($res_media)) {
$media[]= [$resualt_media['title']];
}
echo $media;
Now My OutPut :
[["Test","Test","Test","Test","Test"]]
But I need This custom output:
[["Test"],["Test"],["Test"],["Test"],["Test"],["ItsMyCustomChild"]]
I want add Custom Child with out database!
You can change $media[] = [<value>] to $media[][] = <value> and it will work, because then you'll create a new array inside an array.
I would suggest this approach:
<?php
$input = json_decode('["Test","Test","Test","Test","Test"]');
$output = [];
array_walk($input, function($element) use (&$output) {
$output[] = [$element];
});
var_dump(json_encode($output));
Alternatively this can be simplified to just:
<?php
$data = json_decode('["Test","Test","Test","Test","Test"]');
array_walk($data, function(&$element) {
$element = [$element];
});
var_dump(json_encode($data));
The created array structure obviously is:
Array
(
[0] => Array
(
[0] => Test
)
[1] => Array
(
[0] => Test
)
[2] => Array
(
[0] => Test
)
[3] => Array
(
[0] => Test
)
[4] => Array
(
[0] => Test
)
)
Which, if you again json_encode() it, results in the desired format:
string(46) "[["Test"],["Test"],["Test"],["Test"],["Test"]]"
The specific issue you are actually dealing with is not so much the creation of the desired structure, but that you are trying to modify the JSON string instead of the actual array you want to work with. That is why a call to json_decode() is used initially.
$res_media=mysql_query("SELECT * FROM mv_media");
$media = array();
while($resualt_media = mysql_fetch_assoc($res_media)) {
array_push($media,array($resualt_media['title']));
}
print_r $media;
You just need to change below line. and you will get your desired result.
$media[][]= $resualt_media['title'];
if you want to see what you get . you need to add json_encode() after the while.
like below
echo json_encode($media);

replace duplicate fom stdclass array php [duplicate]

This question already has answers here:
How can I remove duplicates in an object array in PHP?
(2 answers)
Closed 8 years ago.
When I print $online_performers variable I want to get a unique value for id 2. Do I need to convert them in standard array first or is that possible without it? (remove all duplicates).Please check my new code for this.
Array
(
[0] => stdClass Object
(
[id] => 1
[username] => Sample1
)
[1] => stdClass Object
(
[id] => 2
[username] => Sample1
)
[2] => stdClass Object
(
[id] => 2
[username] => Sample1
)
[3] => stdClass Object
(
[id] => 4
[username] => Sample4
)
)
to
Array
(
[0] => stdClass Object
(
[id] => 1
[username] => Sample1
)
[1] => stdClass Object
(
[id] => 4
[username] => Sample4
)
)
PHP has a function called array_filter() for that purpose:
$filtered = array_filter($array, function($item) {
static $counts = array();
if(isset($counts[$item->id])) {
return false;
}
$counts[$item->id] = true;
return true;
});
Note the usage of the static keyword. If used inside a function, it means that a variable will get initialized just once when the function is called for the first time. This gives the possibility to preserve the lookup table $counts across multiple function calls.
In comments you told, that you also search for a way to remove all items with id X if X appears more than once. You could use the following algorithm, which is using a lookup table $ids to detect elements which's id occur more than ones and removes them (all):
$array = array("put your stdClass objects here");
$ids = array();
$result = array();
foreach($array as $item) {
if(!isset($ids[$item->id])) {
$result[$item->id]= $item;
$ids[$item->id] = true;
} else {
if(isset($result[$item->id])) {
unset($result[$item->id]);
}
}
}
$result = array_values($result);
var_dump($result);
If you don't care about changing your keys you could do this with a simple loop:
$aUniq = array ();
foreach($array as $obj) {
$aUniq[$obj->id] = $obj;
}
print_r($aUniq);
Let's say we have:
$array = [
//items 1,2,3 are same
(object)['id'=>1, 'username'=>'foo'],
(object)['id'=>2, 'username'=>'bar'],
(object)['id'=>2, 'username'=>'baz'],
(object)['id'=>2, 'username'=>'bar']
];
Then duplication depends of what do you mean. For instance, if that's about: two items with same id are treated as duplicates, then:
$field = 'id';
$result = array_values(
array_reduce($array, function($c, $x) use ($field)
{
$c[$x->$field] = $x;
return $c;
}, [])
);
However, if that's about all fields, which should match, then it's a different thing:
$array = [
//1 and 3 are same, 2 and 3 are not:
(object)['id'=>1, 'username'=>'foo'],
(object)['id'=>2, 'username'=>'bar'],
(object)['id'=>2, 'username'=>'baz'],
(object)['id'=>2, 'username'=>'bar']
];
You'll need to identify somehow your value row. Easiest way is to do serialize()
$result = array_values(
array_reduce($array, function($c, $x)
{
$c[serialize($x)] = $x;
return $c;
}, [])
);
But that may be slow since you'll serialize entire object structure (so you'll not see performance impact on small objects, but for complex structures and large amount of them it's sounds badly)
Also, if you don't care about keys in resulting array, you may omit array_values() call, since it serves only purpose of making keys numeric consecutive.

How to reduce the code for this function

Input array $items:
Array
(
[0] => Array
(
[id] => 2
)
[1] => Array
(
[id] => 5
)
)
Result of print_r(foo($items))
Array
(
[2] => 1
[5] => 1
)
Function foo()
function foo($items)
{
$result = array();
foreach($items => $array)
{
$result[$array['id']] = TRUE;
}
return $result;
}
How can I simply write this array transformation with standards PHP functions, like array_flip() or something else. Is it possible?
Using a built in PHP function would only introduce the unnecessary overhead of additional function calls. What you have written is already an efficient method for creating the desired output from the given input.
I would recommend using your custom function if possible.
$r = array_combine(
array_map(function($i){ return $i['id']; }, $items), // <-- key
array_fill(0, count($items), true /* or 1 */) // <-- value
);

Converting array and objects in array to pure array [duplicate]

This question already has answers here:
Convert a PHP object to an associative array
(33 answers)
Closed 1 year ago.
My array is like:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => demo1
)
[1] => stdClass Object
(
[id] => 2
[name] => demo2
)
[2] => stdClass Object
(
[id] => 6
[name] => otherdemo
)
)
How can I convert the whole array (including objects) to a pure multi-dimensional array?
Have you tried typecasting?
$array = (array) $object;
There is another trick actually
$json = json_encode($object);
$array = json_decode($json, true);
You can have more info here json_decode in the PHP manual, the second parameter is called assoc:
assoc
When TRUE, returned objects will be converted into associative arrays.
Which is exactly what you're looking for.
You may want to try this, too : Convert Object To Array With PHP (phpro.org)
Just use this :
json_decode(json_encode($yourArray), true);
You can use array_walk to convert every item from object to array:
function convert(&$item , $key)
{
$item = (array) $item ;
}
array_walk($array, 'convert');
Assuming you want to get to this pure array format:
Array
(
[1] => "demo1",
[2] => "demo2",
[6] => "otherdemo",
)
Then I would do:
$result = array();
foreach ($array as $object)
{
$result[$object->id] = $object->name
}
(edit) Actually that's what I was looking for possibly not what the OP was looking for. May be useful to other searchers.
You should cast all objets, something like :
$result = array();
foreach ($array as $object)
{
$result[] = (array) $object
}
As you are using OOP, the simplest method would be to pull the code to convert itself into an array to the class itself, you then simply call this method and have the returned array populate your original array.
class MyObject {
private $myVar;
private $myInt;
public function getVarsAsArray() {
// Return the objects variables in any structure you need
return array($this->myVar,$this->myInt);
}
public function getAnonVars() {
// If you don't know the variables
return get_object_vars($this);
}
}
See: http://www.php.net/manual/en/function.get-object-vars.php for info on get_object_vars()
it you have object and you want to set a value as array
use
$this->object->pluck('name');
then you get the value as array of names like
["name1", "name2", "name3"];

Categories