How looks good structure of construct for creating multidimensial array - php

I am trying to create constructor which creates an multidimensional array. My result should be like this:-
Checkout my array $result_array
For now I have error: Illegal offset type. Note that I have als use __toString() becose I work on xml data.
class Property {
public $xmlClass;
public $elemClass = '';
public $first_array = array();
public $result_array = array();
public $data = '';
public $data2 = '';
public function __construct($xml, $elem) {
$this->xmlClass = $xml;
$this->elemClass = $elem;
foreach ($xml->xpath('//*[#baza]') as $val) {
$this->first_array[] = $val;
foreach ($val->ksiazka as $value) {
$data = $value->$elem->__toString();
$this->result_array[$this->first_array][] = $data;
}
}
}
public function getResult() {
return $this->result_array;
}
}
$result_autor = new Property($xml, 'autor');
$autor = $result_autor->getResult();

You need to change your two foreach() like below:-
foreach($xml->xpath('//*[#baza]') as $val) {
//$this->first_array[] = $val; not needed
foreach($val->ksiazka as $key=> $value){ //check $key here
$data = $value->$elem->__toString();
$this->result_array[$key][] = $data; // add $key hear
}
}
If the above not worked then check this too:-
foreach($xml->xpath('//*[#baza]') as $key=> $val) { //check $key here
//$this->first_array[] = $val; not needed
foreach($val->ksiazka as $value){
$data = $value->$elem->__toString();
$this->result_array[$key][] = $data; // add $key hear
}
}

Related

how to acces values from array in laravel

This is my addToCart method in which I am adding the courses to user_cart column in users table.
public function addToCart($id){
$course = Course::findOrfail($id);
$user =Auth::user();
$cart_array = array();
$cart = $user->user_cart;
if ($cart == '') {
array_push($cart_array, array('id' => $course->id));
// print_r($cart_array);
} else {
$founder = false;
$cart_array = json_decode($cart, true);
for ($i = 0; $i < count($cart_array); $i++) {
$cart_for_eacch_course = $cart_array[$i];
if ($cart_for_eacch_course['id'] == $course->id) {
$founder = true;
}
}
if (!$founder) {
array_push($cart_array, array('id' => $course->id));
}
}
$data['id'] = json_encode($cart_array);
$update = User::where('id',$user->id)->update(['user_cart'=> $cart_array]);
return redirect()->back();
}
And this is my showcart method in which I am taking the courses from users table user_cart column array.
public function showcart(){
$user = Auth::user();
$array = $user->user_cart;
print_r($array);
return view('frontend.my_cart', compact('academic','nonacademic','instructor','coc','my_cart'));
}
And when I am displaying it I am getting the output as follows:
[{"id":84},{"id":86}]
Now can you tell me that how to loop them so I can get the courses? I tried by using a foreach loop for $array but it shows me the error of invalid argument supplied for foreach()
Looks like you are building the array into a JSON or string field within your database on the User object. The resulting array appears to be stored as a JSON string, so decode and then loop:
$array = json_decode( $user->user_cart, true );
foreach($array as $key => $val){
dump $key;
dump $val;
}

Yii2 Update Parent Child

I have a structure table like this
I want to change record data field goid = 1, but I as you can see my code bellow, there's limit looping. Is there a better way to do it?
public function actionShareGoid($folder)
{
$one = DokumenFolder::findOne($folder);
$one->goid = '1';
$one->update(false);
$models_1 = DokumenFolder::find()->where(['parent_id'=>$one->id])->all();
foreach ($models_1 as $key_1 => $model_1) {
$model_1->goid = '1';
$model_1->update(false);
$models_2 = DokumenFolder::find()->where(['parent_id'=>$model_1->id])->all();
foreach ($models_2 as $key_2 => $model_2) {
$model_2->goid = '1';
$model_2->update(false);
$models_3 = DokumenFolder::find()->where(['parent_id'=>$model_2->id])->all();
foreach ($models_3 as $key_3 => $model_3) {
$model_3->goid = '1';
$model_3->update(false);
$models_4 = DokumenFolder::find()->where(['parent_id'=>$model_3->id])->all();
foreach ($models_4 as $key_4 => $model_4) {
$model_4->goid = '1';
$model_4->update(false);
}
}
}
}
return $this->redirect(Yii::$app->request->referrer);
}
Thanks to someone, I got the answer. ^_^
So here it is...
public function folderParent($id)
{
$models = DokumenFolder::find()->where(['parent_id'=>$id])->all();
foreach ($models as $key => $model) {
$model->goid = '1';
$model->update(false);
}
}
public function actionShareGoid($id)
{
$models = DokumenFolder::find()->where(['parent_id'=>$id])->all();
foreach ($models as $key => $model) {
$this->folderParent($model->id);
}
return $this->redirect(Yii::$app->request->referrer);
}

