Restful API throw unexpected output in codeigniter - php

controller:
<?php
require APPPATH . '/libraries/REST_Controller.php';
use Restserver\Libraries\REST_Controller;
class User extends REST_Controller
{
function __construct()
{
parent::__construct();
$this->load->database();
}
function country_state_get()
{
$this->db->select('id,name');
$this->db->from('countries');
$sql = $this->db->get();
$data = $sql->result_array();
foreach($data as $row)
{
$this->db->select('id,name');
$this->db->from('states');
$this->db->where('country_id',$row['id']);
$sqls = $this->db->get();
$data2 = $sqls->result_array();
}
$result= [
"Country" => $data,
"state" => $data2
];
$this->response($result, 200);
}
}
unexpected output:
{
"Country": [
{
"id": "1",
"name": "Afghanistan"
},
{
"id": "2",
"name": "Albania"
},
{
"id": "3",
"name": "Algeria"
}
]
}
expected output:
{
"Country": [
{
"id": "1",
"name": "Afghanistan",
"state": ["Badakhshan", "Badghis", "Baghlan"]
},
{
"id": "2",
"name": "Albania",
"state": ["Berat", "Dibres", "Durres"]
},
{
"id": "3",
"name": "Algeria",
"state": ["Adrar", "Ain Defla", "Ain Temouchent"]
}
]
}
I have to create simple country and state api using codeigniter framework. Here I am getting unexpected output as I mention above. when I hit the url on my localhost server it throw unexpected out but my expected output is different. So, How can I do this? Please help me.
Thank You

Update your country_state_get function with below function code
function country_state_get()
{
$this->db->select('id,name');
$this->db->from('countries');
$sql = $this->db->get();
$data = $sql->result_array();
foreach($data as $key => $row)
{
$this->db->select('id,name');
$this->db->from('states');
$this->db->where('country_id',$row['id']);
$sqls = $this->db->get();
$data2 = $sqls->result_array();
$data[$key]['state'] = $data2;
}
$result= [ "Country" => $data ];
$this->response($result, 200);
}

Related

Format the json encode just like on laravel php

Supposed I have a query that gets the image from a certain tweet
[
{
"pic": "/upload/15680712995mb.jpg",
"tweet_id": "48"
},
{
"pic": "/upload/1568071299test.PNG",
"tweet_id": "48"
},
{
"pic": "/upload/1568015310test.PNG",
"tweet_id": "47"
}
]
And I have a result also from a query that gets all of the tweet
[
{
"id": "48",
"tweet": "test",
},
{
"id": "47",
"tweet": "test tweet",
},
{
"id": "45",
"tweet": "test tweet 3",
}
]
How can I format the result like this (Just like on laravel)
[
{
"id": "48",
"tweet": "test",
"pics": [
[
"/upload/15680712995mb.jpg"
],
[
"/upload/1568071299test.PNG"
],
]
},
{
"id": "47",
"tweet": "test tweet",
"pics" : [
[
"/upload/1568015310test.PNG"
]
]
},
{
"id": "45",
"tweet": "test tweet 3",
"pics" : []
}
]
And this is my simplified code
public function getTweets()
{
$pics = $this->model->getPics();
$aTweets = $this->model->getTweets();
$map = [];
$props = [];
foreach ($aTweets as $sTweet) {
$map['id'] = $sTweet['id'];
$map['tweet'] = $sTweet['tweet'];
foreach ($pics as $pic) {
if ($pic['id'] === $sTweet['tweet_id']) {
$map['pics'] = [$pic['pic']];
}
}
$props[] = $map;
}
return $props;
}
but it just gives me the following output
{
"id": "48",
"tweet": "test",
"pics": [
"/upload/1568015310test.PNG"
]
},
{
"id": "47",
"tweet": "test tweet",
"pics": [
"/upload/1568015310test.PNG"
]
},
Any idea how can I format the result. thanks in advance.?
I'm not sure what's troubling you but in order to add multiple values inside, just put another nesting like what I've eluded in the comments section:
$map['pics'][] = $pic['pic'];
// ^
So to complete the answer:
$map = [];
$props = [];
foreach ($aTweets as $sTweet) {
$map['id'] = $sTweet['id'];
$map['tweet'] = $sTweet['tweet'];
$map['pics'] = []; // initialize
foreach ($pics as $pic) {
if ($pic['tweet_id'] === $sTweet['id']) {
$map['pics'][] = [$pic['pic']];
}
}
$props[] = $map;
}
This essentially creates another dimension for pics index as an array and continually pushing, provided they have the same ID.
Sidenote: tweet_id is to pics and id is to aTweets. Your's have the other way around.

