I have code like this, that initialize config
$this->config = array(
'users' => array(
array('name' => 'admin',
'password' => $password
)
),
'tokens' => array(),
'sessions' => array(),
);
that I'm saving to a file using json_encode($this->config) and later I load it using
json_decode(file_get_contents('file.json'));
it create nested objects, I would like to have this nested object when I initialize and the config, is there a way to create this nested object other then this?
$this->config = json_decode(json_encode($this->config));
You can alternatively use this function
<?php
function arrayToObject($array) {
if(!is_array($array)) {
return $array;
}
$object = new stdClass();
if (is_array($array) && count($array) > 0) {
foreach ($array as $name=>$value) {
$name = strtolower(trim($name));
if (!empty($name)) {
$object->$name = arrayToObject($value);
}
}
return $object;
}
else {
return FALSE;
}
}
?>
I decide to use this function instead
function object($array) {
$object = new stdClass();
foreach ($array as $k => $v) {
$object->$k = $v;
}
return $object;
}
and explicitly call it for assoc arrays
$this->config = object(array(
'users' => array(
object(array(
'name' => 'admin',
'password' => $password
))
),
'tokens' => array(),
'sessions' => array(),
));
EDIT recursive code
function is_assoc($array) {
if (!is_array($array)) {
return false;
} else {
$keys = array_keys($array);
return !is_numeric($keys[0]);
}
}
function object($array) {
if (is_assoc($array)) {
$object = new stdClass();
foreach ($array as $k => $v) {
$object->$k = object($v);
}
return $object;
} else {
return $array;
}
}
Related
I want to transform an array of resources that can have an infinity of children to a simple array like below. I just want to keep the information of the parent, if there is a parent. In my context, a parent is the array just above the child array.
I have this array (bigger in reality with a lof of children), but each children may have an infinity of arrays children:
$array = array (
0 =>
array (
'#id' => 'Authorization',
'#sortOrder' => '1',
'resource' =>
array (
'#id' => 'Authorization2',
'#title' => 'Authorization2',
),
),
);
And I would like to get this, recursively :
$resources = [
0 => [
'parent' => null,
'resource' => 'Authorization'],
1 => [
'Authorization' => 'Authorization',
'resource' => 'Authorization2']
];
I tried this and I get every single resource but I can't get parents for resources that has one:
public function array_values_recursive($array) {
$flat = array();
foreach($array as $key => $value) {
if (is_array($value)) {
$flat = array_merge($flat, $this->array_values_recursive($value));
}
else {
if($key === '#id') {
$flat[]['value'] = $value;
}
}
}
return $flat;
}
That did the job for me, thanks #Sammitch for the idea.
public function array_values_recursive($array, $parent = null) {
$flat = array();
$i = 0;
foreach($array as $key => $value) {
if (is_array($value)) {
//we create a new parent
if(array_key_exists('#id',$array)){
$flat = array_merge($flat, $this->array_values_recursive($value, $array['#id']));
}
//we keep the last parent known
else{
$flat = array_merge($flat, $this->array_values_recursive($value, $parent));
}
}
else {
if($key === '#id') {
if($parent){
$flat[$i]['value'] = $value;
$flat[$i]['parent'] = $parent;
}
else{
$flat[$i]['value'] = $value;
}
$i++;
}
}
}
return $flat;
}
what I want to do is to print the data with foreach, but whatever I have done, it prints the last element and not the other one,
where am i going wrong?
I want "PartyIdentification" to return up to each element.
I don't understand if I'm making a mistake in get and sets. Is there a short solution? I want to print more than one property.
the result of my output
i want to do
$aa = array(
0 => ['ID' => ['val' => '4000068418', 'attrs' => ['schemeID="VKN"']]],
1 => ['ID' => ['val' => '12345678901', 'attrs' => ['schemeID="TICARETSICILNO"']]],
2 => ['ID' => ['val' => '132546555', 'attrs' => ['schemeID="MERSISNO"']]]
);
$invoice_AccountSupplierParty_Party = new \Pvs\eFaturaUBL\Party();
$invoice_AccountSupplierParty_Party->PartyIdentification = InvoiceBuilder::getasd($aa);
public static function getasd(array $data)
{
$asd = new Olusturma();
$date = array();
foreach ($data as $datum) {
$asd->getID($data);
}
return $asd->getResult();
}
namespace App\Support\Invoice;
class Olusturma
{
public $contactDetails = array();
public function __construct()
{
$this->contactDetails = new \Erkan\eFaturaUBL\PartyIdentification();
}
public function setOlusturma(): Olusturma
{
return $this;
}
public function getID($data)
{
foreach ($data as $row => $innerArray) {
foreach ($innerArray as $innerRow => $value) {
$this->setID($value);
}
}
return $this;
}
public function setID($data): Olusturma
{
$this->contactDetails->ID = $data;
return $this;
}
public function getResult(): \Erkan\eFaturaUBL\PartyIdentification
{
return $this->contactDetails;
}
I want to force $_SESSION behave like object using custom session handler. Code as follows,
$_SESSION = [
'user' => [
'id' => '7',
'name' => 'James',
'lastname' => 'Bond',
'login' => '007',
'pass' => 'qwe7fyqw9mhev8qhr',
],
'kill' => [
'Mr_Muscle' => [
'status' => 'alive',
],
'Joe_Black' => [
'status' => 'dead',
]
],
];
$session = new Session();
echo $session->user->name;
$session->kill->Mr_muscle->status = 'dead';
$session->save();
I did it almost but I get warning:
Warning: Creating default object from empty value in /var/www/project/mvc/bootstrap.php on line 80
when I'm trying to create new value, in this case:
$session->kill->Dr_Quinn->status = 'dead';
Value will be created but I don't want to hide this warning, I want to do away with it.
class Session
{
public function __construct()
{
foreach ($_SESSION as $key => $value)
{
$this->{$key} = $value;
}
}
public function __set($name, $value)
{
$this->$name = $this->arrayToObject($value);
}
private function arrayToObject($array) {
if (!is_array($array)) {
return $array;
}
$object = new stdClass();
if (is_array($array) && count($array) > 0) {
foreach ($array as $name=>$value) {
$name = strtolower(trim($name));
if (!empty($name)) {
$object->$name = $this->arrayToObject($value);
}
}
return $object;
}
else {
return FALSE;
}
}
public function save()
{
$_SESSION = json_decode(json_encode(get_object_vars($this)), true);
}
How to fix it?
Just do
if (!isset($session->kill->Mr_muscle))
$session->kill->Mr_muscle = new stdClass();
$session->kill->Mr_muscle->status = 'dead';
to avoid this warning.
I have a multidimensional array that i would like to create into an object so I can then output both as xml and json.
I am having difficulty getting my head around how to do this recursively. I have looked at many multidimensional posts I can find on here but am still stuck.
What am I doing wrong?
class Dataset
{
public $name;
public $attr = array();
public $children = array();
function __construct($name){
$this->name = $name;
}
function addAttr($attr){
$this->attr[] = $attr;
}
function addChildren($children){
$this->children[] = $children;
}
}
$jazzy = Array(
name => 'aaa',
attr => Array(
id => 123
),
children => Array(
Array(
name => 'name',
attr => Array(),
children => Array(
'www'
),
),
Array(
name => 'websites',
attr => Array(),
children => Array(
Array(
name => 'website',
attr => Array(
id => 456,
class => 'boom'
),
children => Array(
Array(
name => 'url',
attr => Array(),
children => Array(
'www.test.com'
)
)
)
),
Array(
name => 'website',
attr => Array(
id => 123,
class => "boom"
),
children => Array(
Array(
name => 'url',
attr => Array(),
children => Array(
'www.example.com'
)
)
)
)
)
)
)
);
I am looking to create this output
<aaa id="123">
<name>www</name>
<websites>
<website id='456' class="boom">
<url>www.test.com</url>
</website>
<website id='123 class="boom">
<url>www.example.com</url>
</website>
</websites>
</aaa>
My code
function arrayToDataset($array, $node){
foreach ($array as $key => $value) {
$name = $array['name'];
$attr = $array['attr'];
$children = $array['children'];
if($key == "name"){
$name = $value;
$node->addName($name);
}
elseif($key == "attr"){
$attr = $value;
$node->addAttr($attr);
}
elseif($key == "children")
{
$children = $value;
$newNode = new Dataset();
foreach($children as $k => $v)
{
$newNode = $node->addChildren($v);
}
return arrayToDataset($children, $newNode);
}
}
}
$node = new Dataset();
$thing = arrayToDataset($jazzy, $node);
print_r($thing);
This may be a way to parse the data into your DataSet object, which you could then use to output in some other format like xml or json. There may be easier ways to do that though...
class Dataset
{
public $name;
public $attr = array();
public $children = array();
public $url = array();
function __construct($name)
{
$this->name = $name;
}
function addAttr($attr, $value)
{
$this->attr[$attr] = $value;
}
function addChild(DataSet $child)
{
$this->children[] = $child;
}
function addUrl($url) {
$this->url[] = $url;
}
static function makeNode($array)
{
// $array needs to have the required elements
$node = new DataSet($array['name']);
if (isset($array['attr'])) {
foreach ($array['attr'] as $k => $v) {
if (is_scalar($v)) {
$node->addAttr($k, $v);
}
}
}
if (isset($array['children']) && is_array($array['children'])) {
foreach ($array['children'] as $c) {
if(is_scalar($c)) {
$node->addUrl($c);
} else {
$node->addChild(self::makeNode($c));
}
}
}
return $node;
}
}
print_r(Dataset::makeNode($jazzy));
I've realized I need to stop banging my head and ask for help...
I have the following array:
$permissionTypes = array(
'system' => array(
'view' => 'View system settings.',
'manage' => 'Manage system settings.'
),
'users' => array(
'all' => array(
'view' => 'View all users.',
'manage' => 'Manage all users.'
)
),
'associations' => array(
'generalInformation' => array(
'all' => array(
'view' => 'View general information of all associations.',
'manage' => 'Manage general information of all associations.'
),
'own' => array(
'view' => 'View general information of the association the user is a member of.',
'manage' => 'Manage general information of the association the user is a member of.'
)
)
));
I'm trying to collapse / cascade the keys into a one-dimension array like so:
array(
'system_view',
'system_manage',
'users_all_view',
'users_all_manage',
'associations_generalInformation_all_view',
'associations_generalInformation_all_manage',
'associations_generalInformation_own_view',
'associations_generalInformation_own_manage'
)
I could use nested loops, but the array will be an undefined number of dimensions.
This is the closest I've gotten:
public function iterateKeys(array $array, $joiner, $prepend = NULL) {
if (!isset($formattedArray)) { $formattedArray = array(); }
foreach ($array as $key => $value) {
if(is_array($value)) {
array_push($formattedArray, $joiner . $this->iterateKeys($value, $joiner, $key));
} else {
$formattedArray = $prepend . $joiner . $key;
}
}
return $formattedArray;
}
Any ideas?
I think this should do it:
public function iterateKeys(array $array, $joiner, $prepend = NULL) {
if (!isset($formattedArray)) {
$formattedArray = array();
}
foreach ($array as $key => $value) {
if(is_array($value)) {
$formattedArray = array_merge($formattedArray, $this->iterateKeys($value, $joiner, $prepend . $joiner . $key));
} else {
$formattedArray[] = $prepend . $joiner . $key;
}
}
return $formattedArray;
}
Since the recursive call returns an array, you need to use array_merge to combine it with what you currently have. And for the non-array case, you need to push the new string onto the array, not replace the array with a string.
try this:
function flattern(&$inputArray, $tmp = null, $name = '')
{
if ($tmp === null) {
$tmp = $inputArray;
}
foreach($tmp as $index => $value) {
if (is_array($value)) {
flattern($inputArray, $value, $name.'_'.$index);
if (isset($inputArray[$index])) {
unset($inputArray[$index]);
}
} else {
$inputArray[$name.'_'.$index] = $value;
}
}
return $inputArray;
}
var_dump(flattern($permissionTypes));
function flattenWithKeys(array $array, array $path = []) {
$result = [];
foreach ($array as $key => $value) {
$currentPath = array_merge($path, [$key]);
if (is_array($value)) {
$result = array_merge($result, flattenWithKeys($value, $currentPath));
} else {
$result[join('_', $currentPath)] = $value;
}
}
return $result;
}
$flattened = flattenWithKeys($permissionTypes);
Working fine for me.
function array_key_append($source_array, $return_array = array(), $last_key = '', $append_with = "#")
{
if(is_array($source_array))
{
foreach($source_array as $k => $v)
{
$new_key = $k;
if(!empty($last_key))
{
$new_key = $last_key . $append_with . $k;
}
if(is_array($v))
{
$return_array = array_key_append($v, $return_array, $new_key, $append_with);
} else {
$return_array[$new_key] = $v;
}
}
}
return $return_array;
}
$StandardContactRequestDataforALL = array_key_append($StandardContactRequestDataforALL, $return_array = array(), $last_key = '', $append_with = "#");