copy dynamic value to array in php

Can we copy all the dynamic values to array for eg:
I have a function like this
<?php
$list_a = array(); //defining an array
$list_b = array();
$list_c = array();
addText($a,$b,$c)
{
$list_a[] = $a;
$list_b[] = $b;
$list_c[] = $c;
}
I will pass different values to addText() function after that I have to access those inserted value using foreach from another function.
How can we do that .
Just define your php variable as global.
Eg. global $list_a,$list_b,$list_c;
When you are using that variable in any function then first declare above variables in that function.
Eg:
addText($a,$b,$c)
{
global $list_a,$list_b,$list_c;
$list_a[] = $a;
$list_b[] = $b;
$list_c[] = $c;
}
To accomplish this you have to use concept of global variable
Try this:
$list_a = array(); //defining an array
$list_b = array();
$list_c = array();
function addText($a,$b,$c)
{
global $list_a, $list_b, $list_c;
array_push($list_a,$a);
array_push($list_b,$b);
array_push($list_c,$c);
}
addText('12','23',12);
echo '<pre>';
print_r($list_a);
print_r($list_b);
print_r($list_c);
This would work but it is bad design. See here why.
<?php
$list_a = array(); //defining an array
$list_b = array();
$list_c = array();
function addText($a,$b,$c)
{
global $list_a, $list_b, $list_c;
$list_a[] = $a;
$list_b[] = $b;
$list_c[] = $c;
}
function foreachThem()
{
global $list_a, $list_b, $list_c;
foreach($list_a as $item)
{
//...
}
foreach($list_b as $item)
{
//...
}
foreach($list_c as $item)
{
//...
}
}
A better way would be saving them in a parent array (this is optional but it reduces the amount of parameters and therefor the amount of code) and passing it as reference. See here for info on passing by reference.
<?php
$theLists = array(
"a" => array(),
"b" => array(),
"c" => array()
);
// note the '&'
function addText(&$lists, $a,$b,$c)
{
$lists["a"][] = $a;
$lists["b"][] = $b;
$lists["c"][] = $c;
}
// '&' is not needed here
function foreachThem($lists)
{
foreach($lists["a"] as $item)
{
//...
}
foreach($lists["b"] as $item)
{
//...
}
foreach($lists["c"] as $item)
{
//...
}
}
Try this,
<?php
$list_a = array(); //defining an array
$list_b = array();
$list_c = array();
addText($a,$b,$c)
{
$list_a[] = $a;
$list_b[] = $b;
$list_c[] = $c;
}
public function 'function_name'($list_a, $list_b, $list_c) {
foreach ($list_a as $list) {
echo $list;
}
}

Decoding mixture of array and stdObject to Database