Laravel : get data array and loop with For

Hi I'am trying to get data Array and looping with For. So I have array called 'color' and I want loop the Array with For. But I have some trouble in the result. I've been tried change the array and in foreach but I got no idea how to get result like what I want.
The Result :
"data": [
{
"title": "get data users",
"function_name": "selectDataUser",
"function_drop": "selectDataUser",
"type_of_chart": "Pie",
"embed": null,
"created_at": "2019-06-15 03:26:09.000",
"updated_at": null,
"data_chart": [
{
"name": "Administrator",
"total": "100",
"color": "0xFF888888" //color cannot be the same
},
{
"name": "Staff",
"total": "100",
"color": "0xFF888888" //the color must be different
},
{
"name": "Super Administrator",
"total": "1",
"color": "0xFF888888" //this is not result what I want.
}
],
}
]
I want response like this:
"data": [
{
"title": "get data users",
"function_name": "selectDataUser",
"function_drop": "selectDataUser",
"type_of_chart": "Pie",
"embed": null,
"created_at": "2019-06-15 03:26:09.000",
"updated_at": null,
"data_chart": [
{
"name": "Administrator",
"total": "100",
"color": "0xFF000000" //all this color different
},
{
"name": "Staff",
"total": "100",
"color": "0xFF444444" //the color different
},
{
"name": "Super Administrator",
"total": "1",
"color": "0xFF888888" //this is result what I want.
}
],
}
]
This my code :
public function index(Request $request)
{
try {
$query = $this->dashboard->with('rolesDashboard','userDashboard')
->orderBy('id')
->get();
$data=[];
foreach ($query as $key) {
$data_chart = DB::select($key->function_name); //call store procedure from SQL Server
$color = array(
"0xFF000000" ,
"0xFF444444" ,
"0xFF888888" ,
"0xFFCCCCCC",
"0xFFFFFFFF",
"0xFFFF0000" ,
"0xFF00FF00" ,
); // this is array color
for ($i=0; $i < count($data_chart) ; $i++) {
$set = $color[$i]; //Get data array color
}
foreach($data_chart as $row){
$row->color = $set;
}
$data[] = [
'title' => $key->title,
'function_name' => $key->function_name,
'created_at' => $key->created_at,
'updated_at' => $key->updated_at,
'data_chart' => $data_chart, //return data_chart and color
];
}
return response()->default(200, trans('messages.success.get-data'),$data);
} catch (Exception $e) {
return response()->default(400, $e->getMessage());
}
}
$set is array, cannot be assigned as a string. My advice is changing below code:
for ($i=0; $i < count($data_chart) ; $i++) {
$set = $color[$i]; //Get data array color
}
foreach($data_chart as $row){
$row->color = $set;
}
to
$i=0;
foreach($data_chart as $row){
$row->color = $color[$i];
$i++;
}
but if your $data_chart count is more than $color count it will return error, for better handling use code below:
$i=0;
foreach($data_chart as $row){
if(isset($color[$i])){
$row->color = $color[$i];
$i++; }
else{
$i=0;
}
}

PHP - fetch json data

I have problem with this script...
My script has return this:
{
"categories": {
"cid": "1",
"name": "Pierwsza pomoc"
}
}{
"categories": {
"cid": "2",
"name": "Poradniki"
}
}{
"categories": {
"cid": "3",
"name": "Klany"
}
}{
"categories": {
"cid": "4",
"name": "Eventy, imprezy"
}
}{
"categories": {
"cid": "5",
"name": "Rozm\u00f3wki"
}
}{
"categories": {
"cid": "6",
"name": "Quest, solucje"
}
}{
"categories": {
"cid": "7",
"name": "Off topic"
}
}
But i want to this
[
'categories': {
'cid': 1,
'name': 'test',
'cid': 2,
'name': 'asdsad',
'cid': 3,
'name': 'asdasd'
}
]
Code used to create the data is
if($query->rowCount() > 0){
foreach($query as $row){
$Forum->writeJSON(array('categories' => array( 'cid' => $row['id'], 'name' => $row['name'] )));
}
}
class Forum {
public function writeJSON($array){
echo json_encode($array, JSON_PRETTY_PRINT);
}
}
$Forum = new Forum;
Well, this structure is not possible. You cannot store two or more elements with exactly same key in same object. However maybe you simply want this output:
[ 'categories' : { 1: {category_id:1, name:'test'}, 2: {category_id:2, name:'test'} } ]
It is simple, for example, you can use something like this to form that array:
<?php
//fetch data into categories variable
$output = array();
$output['categories'] = array();
foreach ($category as $category){
$output['categories'][] = array('category_id' => $category['id'], 'name' => $category['name']);
}
$output = json_encode($output);
?>
PS: Please use the correct variable names in your code, this is just an example using fictitious variable names
You need to change your foreach loop code
if($query->rowCount() > 0){
foreach($query as $row){
$cat_array[$row['id']] = array('cid'=>$row['id'],'name'=>$row['name']);
}
$json_array[] = array('categories'=>$cat_array);
$Forum->writeJSON($json_array);
}

