Create PHP stdClass object from array - php

I am trying to create this format of information/Array in PHP
[OverrideEmailSettings] => stdClass Object (
[email#domain.com] => stdClass Object (
[Reports] => Array (
[0] => stdClass Object (
[ReportType] => 1
[SummaryFrequency] => Array (
[0] => stdClass Object (
[FrequencyType] => 8011
[SecondsPast] => 32400
)
)
[Filter] => stdClass Object (
[ClauseType] => and
[RuleField] =>
[RuleOperator] =>
[RuleValue] =>
[ClauseChildren] => Array (
[0] => stdClass Object (
[ClauseType] =>
[RuleField] => BackupJobDetail.TimeSinceStarted
[RuleOperator] => int_lte
[RuleValue] => 86400
)
)
)
)
)
)
)
Here is my code - $line = the equivelent to email#domain.com
$x = array(
'Reports' => array(
'ReportType' => '1',
'SummaryFrequency' => array(
'FrequencyType' => '8011',
'SecondsPast' => '32400',
),
'Filter' => array(
'ClauseType' => 'or',
'RuleField' => '',
'RuleOperator' => '',
'RuleValue' => '',
'ClauseChildren' => array(
'ClauseType' => '',
'RuleField' => 'BackupJobDetail.TimeSinceStarted',
'RuleOperator' => 'int_lte',
'RuleValue' => '86400',
),
),
),
);
$account_get_user_profile->OverrideEmailSettings->$line = $x;
But I think I have formatted it incorrectly.

You need to cast your arrays to stdClass like:
<?php
$x = [
"Reports" => [
(object) [
"ReportType" => "1",
"SummaryFrequency" => [
(object) [
"FrequencyType" => "8011",
"SecondsPast" => "32400",
],
],
"Filter" => (object) [
"ClauseType" => "or",
"RuleField" => "",
"RuleOperator" => "",
"RuleValue" => "",
"ClauseChildren" => [
(object) [
"ClauseType" => "",
"RuleField" => "BackupJobDetail.TimeSinceStarted",
"RuleOperator" => "int_lte",
"RuleValue" => "86400",
],
],
],
],
],
];
print_r($x);
Look PHP online code

Related

separate an array into multiple arrays with a separator kay value pair php

$test = [
0 => [
'type' => 'separator',
'data' => 'separator1'
],
1 => [
'type' => 'image',
'data' => 'image1url'
],
3 => [
'type' => 'separator',
'data' => 'separator2'
],
4 => [
'type' => 'video',
'data' => 'video1url'
],
5 => [
'type' => 'image',
'data' => 'image3url'
],
];
I have an array that has multiple arrays in it. I need to separate the array into multiple arrays like the example below.
$array1 = [
0 => [
'type' => 'separator',
'data' => 'separator1'
],
1 => [
'type' => 'image',
'data' => 'image1url'
],
];
$array2 = [
0 => [
'type' => 'separator',
'data' => 'separator2'
],
1 => [
'type' => 'video',
'data' => 'video1url'
],
2 => [
'type' => 'image',
'data' => 'image3url'
],
];
Is there any way to do such thing?
Please consider that the item-count between separators can be changed.
I tried to do it using a foreach but didn't succeed.
The following code:
$test = [
0 => [
'type' => 'separator',
'data' => 'separator1'
],
1 => [
'type' => 'image',
'data' => 'image1url'
],
3 => [
'type' => 'separator',
'data' => 'separator2'
],
4 => [
'type' => 'video',
'data' => 'video1url'
],
5 => [
'type' => 'image',
'data' => 'image3url'
],
6 => [
'type' => 'separator',
'data' => 'separator3'
],
7 => [
'type' => 'video',
'data' => 'video3url'
],
8 => [
'type' => 'image',
'data' => 'image5url'
],
];
$aaResult = [];
$count=-1;
foreach ($test as $subarray) {
if ($subarray['type']=='separator') {
$count++;
$aaResult[$count] = [];
$aaResult[$count][] = $subarray;
}
else {
$aaResult[$count][] = $subarray;
}
}
// if you want separate arrays ($array1, $array2,..) and not $aaResult[0], $aaResult[1],...
$varNamePrefix='array';
for ($i=0;$i<count($aaResult);$i++) {
$varName = $varNamePrefix.($i+1);
$$varName = $aaResult[$i];
}
print_r($array1);
print_r($array2);
print_r($array3);
prints:
Array
(
[0] => Array
(
[type] => separator
[data] => separator1
)
[1] => Array
(
[type] => image
[data] => image1url
)
)
Array
(
[0] => Array
(
[type] => separator
[data] => separator2
)
[1] => Array
(
[type] => video
[data] => video1url
)
[2] => Array
(
[type] => image
[data] => image3url
)
)
Array
(
[0] => Array
(
[type] => separator
[data] => separator3
)
[1] => Array
(
[type] => video
[data] => video3url
)
[2] => Array
(
[type] => image
[data] => image5url
)
)
You can do that using ${} to create dynamic variables like:
${'array' . $counter} = 'your array';
And also check for the presence of ('type' => 'separator') in a foreach, so you can increase the $counter.