I am trying to decode a collection of json files to a mysql database and return the decoded values to a datatable for presentation. I have one table called ec2_instances, and want to send to that table an array of values which are located at cfi configuration which works fine. but have now added a new column called aws account id which is on object rather than an array I have updated the model to include the new column but I am struggling
<?php
function from_camel_case($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$ret = $matches[0];
foreach ($ret as &$match)
{
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
}
return implode('_', $ret);
}
$resource_types = array();
$resource_types['AWS::EC2::Instance'] = 'EC2Instance';
$resource_types['AWS::EC2::NetworkInterface'] = 'EC2NetworkInterface';
$resource_types['AWS::EC2::VPC'] = 'VPC';
$resource_types['AWS::EC2::Volume'] = 'Volume';
$resource_types['AWS::EC2::SecurityGroup'] = 'EC2SecurityGroup';
$resource_types['AWS::EC2::Subnet'] = 'Subnet';
$resource_types['AWS::EC2::RouteTable'] = 'RouteTable';
$resource_types['AWS::EC2::EIP'] = 'EIP';
$resource_types['AWS::EC2::NetworkAcl'] = 'NetworkAcl';
$resource_types['AWS::EC2::InternetGateway'] = 'InternetGateway';
$accounts = DB::table('aws_account')->get();
$account_id = array($accounts);
$account_id_exists = array_add($account_id, 'key', 'value');
foreach(glob('../app/views/*.json') as $filename)
{
//echo $filename;
$data = file_get_contents($filename);
if($data!=null)
{
$decoded=json_decode($data,true);
if(isset($decoded["Message"]))
{
//echo "found message<br>";
$message= json_decode($decoded["Message"]);
if(isset($message->configurationItem))
{
// echo"found cfi<br>";
$insert_array = array();
$cfi = $message->configurationItem;
switch ($cfi->configurationItemStatus)
{
case "ResourceDiscovered":
//echo"found Resource Discovered<br>";
if (array_key_exists($cfi->resourceType,$resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
foreach ($cfi->configuration as $key => $value)
{
if (in_array($key,$resource->fields))
{
$insert_array[from_camel_case($key)] = $value;
}
}
if (array_key_exists($cfi->awsAccountId,$resource_types))
{
$resource = new $resource_types[$cfi->awsAccountId];
foreach ($cfi->awsAccountId as $key => $value)
{
if (in_array($key,$resource->fields))
{
$insert_array[from_camel_case($key)] = $value;
}
}
$resource->populate($insert_array);
if (!$resource->checkExists())
{
$resource->save();

Split an array into sub arrays

I would like to split an array:
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
based on the color attribute of each item, and fill corresponding sub arrays
$a = array("green", "yellow", "blue");
function isGreen($var){
return($var->color == "green");
}
$greens = array_filter($o, "isGreen");
$yellows = array_filter($o, "isYellow");
// and all possible categories in $a..
my $a has a length > 20, and could increase more, so I need a general way instead of writing functions by hand
There doesn't seem to exist a function array_split to generate all filtered arrays
or else I need a sort of lambda function maybe
You could do something like:
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$greens = array_filter($o, function($item) {
if ($item->color == 'green') {
return true;
}
return false;
});
Or if you want to create something really generic you could do something like the following:
function filterArray($array, $type, $value)
{
$result = array();
foreach($array as $item) {
if ($item->{$type} == $value) {
$result[] = $item;
}
}
return $result;
}
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$greens = filterArray($o, 'color', 'green');
$yellows = filterArray($o, 'color', 'yellow');
In my second example you could just pass the array and tell the function what to filter (e.g. color or some other future property) on based on what value.
Note that I have not done any error checking whether properties really exist
I would not go down the road of creating a ton of functions, manually or dynamically.
Here's my idea, and the design could be modified so filters are chainable:
<?php
class ItemsFilter
{
protected $items = array();
public function __construct($items) {
$this->items = $items;
}
public function byColor($color)
{
$items = array();
foreach ($this->items as $item) {
// I don't like this: I would prefer each item was an object and had getColor()
if (empty($item->color) || $item->color != $color)
continue;
$items[] = $item;
}
return $items;
}
}
$items = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$filter = new ItemsFilter($items);
$greens = $filter->byColor('green');
echo '<pre>';
print_r($greens);
echo '</pre>';
If you need more arguments you could use this function:
function splitArray($array, $params) {
$result = array();
foreach ($array as $item) {
$status = true;
foreach ($params as $key => $value) {
if ($item[$key] != $value) {
$status = false;
continue;
}
}
if ($status == true) {
$result[] = $item;
}
}
return $result;
}
$greensAndID1 = splitArray($o, array('color' => 'green', 'id' => 1));

Categories