Flatten a Multidimensional Array with key, value and object from a JSON

For 2 days, I'm trying to extract informations from a multidimensional array and I think I'm stuck after trying a lot of things
Here is my json
{
"profile": [
{
"id": "123456",
"hostId": null,
"description": [
{
"id": "name",
"value": "foo"
},
{
"id": "name2",
"value": "foo2"
},
{
"id": "bio",
"value": "heyyyy"
},
{
"id": "location",
"value": "somewhere"
}
],
"ishere": true
}
]
}
I want to manipulate it to have this
{
"id": "123456",
"host": null,
"name": "foo",
"name2": "foo2",
"bio": "heyyyy",
"location": "somewhere",
"ishere": true
}
with this (after a json_decode)
foreach ($array->profileUsers[0]->settings as $item) {
$out2[$item->id] = $item->value;
}
I only have
{
"name": "foo",
"name2": "foo2",
"bio": "heyyyy",
"location": "somewhere"
}
Thank you
This should do the trick:
$obj = json_decode($your_json);
$obj = $obj->profile[0];
foreach($obj->description as $d)
$obj->{$d->id} = $d->value;
unset($obj->description);
$data = json_decode($your_json, true);
$new_array = [];
foreach($data['profile'] as $key=>$item) {
if(is_array($item)) {
$new_array[$item['id']] = $item['value'];
}
else {
$new_array[$key] = $item;
}
}
Hardcoded this, hope it will help.

PHP - Nested array keys based on string lines

