Add element to array then encode it to json - php

I have this code
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
//print_r($arr);
}
echo json_encode($arr);
what I am trying to do is to add something => false to each record of the array
so lets say I got from the database
array of
title:"aaaaa",
start: "xxxx",
end: "cccc",
I want to add to each one something :false to become like
title:"aaaaa",
start: "xxxx",
end: "cccc",
something,false
for each record
but the problem is when I print using the print_r its fine, but the json_encode print only the last one.

Passing by value vs. by reference
You are passing your $arr by value in your foreach loop. Try to pass it by reference.
This is done by adding a & just before your $arr variable in your loop declaration:
foreach ($data['events'] as &$arr) {
settype($arr,"array");
$arr['something'] = false;
}
echo json_encode($data['events']);
How it works
Passing by value means that your foreach loop instanciates a local copy or your array. All modifications made inside the loop will affect only the local copy.
Passing by reference means that inside your loop, you are working directly on the original array. But be careful when doing that because it can be dangerous. For instance, I don't know what are the consequences of calling setType($arr,"array"); for the rest of your code.

You're not collecting $arr from each iteration of your loop into anything. It looks like you probably want to push $arr onto another array that stores everything, and then JSON encode that new array.
Try this:
$collection = array();
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
array_push($collection, $arr);
}
echo json_encode($collection);

$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as &$arr) {
settype($arr,"array");//This if there is not array
$arr['something'] = false;
}
echo json_encode($data['events']);

Try to make your own json like this
$strJson = '';
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
//Assign value as yours in blow code
$strJson .= '{"title" : "'.$arr.'","start" : "'.$arr.'","end" : "'.$arr.'"},';
}
$strJson1=rtrim($strJson, ",");
$newStr = '['.$strJson1.']';
echo $newStr;

Related

How to get index of array of object without using loop in PHP

I need to get index of from array of objects without using loop as per the key name using PHP. Here I am explaining my code below.
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
$key = array_search('Jack', $arr);
echo $key;exit;
Here my code does not give any output. By using some key name I need the index of that object present inside array and also I dont want to use any loop. I need Is ther any PHP in build method so that I can get the result directly.
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
function myfunction($v){return $v['name'];}
echo array_search('Jack', array_map( 'myfunction', $arr ));
<?php
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
//calling function searchByName
$key = searchByName('Jasck',$arr);
if($key != '-1'){
print_r($arr[$key]);
}else{
echo "No match found";
}
//function to chek if the name is there or not.
function searchByName($name, $array) {
foreach ($array as $key => $val) {
if ($val['name'] == $name) {
return $key;
}
}
return '-1';
}
sandbox

fetching two type of json files with different beginning of structure