PHP Mutli-Dimensional Array Grabbing Item

I have an API which I'm trying to get an ID from, but the output is a mutli-dimensional array and I can't grab just the ID.
This is what the array looks like:
Array ( [{ data] => [ { account_key [ is_owner] => true [ id] => 1 [ name] => test [ display_name] => test [ balance] => 0 [ paid_to_date] => 0 [ updated_at] => 1577724986 [ archived_at] => null [ address1] => [ address2] => [ city] => [ state] => [ postal_code] => [ country_id] => 0 [ work_phone] => [ private_notes] => [ public_notes] => [ last_login] => [ website] => [ industry_id] => 0 [ size_id] => 0 [ is_deleted] => false [ payment_terms] => 30 [ vat_number] => [ id_number] => [ language_id] => 0 [ currency_id] => 0 [ custom_value1] => [ custom_value2] => [ invoice_number_counter] => 1 [ quote_number_counter] => 1 [ task_rate] => 0 [ shipping_address1] => [ shipping_address2] => [ shipping_city] => [ shipping_state] => [ shipping_postal_code] => [ shipping_country_id] => 0 [ show_tasks_in_portal] => true [ send_reminders] => true [ credit_number_counter] => 1 [ custom_messages] => {} [ contacts] => [ { account_key [ is_owner] => true [ id] => 1 [ first_name] => test [ last_name] => test [ email] => me#idontlikespam.com [ contact_key] => mq1dzpkqznfgtqwhdwt9nte1ohmvsju1 [ updated_at] => 1577724986 [ archived_at] => null [ is_primary] => true [ phone] => [ last_login] => [ send_invoice] => true [ custom_value1] => [ custom_value2] => } ] } ] [ meta] => { pagination [ count] => 1 [ per_page] => 15 [ current_page] => 1 [ total_pages] => 1 [ links] => [] } } } )
This is the code I have so far to split it out:
$clients = str_replace('"', "", $clients);
$convert_to_array = explode(',', $clients);
for($i=0; $i < count($convert_to_array ); $i++){
$key_value = explode(':', $convert_to_array [$i]);
$end_array[$key_value [0]] = $key_value [1];
}
print_r($end_array);
foreach ($end_array as $key => $item)
{
echo "[" . $key . "] => " . $item . "<br />";
if ($key = ' id')
{
echo $item;
}
}
It's just the final step I'm missing, it's probably something easy, but I'm still running on a Christmas brain...
New data:
stdClass Object ( [data] => Array ( [0] => stdClass Object ( [account_key] => jvg7qgtw2btrlmpigrq2zpco48eegxvv [is_owner] => 1 [id] => 1 [name] => test [display_name] => test [balance] => 0 [paid_to_date] => 0 [updated_at] => 1577724986 [archived_at] => [address1] => [address2] => [city] => [state] => [postal_code] => [country_id] => 0 [work_phone] => [private_notes] => [public_notes] => [last_login] => [website] => [industry_id] => 0 [size_id] => 0 [is_deleted] => [payment_terms] => 30 [vat_number] => [id_number] => [language_id] => 0 [currency_id] => 0 [custom_value1] => [custom_value2] => [invoice_number_counter] => 1 [quote_number_counter] => 1 [task_rate] => 0 [shipping_address1] => [shipping_address2] => [shipping_city] => [shipping_state] => [shipping_postal_code] => [shipping_country_id] => 0 [show_tasks_in_portal] => 1 [send_reminders] => 1 [credit_number_counter] => 1 [custom_messages] => {} [contacts] => Array ( [0] => stdClass Object ( [account_key] => jvg7qgtw2btrlmpigrq2zpco48eegxvv [is_owner] => 1 [id] => 1 [first_name] => test [last_name] => test [email] => ema#il.co.uk [contact_key] => mq1dzpkqznfgtqwhdwt9nte1ohmvsju1 [updated_at] => 1577724986 [archived_at] => [is_primary] => 1 [phone] => [last_login] => [send_invoice] => 1 [custom_value1] => [custom_value2] => ) ) ) ) [meta] => stdClass Object ( [pagination] => stdClass Object ( [total] => 1 [count] => 1 [per_page] => 15 [current_page] => 1 [total_pages] => 1 [links] => Array ( ) ) ) )
In Array you can access to values by [index].
In stdObject you can access to properties by -> because it is object.
So
stdClass Object ( [data] => Array ( [0] => stdClass Object ( [account_key]
Is
Object->(property data has value array)[index 0 in array and is object]->(property account_key)
On your data you need this.
foreach ($end_array->data as $key => $item)
{
echo $item->id . "<br />";
}
or if you know if data can have always one item you can access with this shortcut
echo $end_array->data[0]->id;

ElasticSearch - How to return data from elastic search with not empty value?

I've got a problem with eliminating empty values from a document of one of my index.
$params = [
"scroll" => "30s", // how long between scroll requests. should be small!
"size" => 1,
"index" => $eddIndex,
'type' => $eddIndexType
];
$response = $client->search ( $params );
while ( isset ( $response ['hits']['hits'] ) && count ( $response['hits']['hits'] ) > 0 ) {
$scroll_id = $response ['_scroll_id'];
$response = $client->scroll ( [
"scroll_id" => $scroll_id,
"scroll" => "30s"
] )
;
This will Return
Array
(
[_scroll_id] => cXVlcnlUaGVuRmV0Y2g7NTs0NTY0NDM6di1Bd2x4X0ZSaTJ5cnpVUkFHb3FRdzs0NTY0NDQ6di1Bd2x4X0ZSaTJ5cnpVUkFHb3FRdzs0NTY0NDY6di1Bd2x4X0ZSaTJ5cnpVUkFHb3FRdzs0NTY0NDc6di1Bd2x4X0ZSaTJ5cnpVUkFHb3FRdzs0NTY0NDU6di1Bd2x4X0ZSaTJ5cnpVUkFHb3FRdzswOw==
[took] => 12
[timed_out] =>
[_shards] => Array
(
[total] => 5
[successful] => 5
[failed] => 0
)
[hits] => Array
(
[total] => 378887
[max_score] => 1
[hits] => Array
(
[0] => Array
(
[_index] => index
[_type] => edd
[_id] => 13038
[_score] => 1
[_source] => Array
(
[reason] =>
[booking_date] => 2013-05-03T18:30:00.000Z
[booking_location] => ABC
[scan_edd] =>
[call_status] => Call
[patient_name] => ABCD
[#version] => 1
[effective_edd] =>
[id] => 13038
[email] => xxxxxxxxx#gmail.com
[last_known_edd] =>
[booking_amount] => 8000
[address] => xxxxxxxxxxxxxxxxx
[eda] => 2013-09-09T18:30:00.000Z
[edd] =>
[mpi] => xxxxxxx
[mobile] => xxxxxxx
[statuss] => Open Payment
[tags] => Array
(
[0] => edd
)
[last_consult_by] => Dr. XXXX [site] => BLR
[#timestamp] => 2018-07-06T06:30:39.040Z
[patient_id] => 75220
[last_consult_on] => 2014-02-28T18:30:00.000Z
[ip_booking] => XYX Package
[is_converted] => 0
)
)
)
)
)
If you look at my output, There is a field [effective_edd] returning empty.
I wanted to return data with [effective_edd] not empty.
I'm referring to the below document https://packagist.org/packages/elasticsearch/elasticsearch
You need to add a query that checks for the existence of the field to your scroll request:
$params = [
"scroll" => "30s", // how long between scroll requests. should be small!
"size" => 1,
"index" => $eddIndex,
'type' => $eddIndexType,
'body' => [
'query' => [
'exists' => [
'field' => 'effective_edd'
]
]
]
];

Traversing an nested array and transform some values

I'm looking for a clean solution to transform a nested array.
Here is what I'm trying to achieve...
Original array:
$map = array(
'name' => 'super test',
'machine_name' => 'super_test',
'class' => 'openlayers_map_map',
'options' => array(
'width' => 'auto',
'height' => '300px',
'contextualLinks' => 1,
'provideBlock' => 1,
'view' => array(
'center' => array(
'lat' => '0',
'lon' => '0',
),
'rotation' => '0',
'zoom' => '2',
),
'layers' => array(
'0' => array(
'name' => 'Ma super layer',
'machine_name' => 'plouf',
'class' => 'openlayers_layer_tile',
'options' => array(
'source' => array(
'name' => 'Ma super layer',
'machine_name' => 'plouf',
'class' => 'openlayers_source_osm'
),
'param1' => 'ca roule'
)
),
),
'controls' => array(
'control_mouseposition',
'0' => array(
'name' => 'Control attribution',
'machine_name' => 'openlayers_control_attribution',
'class' => 'openlayers_control_attribution',
'options' => array(
'collapsible' => 1
)
),
'control_rotate',
'control_zoom',
),
'interactions' => array(
'interaction_doubleclickzoom',
'interaction_dragpan',
'interaction_dragrotateandzoom',
'interaction_mousewheelzoom',
),
)
);
Final array:
$map = array(
'name' => 'super test',
'machine_name' => 'super_test',
'class' => 'openlayers_map_map',
'options' => array(
'width' => 'auto',
'height' => '300px',
'contextualLinks' => 1,
'provideBlock' => 1,
'view' => array(
'center' => array(
'lat' => '0',
'lon' => '0',
),
'rotation' => '0',
'zoom' => '2',
),
'layers' => array(
'0' => (object) openlayers_layer_tile
'name' => 'Ma super layer',
'machine_name' => 'plouf',
'class' => 'openlayers_layer_tile',
'options' => array(
'source' => (object) openlayers_source_osm
'name' => 'Ma super layer',
'machine_name' => 'plouf',
'class' => 'openlayers_source_osm'
),
'param1' => 'ca roule'
)
),
),
'controls' => array(
'control_mouseposition',
'0' => (object) openlayers_control_attribution
'name' => 'Control attribution',
'machine_name' => 'openlayers_control_attribution',
'class' => 'openlayers_control_attribution',
'options' => array(
'collapsible' => 1
)
),
'control_rotate',
'control_zoom',
),
'interactions' => array(
'interaction_doubleclickzoom',
'interaction_dragpan',
'interaction_dragrotateandzoom',
'interaction_mousewheelzoom',
),
)
);
Basically, I need to traverse the array, find all children with the 'class' key and transform them into objects of the same name.
If you don't have the classes ready to be instantiated, this code will create anonymous objects instead. (The class name still being present as a property.)
function class_to_object (&$arr) {
if (is_array($arr)) {
foreach ($arr as $key => &$val) {
class_to_object($val);
}
if (isset($arr['class'])) {
$arr = (object) $arr;
}
}
}
class_to_object($map);
Result :
(Notice that the first array is turned into an object, since it contains the field "class" too. I guess you can tweak the function easily enough if you don't want that behavior)
stdClass Object
(
[name] => super test
[machine_name] => super_test
[class] => openlayers_map_map
[options] => Array
(
[width] => auto
[height] => 300px
[contextualLinks] => 1
[provideBlock] => 1
[view] => Array
(
[center] => Array
(
[lat] => 0
[lon] => 0
)
[rotation] => 0
[zoom] => 2
)
[layers] => Array
(
[0] => stdClass Object
(
[name] => Ma super layer
[machine_name] => plouf
[class] => openlayers_layer_tile
[options] => Array
(
[source] => stdClass Object
(
[name] => Ma super layer
[machine_name] => plouf
[class] => openlayers_source_osm
)
[param1] => ca roule
)
)
)
[controls] => Array
(
[0] => stdClass Object
(
[name] => Control attribution
[machine_name] => openlayers_control_attribution
[class] => openlayers_control_attribution
[options] => Array
(
[collapsible] => 1
)
)
[1] => control_rotate
[2] => control_zoom
)
[interactions] => Array
(
[0] => interaction_doubleclickzoom
[1] => interaction_dragpan
[2] => interaction_dragrotateandzoom
[3] => interaction_mousewheelzoom
)
)
)
This totally untested recursive function may get you on the right track:
function recursive_hydrate_array($arr)
{
if(!is_array($arr) || !isset($arr["class"]))
{
throw new Exception("Argument is not an array or does not have a 'class' key.");
}
$klass = $arr["class"];
unset($arr["class"]);
$obj = new $klass();
foreach($arr as $k => $v)
{
if(is_array($arr[$k]) && isset($arr[$k]["class"]))
{
$obj->{$k} = recursive_hydrate_array($arr[$k]);
}
else
{
$obj->{$k} = $arr[$k];
}
}
return $obj;
}
Note that I am making three assumptions here:
The classes in question already exist.
Each class can be instantiated without passing any parameters to its constructor.
All relevant properties of each class are public and can be set from outside of the class.

Removing unnecessary nested index in array (generated by Cake PHP)

The following question can either be solved by probably changing my use of the find method in Cake PHP OR using some PHP function. I would prefer to solve it using Cake but it doesn't matter too much. I have any array like this:
Array
(
[0] => Array
(
[Model] => Array
(
[id] => 14
[foo] => bar
)
)
[1] => Array
(
[Model] => Array
(
[id] => 15
[foo] => something
)
) .............
I just want to remove the Model index and just use the numeric one. The following function generated this array:
$arr = $this->Model->find('all', array('contain' => false ) );
I probably need to change the 'contain' part of the call. Basically, in addition to the data that appears under each Model index, I also have a second and third model and the contain = false just restricts Cake from getting data from the current model (Model).
If I understand your question correctly, I think CakePHP's Set::combine function will help http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::combine :
$result = Set::combine($your_array, '{n}.Model.id', '{n}.Model.data');
This will result in:
Array
(
[14] => Array
(
[foo] => bar
)
[15] => Array
(
[foo] => something
)
)
you have to write your own piece of code to modify your array , here is a function that will do what you want (you can improve it)
function reformArray($array,$modelName)
{
foreach($arr as $key => $value)
{
$newArr[] = $arr[$key][$modelName];
}
return $newArr;
}
you have to pass your array and the Model Name to this function and will return you the result
$a = array(
array(
'User' => array(
'id' => 2,
'group_id' => 1,
'Data' => array(
'user' => 'mariano.iglesias',
'name' => 'Mariano Iglesias'
)
)
),
array(
'User' => array(
'id' => 14,
'group_id' => 2,
'Data' => array(
'user' => 'phpnut',
'name' => 'Larry E. Masters'
)
)
),
array(
'User' => array(
'id' => 25,
'group_id' => 1,
'Data' => array(
'user' => 'gwoo',
'name' => 'The Gwoo'
)
)
)
);
RUN THIS TO REMOVE THE MODEL NAME USER
Set::extract($a, '{n}.User');
WILL RETURN THIS
$a = array(
array(
'id' => 2,
'group_id' => 1,
'Data' => array(
'user' => 'mariano.iglesias',
'name' => 'Mariano Iglesias'
)
),
array(
'id' => 14,
'group_id' => 2,
'Data' => array(
'user' => 'phpnut',
'name' => 'Larry E. Masters'
)
),
array(
'id' => 25,
'group_id' => 1,
'Data' => array(
'user' => 'gwoo',
'name' => 'The Gwoo'
)
)
);
In CakePHP 2:
$data = $this->Model->find('all');
$data = Set::extract('/Model/.', $data );
You can achieve this result by foreach also
foreach ($data as $k => &$t) {
$t = $t['Model']
}
It will be much easier with Object. Change the Array with Object.
Actually I had faced the same problem with nested array And I found the solution with Set::map($array);
If you don't want the model_name as nested array, You can prefer this solution.
$data = array(
array(
"IndexedPage" => array(
"id" => 1,
"url" => 'http://blah.com/',
'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
'get_vars' => '',
'redirect' => '',
'created' => "1195055503",
'updated' => "1195055503",
)
),
array(
"IndexedPage" => array(
"id" => 2,
"url" => 'http://blah.com/',
'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
'get_vars' => '',
'redirect' => '',
'created' => "1195055503",
'updated' => "1195055503",
),
)
);
$mapped = Set::map($data);
/* $mapped now looks like: */
Array
(
[0] => stdClass Object
(
[_name_] => IndexedPage
[id] => 1
[url] => http://blah.com/
[hash] => 68a9f053b19526d08e36c6a9ad150737933816a5
[get_vars] =>
[redirect] =>
[created] => 1195055503
[updated] => 1195055503
)
[1] => stdClass Object
(
[_name_] => IndexedPage
[id] => 2
[url] => http://blah.com/
[hash] => 68a9f053b19526d08e36c6a9ad150737933816a5
[get_vars] =>
[redirect] =>
[created] => 1195055503
[updated] => 1195055503
)
)
you may do this :
$tmp = $this->Model->find('all', array('contain' => false ) );
$arr = $tmp['ModelName'];

Categories