I need a help. I'm looking for a solution for this problem!
I have a file which contains the following pattern:
Brazil|SaoPaulo|Diadema|RuadaFe Brazil|SaoPaulo|Diadema|RuadoLimoeiro
Brazil|SaoPaulo|SaoCaetano|RuadasLaranjeiras
Brazil|Parana|Curitiba|ComendadorAraujo
USA|NewJersey|JerseyCity|WhashingtonBoulervard
USA|NewJersey|JerseyCity|RiverCourt
Which should bring after some array key implementation, something like this (after apply json_encode call on php):
{
"name": "Brazil",
"children": [
{
"name": "SaoPaulo",
"children": [
{
"name": "Diadema",
"children": [
{"name": "RuadaFe"},
{"name": "RuadoLimoeiro"}
]
},
{
"name": "SaoCaetano",
"children": [
{"name": "RuadasLaranjeiras"}
]
},
]
"name": "Parana",
"children": [
{
"name": "Curitiba",
"children": [
{"name": "ComendadorAraujo"}
]
}
]
},
"name":"USA",
"children":[
{
"name": "NewJersey",
"children": [
{
"name": "JerseyCity",
"children": [
{"name": "WhashingonBoulevard"},
{"name": "RiverCourt"}
]
}
]
}
]
}
]
And keep going and going (and even more deeper too).
Please, help me team... thanks in advance.
Here what I get until now:
Array
(
[Brazil] => Array
(
[SaoPaulo] => Array
(
[Diadema] => Array
(
[RuadoLimoeiro] =>
)
[SaoCaetano] => Array
(
[RuadasLaranjeiras] =>
)
)
[Parana] => Array
(
[Curitiba] => Array
(
[ComendadorAraujo] =>
)
)
)
[USA] => Array
(
[NewJersey] => Array
(
[JerseyCity] => Array
(
[WhashingtonBoulervard] =>
[RiverCourt] =>
)
)
)
)
And here is the json encoded:
{
"Brazil":{
"SaoPaulo":
{"Diadema":
{"RuadoLimoeiro":null},
"SaoCaetano":{"RuadasLaranjeiras":null}
},
"Parana":
{"Curitiba":
{"ComendadorAraujo":null}
}
},
"USA":{
"NewJersey":{
"JerseyCity":{
"WhashingtonBoulervard":null,
"RiverCourt":null}
}
}
}
As you can see, the "names" and "child" is missing because is not an array key structure, also something is wrong, because I'm missing some values on SaoPaulo.
Here is the function:
foreach($strings as $string) {
$parts = array_filter(explode('|', $string));
$ref = &$result;
foreach($parts as $p) {
// echo $p;
if(!isset($ref[$p])) {
$ref[$p] = array();
// $ref[$p] = array("name"=>$p);
}
$ref = &$ref[$p];
}
$ref = null;
}
-------------------------------- AFTER SOME ANSWERS --------------------------
{
"name": "Brazil(country)",
"children": [
{
"name": "SaoPaulo(state)", // only one state
"children": [
{
"name": "Diadema(city)", // only one city
"children": [
{"name": "RuadaFe(street)"}, // two streets under the same city...
{"name": "RuadoLimoeiro(street)"}
]
},
{
"name": "SaoCaetano(city)",
"children": [
{"name": "RuadasLaranjeiras(street)"}
]
},
]
"name": "Parana(state)",
"children": [
{
"name": "Curitiba(city)",
"children": [
{"name": "ComendadorAraujo(street)"}
]
}
]
},...
I put on parentesis the structure (country, state, city, street) just to clarify what i want.
Got it?
It is not outright trivial, but what I did is actually the same as you (the same way as in your edited question), but I also keep track of those arrays to rename the keys. And that's what I do afterwards then:
$separator = [' ', '|'];
$buffer = file_get_contents($file);
$entries = explode($separator[0], $buffer);
$result = [];
$named[] = &$result;
########
foreach ($entries as $entry) {
$each = explode($separator[1], $entry);
$pointer = & $result;
while ($current = array_shift($each)) {
if (!isset($pointer[$current])) {
unset($children);
$children = [];
$named[] = &$children;
########
$pointer[$current] = ['name' => $current, 'children' => &$children];
}
$pointer = & $pointer[$current]['children'];
}
}
foreach($named as $offset => $namedArray) {
$keys = array_keys($namedArray);
foreach($keys as $key) {
$named[$offset][] = &$namedArray[$key];
unset($named[$offset][$key]);
}
}
print_r($result);
See it in action.
You probably might want to modify this by checking in the later foreach if children are empty (leaf-nodes) and then removing the children entry as well.
Here the modified foreach at the end and json output:
foreach($named as $offset => $namedArray) {
$keys = array_keys($namedArray);
foreach($keys as $key) {
if (!$namedArray[$key]['children']) {
unset($namedArray[$key]['children']);
}
$named[$offset][] = &$namedArray[$key];
unset($named[$offset][$key]);
}
}
echo json_encode($result, JSON_PRETTY_PRINT);
Output:
[
{
"name": "Brazil",
"children": [
{
"name": "SaoPaulo",
"children": [
{
"name": "Diadema",
"children": [
{
"name": "RuadaFe"
},
{
"name": "RuadoLimoeiro"
}
]
},
{
"name": "SaoCaetano",
"children": [
{
"name": "RuadasLaranjeiras"
}
]
}
]
},
{
"name": "Parana",
"children": [
{
"name": "Curitiba",
"children": [
{
"name": "ComendadorAraujo"
}
]
}
]
}
]
},
{
"name": "USA",
"children": [
{
"name": "NewJersey",
"children": [
{
"name": "JerseyCity",
"children": [
{
"name": "WhashingtonBoulervard"
},
{
"name": "RiverCourt"
}
]
}
]
}
]
}
]
The full code-example at a glance:
<?php
/**
* PHP - Nested array keys based on string lines
* #link http://stackoverflow.com/a/16305236/2261774
*/
$file = 'data://text/plain;base64,' . base64_encode('Brazil|SaoPaulo|Diadema|RuadaFe Brazil|SaoPaulo|Diadema|RuadoLimoeiro Brazil|SaoPaulo|SaoCaetano|RuadasLaranjeiras Brazil|Parana|Curitiba|ComendadorAraujo USA|NewJersey|JerseyCity|WhashingtonBoulervard USA|NewJersey|JerseyCity|RiverCourt');
$separator = [' ', '|'];
$buffer = file_get_contents($file);
$entries = explode($separator[0], $buffer);
$result = [];
$named[] = &$result;
foreach ($entries as $entry) {
$each = explode($separator[1], $entry);
$pointer = & $result;
while ($current = array_shift($each)) {
if (!isset($pointer[$current])) {
unset($children);
$children = [];
$named[] = &$children;
$pointer[$current] = ['name' => $current, 'children' => &$children];
}
$pointer = & $pointer[$current]['children'];
}
}
unset($pointer);
foreach($named as $offset => $namedArray) {
$keys = array_keys($namedArray);
foreach($keys as $key) {
if (!$namedArray[$key]['children']) {
unset($namedArray[$key]['children']);
}
$named[$offset][] = &$namedArray[$key];
unset($named[$offset][$key]);
}
}
unset($named);
echo json_encode($result, JSON_PRETTY_PRINT);
your question JSON:
{
"name": "Brazil",
"children": [
{
"name": "SaoPaulo",
"children": [
{
"name": "Diadema",
"children": [
{"name": "RuadaFe"},
{"name": "RuadoLimoeiro"}
]
},
My Answer JSON:
[
{
"name": "Brazil",
"children": [
{
"name": "SaoPaulo",
"children": [
{
"name": "Diadema",
"children": [
{
"name": "RuadaFe"
},
{
"name": "RuadoLimoeiro"
}
]
},
The only difference I can spot is that the root-nodes are wrapped inside an array in my answer, but it should be trivial to fetch them out there if that really is your issue ;)
Does it solves your problem? Use $inputString to put your real string.
<?php
// ------------------------------------------------------ your input goes here ------------------------------------------------------
$inputString = 'Brazil|SaoPaulo|Diadema|RuadaFe Brazil|SaoPaulo|Diadema|RuadoLimoeiro Brazil|SaoPaulo|SaoCaetano|RuadasLaranjeiras Brazil|Parana|Curitiba|ComendadorAraujo USA|NewJersey|JerseyCity|WhashingtonBoulervard USA|NewJersey|JerseyCity|RiverCourt';
class item {
public $name = null;
public function getChildrenByName($strName) {
$ret = null;
# this variable should be defined in interface, but i skipped it so it wont be printed in json when obj does not have childrens
if( !isset( $this->children ) ) {
$this->children = array( );
}
foreach ( $this->children as $child ) {
if( $child->name === $strName ) {
$ret = $child;
break;
}
}
if ( !$ret ) {
$this->children[] = self::spawnByName( $strName );
}
return $this->children[ count($this->children) - 1];
}
static public function spawnByName($strName) {
$ret = new item();
$ret->name = $strName;
return $ret;
}
}
class listManager {
protected $list = array();
public function getList() {
return $this->list;
}
public function addPath( $desiredPath ) {
# path needs to be as array
if ( is_string( $desiredPath ) ) {
$desiredPath = explode('|', $desiredPath);
}
# create root element if it does not already exists
if ( !isset( $this->list[$desiredPath[0]] ) ) {
$this->list[$desiredPath[0]] = item::spawnByName($desiredPath[0]);
}
$curElement = $this->list[$desiredPath[0]];
for( $i=1; $i<count($desiredPath); $i++ ) {
$curElement = $curElement->getChildrenByName( $desiredPath[$i] );
}
}
protected function spawnElement( $strName ) {
$ret = new item();
$ret->name = $strName;
return $ret;
}
}
$output = array();
$expl = explode(' ', $inputString);
$list = new listManager();
foreach ( $expl as $key => $path ) {
$list->addPath( $path );
}
$output = '';
foreach ( $list->getList() as $singleVariable ) {
$output .= json_encode($singleVariable, JSON_PRETTY_PRINT) . ",\n";
}
echo '<pre>'.$output.'</pre>';
?>
Above code produces following json out of your sample code:
{
"name": "Brazil",
"children": [{
"name": "SaoPaulo",
"children": [{
"name": "Diadema",
"children": [{
"name": "RuadaFe"
}
]
}
]
}, {
"name": "SaoPaulo",
"children": [{
"name": "Diadema",
"children": [{
"name": "RuadoLimoeiro"
}
]
}
]
}, {
"name": "SaoPaulo",
"children": [{
"name": "SaoCaetano",
"children": [{
"name": "RuadasLaranjeiras"
}
]
}
]
}, {
"name": "Parana",
"children": [{
"name": "Curitiba",
"children": [{
"name": "ComendadorAraujo"
}
]
}
]
}
]
} {
"name": "USA",
"children": [{
"name": "NewJersey",
"children": [{
"name": "JerseyCity",
"children": [{
"name": "WhashingtonBoulervard"
}
]
}
]
}, {
"name": "NewJersey",
"children": [{
"name": "JerseyCity",
"children": [{
"name": "RiverCourt"
}
]
}
]
}
]
}
edit: changed, does it fit now?

Categories