I'm processing json file with php with little difference in the beginning of the file ,my problem now is that i built two foreach loops and i am looking for a way to make it one loop.
{"code":0,"rid":"0","data":{"subid":"9174906486819979969","data":{"more":
{"code":0,"rid":"0","data":{"9174906486819979969":{"more":
Now I'm doing like that and it double the code for processing , the rest of the json file is all the same.
foreach($json['data']['data'])
{
}
foreach($json['data'])
{
}
What i need is one foreach loop instead of 2, is that possible?
You can check for the key and if present use it, if not then get the first key:
if(isset($json['data']['data'])) {
$data = $json['data']['data'];
} else {
$data = reset($json['data']); //or current()
}
Or shorter:
$data = $json['data']['data'] ?? reset($json['data']);
Then:
foreach($data as $values) {
//code
}
Another option would be to loop and check for an array, depending on the structure you have:
foreach($json['data'] as $values) {
if(is_array($values)) {
foreach($values as $v) {
//code
}
}

Laravel Input::old is an array as a string

In my form im outputting some json or a string of data that is an array from Input::old('tags') the problem I'm having is being able to test it and see if it is json and if it is do a foreach loop and put the tag attribute is an array then implode the array and output it in an input field.
[{"id":112,"tag":"corrupti","tagFriendly":"corrupti","created_at":"2015-07-20 00:05:28","updated_at":"2015-07-20 00:05:28","pivot":{"question_id":60,"tag_id":112,"created_at":"2015-07-20 00:05:28","updated_at":"2015-07-20 00:05:28"}},{"id":9,"tag":"placeat","tagFriendly":"placeat","created_at":"2015-07-20 00:05:23","updated_at":"2015-07-20 00:05:23","pivot":{"question_id":60,"tag_id":9,"created_at":"2015-07-20 00:05:28","updated_at":"2015-07-20 00:05:28"}}]
So my output should look like this
'corrupti, placeat, etc...'
Could someone help me get the desired result following the steps I just outlined
This code doesn't work but it's what I kinda need to happen. is_array is always false
<?php
$tags = Input::old('tags');
if(is_array($tags)) {
foreach ($tags as $tag) {
$tags[] = $tag->tag;
}
$tags = implode(', ', $tags);
}
?>
Here you go.
$tags = json_decode(Input::old('tags'), true); // decode json input as an array
if (is_array($tags)) {
foreach ($tags as $key=>$value) {
$tags[$key] = $value['tag'];
}
$tags = implode(', ', $tags);
echo $tags;
}
You can use array_map to extract the tag property from the object.
<?php
$jsonObject = json_decode(Input::old('tags'));
if(is_array($jsonObject)) {
$onlyTags = array_map(function($item) { return $item->tag; },$jsonObject);
print implode(",", $onlyTags);
}
Try adding true to json_decode.
json_decode($tags, true);
According to the docs that should return an associative array.
http://php.net/manual/en/function.json-decode.php
is_array might not work with associative arrays with a key/value pair. Try replacing is_array with this function:
function is_associate_array($array)
{
return $array === array_values($array);
}
So:
if(is_associate_array(json_decode($tags, true))) {
}

set element values using foreach not working as expected

I have a muti-dimention array like this:
$arrayTest = array(0=>array("label"=>"test","category"=>"test","content"=>array(0=>array("label"=>"test","category"=>"test"),1=>array("label"=>"test","category"=>"test"))));
then I want to set all the labels in the content array like this:
foreach($arrayTest as $obj) {
foreach($obj["content"] as $anobj){
$anobj["label"] = "hello";
}
}
After that I print out the array
echo json_encode($arrayTest);
On the browser I saw:
[{"label":"test","category":"test","content":[{"label":"test","category":"test"},{"label":"test","category":"test"}]}]
Nothing changed, but if I try
$arrayTest[0]["content"][0]["label"] = "hello";
$arrayTest[0]["content"][1]["label"] = "hello";
Then it seems working. I want to know why the first method not working?
You need to iterate over the array by reference for the changes to stick:
foreach($arrayTest as &$obj) { // by reference
foreach($obj["content"] as &$anobj){ // by reference
$anobj["label"] = "hello";
}
}
// Whenever you iterate by reference it's a good idea to unset the variables
// when finished, because assigning to them again will have unexpected results.
unset($obj);
unset($anobj);
Alternatively, you can index into the array using keys, starting from the root:
foreach($arrayTest as $key1 => $obj) {
foreach($obj["content"] as $key2 => $anobj){
$arrayTest[$key1]["content"][$key2]["label"] = "hello";
}
}

PHP foreach loop to do something once instead of multiple times

I'm running a foreach loop for the whole script that checks 9 things.
Let's say five of them have value "a" and four of them have value "b".
How do I write an IF condition (or something) that only returns "a" and "b" once?
Simple method (check last value)
Use a variable which stores the previous contents, and compare it with the current iteration (only works if the similar items are sequential)
$last_thing = NULL;
foreach ($things as $thing) {
// Only do it if the current thing is not the same as the last thing...
if ($thing != $last_thing) {
// do the thing
}
// Store the current thing for the next loop
$last_thing = $thing;
}
More robust method (store used values on an array)
Or, if you have complex objects, where you need to check an inner property and the like things are not sequential, store the ones used onto an array:
$used = array();
foreach ($things as $thing) {
// Check if it has already been used (exists in the $used array)
if (!in_array($thing, $used)) {
// do the thing
// and add it to the $used array
$used[] = $thing;
}
}
For example (1):
// Like objects are non-sequential
$things = array('a','a','a','b','b');
$last_thing = NULL;
foreach ($things as $thing) {
if ($thing != $last_thing) {
echo $thing . "\n";
}
$last_thing = $thing;
}
// Outputs
a
b
For example (2)
$things = array('a','b','b','b','a');
$used = array();
foreach ($things as $thing) {
if (!in_array($thing, $used)) {
echo $thing . "\n";
$used[] = $thing;
}
}
// Outputs
a
b
Could you be more concrete (it might be helpful to insert a code-snippet with your "content"-objects).
It sounds like, you are trying to get unique values of an array:
$values = array(1,2,2,2,2,4,6,8);
print_r(array_unique($values));
>> array(1,2,4,6,8)

Categories