Relatively new to Laravel and trying to create a REST api that will have as a response a json that is split between rows and cols of a query
So, the code used to generate the json is:
$r = array(
'cols' => array_keys(get_object_vars(Dd_hr::take(2)->get())),
'rows' => Dd_hr::take(2)->get()
);
return response()->json($r, 201);
Basically, the json should look something like:
{"cols":[{"id", "user_name"}],"rows":[{"710206","user"}]}
But in fact it looks like:
{"cols":[],"rows":[{"id":"710206","user_name":"user"}]}
Could someone help me to solve this issue?
The result of dd(Dd_hr::take(2)->get()->toArray()):
array:2 [▼
0 => array:27 [▼
"rn" => "1"
"id" => "710206"
"user_name" => "user"
]
1 => array:27 [▼
"rn" => "2"
"id" => "710207"
"user_name" => "user"
]
]
Didn't find a way to do this properly so here goes the good old array_map.
This doesn't remove the "rn" key. If you want to chose the keys in the select you can, it'll even make creating the JSON easier since you'll already have the 'cols'.
$res_array = Dd_hr::take(2)->get()->toArray();
$cols = array_keys($res_array[0]);
$rows = array_map(function($row){
return array_values($row);
}, $res_array);
return response()->json(array('cols'=>$cols, 'rows'=>$rows), 201);
This returns :
"{"cols":["rn","id","user_name"],"row":[["1","710206","user"],["2","710207","user"]]}"
Related
This question already has an answer here:
How to convert a 1-dimensional array into a 2-dimensional array in PHP
(1 answer)
Closed 26 days ago.
I want to make array without foreach loop. This is should be returned:
array:4 [
0 => array:1 [
"name" => "tag1"
]
1 => array:1 [
"name" => "tag2"
]
2 => array:1 [
"name" => "tag3"
]
3 => array:1 [
"name" => "tag4"
]
]
I made it to work like this:
$tags=[];
$j=0;
foreach($woo->tags as $tag){
$tags[$j]['name']=$tag;
$j++;
}
But when I have a lot of tags it can be slow in foreach loop. My tags are saved in database in text field like tag1,tag2,tag3,tag4
Is there any other faster way to return this..
Try array_map, I haven't actually benchmarked the both but it is one of (if not your only) alternative:
$tags = array_map(function($tag) {
return ['name' => $tag];
}, $woo->tags);
For what it's worth, if you are actually storing so many tags in a singular column that it actually slows PHP down, might be something you need to step back and think about improving.
I am using this package to handle hierarchy data in Laravel: https://github.com/lazychaser/laravel-nestedset
Their is an implemented functionality which provides the opportunity to create new data with a multidimensional array. So I have the following sample array (of a file/directory hierarchy):
array:3 [
"name" => "Folder1"
"type" => "folder"
"children" => array:2 [
0 => array:2 [
"name" => "test1.txt"
"type" => "txt"
]
1 => array:3 [
"name" => "Folder1.1"
"type" => "folder"
"children" => array:2 [
0 => array:2 [
"name" => "file.png"
"type" => "png"
]
1 => array:3 [
"name" => "folder1.1.1"
"type" => "folder"
"children" => array:1 [
0 => array:2 [
"name" => "file.txt"
"type" => "txt"
]
]
]
]
]
]
]
But their are directories with more than 10GB of data which means they have a much higher complexity than the shown example with a deep hierarchy. The database is already filled with over a million rows. And if I try to insert a new array the MySQL immediately runs on 100% CPU and needs about 20 minutes to insert that new structure into the database.
The reason is because it needs to calculate LEFT and RIGHT for nested set considering already existent data in the table.
Is there a more efficient way to insert such hierarchies into the database?
Quick example of adding the left and right items to the various arrays (assuming that the lowest level of the arrays is a row of items, so no need add a left and right to these individual items).
Something like this could be used to add the values
<?php
function array_left_right (&$array, &$counter = 1)
{
if (is_array($array))
{
$array['left'] = $counter++;
foreach($array as $array_key=>&$array_item)
{
array_left_right($array_item, $counter);
}
$array['right'] = $counter++;
}
}
$fred = array(array(array('a', 'b'), array('c', 'd'), array('e', 'f'), array('g', 'h')),array(array('aa', 'ab'), array('ac', 'ad'), array('ae', 'af'), array('ag', 'ah')));
array_left_right($fred);
print_r($fred);
I have this statement:
$request->lines[$i]['price_ex_vat'] = preg_replace("/([^0-9\\.])/i", "", $request->lines[$i]['price_ex_vat']);
Its purpose is to remove the currency formatting on a value but I get the error Indirect modification of overloaded property Illuminate\Http\Request::$lines has no effect
Googling tells me I need to use ->merge() but it is just not sinking in how to do that. Any help appreciated.
As Laravel uses Symfony's ParameterBag to store the request's data it internally does this:
$p = new \Symfony\Component\HttpFoundation\ParameterBag(['foo' => 'bar', 'baz' => 'qux']);
$p->add(['baz' => 'xyz']);
dump(
$p->all()
);
Which prints out:
array:2 [
"foo" => "bar"
"baz" => "xyz"
]
Laravel's request exposes merge method that calls ParameterBag's add method internally. All is good until you manipulate one dimension data.
In your case, the solution could be like this:
$request = \Illuminate\Http\Request::create('/', 'POST',
[
'lines' => [
['price_ex_vat' => 'foo'],
['price_ex_vat' => 'bar'],
['price_ex_vat' => 'baz'],
],
]
);
$data = $request->input();
$data['lines'][1]['price_ex_vat'] = 'xyz'; // preg_replace or whatever you want.
dd(
$request->merge($data)->input();
);
Which prints accordingly:
array:1 [
"lines" => array:3 [
0 => array:1 [
"price_ex_vat" => "foo"
]
1 => array:1 [
"price_ex_vat" => "xyz"
]
2 => array:1 [
"price_ex_vat" => "baz"
]
]
]
I assume $request->lines is an array you are iterating through and want to change price_ex_vat on it. I would suggest making a separate variable to do the changes on it, then use merge to replace $request->lines
$arr = $request->lines;
foreach($arr as $line){ //or you can use a normal for loop if you prefer
$line['price_ex_vat'] = preg_replace("/([^0-9\\.])/i", "", $line['price_ex_vat']); //your changes here
}
$request->merge('lines',$arr);
I am doing a request to an API and for each request I get an array with the BrowseNodes back. Inside this array I get this result:
array:1 [
"BrowseNode" => array:3 [
"BrowseNodeId" => "2502033031"
"Name" => "OBD-II Diagnosewerkzeuge"
"Ancestors" => array:1 [
"BrowseNode" => array:3 [
"BrowseNodeId" => "5142250031"
"Name" => "Motorwerkzeuge & Zubehör"
"Ancestors" => array:1 [
"BrowseNode" => array:3 [
"BrowseNodeId" => "2502064031"
"Name" => "Werkzeuge"
"Ancestors" => array:1 [
"BrowseNode" => array:4 [
"BrowseNodeId" => "79899031"
"Name" => "Kategorien"
"IsCategoryRoot" => "1"
"Ancestors" => array:1 [
"BrowseNode" => array:2 [
"BrowseNodeId" => "78191031"
"Name" => "Auto & Motorrad"
]
]
]
]
]
]
]
]
]
]
If this would be a fixed array which always had this length it would be easy for me to get the last BrowseNode Array and the value with the key "Name". In this case it would be the this one "Name" => "Auto & Motorrad".
However, because a category can have one or more nested arrays, it is not static...
That means I have to find a solution to always get the most nested array and from this one the name to get the category. Because it is dynamic data, I don't know how to solve that. I just know I always have to get the BrowseNode and then inside the BrowseNode array. I have to get the Ancestors and inside this Ancestors again. I have to get the BrowseNode array until I arrived at the last BrowseNode array and the get the name.
So, I have to iterate through my array until the BrowseNode array doesn't have an Ancestors array anymore and the get the name of this BrowseNode array.
Do you guys have any idea on how to do this?
I guess you can use recursion to achieve that.
On each object, search for Ancestors, if not found return the name, else do so again on the Ancestors.
Consider the following code:
$arr = array("BrowseNode" => array("BrowseNodeId" => "1", "Ancestors" => array("BrowseNode" => array("BrowseNodeId" => "2", "Ancestors" => array("BrowseNode" => array("BrowseNodeId" => "3"))))));
function getLastName($elem) {
$elem = $elem["BrowseNode"];
if (!array_key_exists("Ancestors", $elem))
return $elem['BrowseNodeId'];
else return getLastName($elem["Ancestors"]);
}
echo getLastName($arr);
Notice that this code return id instead of your Name - small modification I leave to you...
There might be a more "correct" way of doing this but since I'm writing this on my phone on a plane, you'll have to forgive my not being able to proof check my answer. But you could do a recursive function, like...
function recurseArray($browseNode)
{
if(isset($browseNode["Ancestors"])) {
recurseArray($browseNode["Ancestors"]["browseNode"])
} else {
// Do whatever you want with the last iteration
}
}
Hope that makes sense!
I'm struggling to get data from JSON response. This is my code for getting the data:
$client = new Client;
$r = $client->get("http://my.api.com/get-campaign/" . $id . "?api_token=1235");
$apiResult = json_decode($r->getBody(), true);
dd($apiResult);
And I get something like this:
array:4 [
"campaign" => array:1 [
0 => array:3 [
"manufacturer" => "Sony"
"product" => "PlayStation 4"
"created_at" => "2015-07-04T00:00:00+00:00"
]
]
"media" => array:2 [
"video" => "https://my.domain.com/421156.mp4"
"images" => "https://my.domain.com/tv/thumbs/421156-1.jpg"
]
"statistics" => array:3 [
"runs" => 172
"firstseen_at" => "2015-07-04T19:06:41+00:00"
"lastseen_at" => "2015-07-09T12:04:13+00:00"
]
"broadcasts" => array:172 []
]
How can I get single values from this response? Let's say I want to display, or assign to another variable the value of "manufacturer" and in another variable to store number of runs ("runs")?
For manufacturer I've tried to do something like this:
dd($apiResult["campaign"]->manufacturer);
But then error is shown - trying to get non-property object!
You're mixing object access with array access.
$apiResult = json_decode($r->getBody(), true);
dd($apiResult["campaign"][0]["manufacturer"]);
or with objects
$apiResult = json_decode($r->getBody(), false);
dd($apiResult->campaign[0]->manufacturer);
Looks like campaign is an array so you would need to do:
$apiResult["campaign"][0]->manufacturer
If you want to play with object then use following:
$apiResult = json_decode($r->getBody());
dd($apiResult->campaign[0]->manufacturer);
or want an associative array
$apiResult = json_decode($r->getBody(), true);
dd($apiResult["campaign"][0]["manufacturer"]);
For more detail read documentation of json_decode