Generating data array from POST data with a param-map - php

I have the following two things:
$_POST array with posted data
$params array with a path for each param in the desired data array.
$_POST = array(
'name' => 'Marcus',
'published' => 'Today',
'url' => 'http:://example.com',
'layout' => 'Some info...',
);
$params = array(
'name' => 'Invoice.name',
'published' => 'Page.published',
'url' => 'Page.Data.url',
'layout' => 'Page.Data.layout',
);
I would like to generate the $data array like the example below.
How can I do that?
Notice how the "paths" from the $params array are used to build the keys for the data array, filling it with the data from the $_POST array.
$data = array(
'User' => array(
'name' => 'Marcus',
),
'Page' => array(
'published' => 'Today',
'Data' => array(
'url' => 'http:://example.com',
'layout' => 'Some info...',
),
),
);

I would use referenced variables:
$post = array( // I renamed it
'name' => 'Marcus',
'published' => 'Today',
'url' => 'http:://example.com',
'layout' => 'Some info...',
);
$params = array(
'name' => 'Invoice.name',
'published' => 'Page.published',
'url' => 'Page.Data.url',
'layout' => 'Page.Data.layout',
);
echo '<pre>'; // just for var_dump()
foreach($post as $key=>$var){ // take each $_POST variable
$param=$params[$key]; // take the scheme fields
$path=explode('.',$param); // take scheme fields as an array
$temp=array(); // temporary array to manipulate
$temp_original=&$temp; // we need this the same as we're going to "forget" temp
foreach($path as $pathvar){ // take each scheme fields
$temp=&$temp[$pathvar]; // go deeper
}
$temp=$var; // that was the last one, insert it
var_dump($temp_original); // analize carefully the output
}
All you have to do now is to combine them all, they are not exactly what you want, but this will be easy.
And please note, that each $temp_original fields are pointing at $post variable data! (&string instead of string). You may want to clone it somehow.

Related

PHP Write "an array of arrays" dynamically inside an array of arrays, while declaring it [duplicate]

This question already has answers here:
PHP is there a way to add elements calling a function from inside of array
(3 answers)
Closed last month.
In the middle of declaring an array of arrays, I want to "write" an array of arrays generated by my function.
I have a working example when I:
simply store my function-generated arrays into a variable and
then call each array from that function by its key,
but I can't find a command to simply call everything at once.
Here is the code which (I hope) explains it:
<?php
// A. (THIS WORKS)
// A1: A function that returns an array of arrays
function my_arrays_building_function() {
$first_array = array(
'id' => 'my_array_1',
'type' => 'some-type',
'title' => 'My title 1',
);
$second_array = array(
'id' => 'my_array_2',
'type' => 'some-type',
'title' => 'My title 2',
);
// ... and so on, many more.
return array(
'first-array' => $first_array,
'second-array' => $second_array,
// ... and so on.
);
// NOTE there are tens or hundreds of returned arrays here.
}
// A2: Store my arrays in a variable
$my_array = my_arrays_building_function();
// A3: Inside an array (of arrays), I simply "write" my arrays INDIVIDUALLY and THAT works
array(
array(
'id' => 'dummy_preexisting_array_1',
'type' => 'some-type',
),
array(
'id' => 'dummy_preexisting_array_2',
'type' => 'some-type',
),
// HERE THERY ARE, INDIVIDUALLY, COMMA SEPARATED
$my_array[ 'first-array' ],
$my_array[ 'second-array' ],
array(
'id' => 'dummy_preexisting_array_n',
'type' => 'some-type',
)
),
/** -------------------- //
THE ISSUE
// -------------------- **/
// B: HOW DO I "write" THEM ALL AT ONCE???
// B1: The same as A1
function my_arrays_building_function() {
$first_array = array(
'id' => 'my_array_1',
'type' => 'some-type',
'title' => 'My title 1',
);
$second_array = array(
'id' => 'my_array_2',
'type' => 'some-type',
'title' => 'My title 2',
);
// NOT SURE I SHOULD RETURN LIKE THIS
return array(
'first-array' => $first_array,
'second-array' => $second_array
);
}
// B2: Same as A3, Inside an array (of arrays), I "write" my arrays BUT NOW I WANT TO "WRITE" THEM ALL AT ONCE
array(
array(
'id' => 'dummy_preexisting_array_1',
'type' => 'some-type',
),
array(
'id' => 'dummy_preexisting_array_2',
'type' => 'some-type',
),
/** >>>> I need my arrays here ALL AT ONCE aka NOT INDIVIDUALLY AS IN EXAMPLE A. <<<< **/
/**
* In other words, while I'm declaring this array,
* I simply need all my arrays from my_arrays_building_function()
* "written" here with a simple command instead of calling hundreds
* of arrays individually as in the first example
*/
array(
'id' => 'dummy_preexisting_array_n',
'type' => 'some-type',
)
), /* this goes on as it's a part of even bigger array */
Although I wouldn't recommend declaring hundreds of array variables inside a function because that's crazy, but for now, you can use get_defined_vars() to get over this issue.
You will also need to filter out the variables which are arrays and has the keys id, type and title as there are could be several other variables defined apart from this.
Snippet:
<?php
array_filter(get_defined_vars(), fn($val) => is_array($val) && isset($val['id'], $val['type'], $val['title']));
Online Demo
Not too sure if I'm understanding this correctly but from what I assume, you just want to return an array with a bunch of others inside it that you define throughout the function?
A simple approach for this would be to define your output variable immediately and add all of your other arrays to it:
function my_arrays_building_function() {
$output = [];
$output[] = [
'id' => 'my_array_1',
'type' => 'some-type',
'title' => 'My title 1',
];
$output[] = [
'id' => 'my_array_2',
'type' => 'some-type',
'title' => 'My title 2',
];
return $output;
}
Thank you to #Rylee for suggesting Array Unpacking.
The final code would look like this:
// C1: A function that returns an array of arrays BUT without keys
function my_arrays_building_function() {
$first_array = array(
'id' => 'my_array_1',
'type' => 'some-type',
'title' => 'My title 1',
);
$second_array = array(
'id' => 'my_array_2',
'type' => 'some-type',
'title' => 'My title 2',
);
// ... and so on, many more.
// Then return but now I don't assign keys, I only list the vars.
return array(
$first_array, $second_array, ... and so on.
);
}
// C2: Inside an array (of arrays), I use Array Unpacking, THAT'S WHAT I WAS LOOKING FOR, UNPACK ARRAY! SEE BELOW
array(
array(
'id' => 'dummy_preexisting_array_1',
'type' => 'some-type',
),
array(
'id' => 'dummy_preexisting_array_2',
'type' => 'some-type',
),
// HERE I UNPACK MY ARRAY BY USING ... THE THREE DOTS ARE THE KEY
... my_arrays_building_function(),
array(
'id' => 'dummy_preexisting_array_n',
'type' => 'some-type',
)
),
Hooray!

place form data in multiples array and save in json format

I have a form with 3 pages and each page have different fields
in my controller i am able to make data in json format which is as
controller code
$input = $request->all();
unset($input['_token']);
unset($input['submit']);
$form_attributes = json_encode($input);
dd($form_attributes);
Output is as
"{"name":"test","student":"yes","email":"test.student#gmail.com","format":"auto",
"lists":["1,2"],"class_lists":["2,5"],"status":"1"}"
I not show full form so that it will easy to understand with small data
I want to make above out put as
its array should save as one main array Student then page1 array page2 array and then page3 array
it should be as
"Student":[{"arraypage1":[{"name":"test","student":"yes","email":"student#gmail.com"}],
"arraypage2":[{"format":"auto","lists":["1,2"]}],
"arraypage3":[{"class_lists":["2,5"],"status":"1"}]]"
Please help me to encode this data in above format
Thanks
You can easily build up an associative array in your desired format, then json_encode() it:
$formattedOutput = Array(
'student' => Array(
'arraypage1' => Array(
'name' => $input['name'],
'student' => $input['student'],
'email' => $input['email']
),
'arraypage2' => Array(
'format' => $input['format'],
'lists' => $input['lists']
),
'arraypage3' => Array(
'class_lists' => $input['class_lists'],
'status' => $input['status']
)
)
);
$form_attributes = json_encode($formattedOutput);
The exact key names may differ, but you should get the idea.
UPDATE:
To get the square brackets, you can wrap with additional Array():
$formattedOutput = Array(
'student' => Array(
Array('arraypage1' =>
Array(
Array(
'name' => $input['name'],
'student' => $input['student'],
'email' => $input['email']
)
)
),
Array('arraypage2' =>
Array(
Array(
'format' => $input['format'],
'lists' => $input['lists']
)
)
),
Array('arraypage3' =>
Array(
Array(
'class_lists' => $input['class_lists'],
'status' => $input['status']
)
)
)
)
);
see this post for more details: no square bracket json array

PHP APC update key and value array

I have the following testcode.
Now its a very smal array, but in realtime very large.
How can i update only the values from key 1 direct in the APC FOO?
$test = array(
array(
'name' => 'Mike',
'lastname' => 'Last',
),
array(
'name' => 'test',
'lastname' => 'testlast',
),
array(
'name' => 'anothertest',
'lastname' => 'anothertestlast',
),
);
apc_store('foo', $test);
print_r(apc_fetch('foo'));
I don't think you can alter the variable directly in the cache. My best guess would be to write a function which gets the data from the cache, alters it, and stores it back in the cache. Maybe something like:
function apc_update_array($cacheKey, $arrayKey, $array)
{
$data = apc_fetch($cacheKey);
$data[$arrayKey] = $array;
apc_store($cacheKey, $data);
}
With that function you could just run the following code to get it done.
apc_update_array(
'foo',
1,
array(
'name' => 'differenttest',
'lastname' => 'differenttestlast',
)
);

Basic looping with php to build json

I'm querying the instagram api to return json with this code:
$instagramClientID = '9110e8c268384cb79901a96e3a16f588';
$api = 'https://api.instagram.com/v1/tags/zipcar/media/recent?client_id='.$instagramClientID; //api request (edit this to reflect tags)
$response = get_curl($api); //change request path to pull different photos
So I want to decode the json
if($response){
// Decode the response and build an array
foreach(json_decode($response)->data as $item){
...
So now I want to reformat the contents of said array into a particular json format (geojson) the code would be roughly this:
array(
'type' => 'FeatureCollection',
'features' => array(
array(
'type' => 'Feature',
'geometry' => array(
'coordinates' => array(-94.34885, 39.35757),
'type' => 'Point'
), // geometry
'properties' => array(
// latitude, longitude, id etc.
) // properties
), // end of first feature
array( ... ), // etc.
) // features
)
And then use json_encode to return it all into a nice json file to cache on the server.
My question...is how to I use the code above to loop through the json? The outer structure of the array/json is static but the interior needs to change.
In this case it's better to build a new data structure instead of replacing the existing one inline.
Example:
<?php
$instagrams = json_decode($response)->data;
$features = array();
foreach ( $instagrams as $instagram ) {
if ( !$instagram->location ) {
// Images aren't required to have a location and this one doesn't have one
// Now what?
continue; // Skip?
}
$features[] = array(
'type' => 'Feature',
'geometry' => array(
'coordinates' => array(
$instagram->location->longitude,
$instagram->location->latitude
),
'type' => 'Point'
),
'properties' => array(
'longitude' => $instagram->location->longitude,
'latitude' => $instagram->location->latitude,
// Don't know where title comes from
'title' => null,
'user' => $instagram->user->username,
// No idea where id comes from since instagram's id seems to belong in instagram_id
'id' => null,
'image' => $instagram->images->standard_resolution->url,
// Assuming description maps to caption
'description' => $instagram->caption ? $instagram->caption->text : null,
'instagram_id' => $instagram->id,
)
);
}
$results = array(
'type' => 'FeatureCollection',
'features' => $features,
);
print_r($results);

Adding to Array where Key equals Variable

I always have trouble wrapping my head around these foreach array things, and SO has been an incredibly value resource in getting me there, so I hope you guys can help with this one.
public function progress_bar()
{
$items = array(
array(
'step-name' => 'Setup',
'url' => '/projects/new/setup/',
),
array(
'step-name' => 'Artwork',
'url' => '/projects/new/artwork/',
),
array(
'step-name' => 'Review',
'url' => '/projects/new/review/',
),
array(
'step-name' => 'Shipping',
'url' => '/projects/new/shipping-info/',
),
array(
'step-name' => 'Billing',
'url' => '/projects/new/billing/',
),
array(
'step-name' => 'Receipt',
'url' => '/projects/new/receipt/',
),
);
// Status can be active, editing, or complete.
foreach ($this->progress as $step => $status)
{
foreach ($items as $item)
{
$item['step-name'] == ucfirst($step) ? $item['status'] = $status : '';
}
}
return $items;
}
$this->progress contains an array of statuses ('setup' => 'active', 'artwork' => 'editing')
I want to add to the $items array the status of each matching item in $this->progress
$items = array(
array(
'step-name' => 'Setup',
'url' => '/projects/new/setup',
'status' => 'active',
),
etc...
);
If I understand your question correctly, the problem is that you are trying to add an array element to $items, but what you're actually doing is adding the element to a temporary variable ($item), which does not reference the original $items variable.
I'd suggest approaching it like this:
foreach ($this->progress as $step => $status)
{
// Having the $key here allows us to reference the
// original $items variable.
foreach ($items as $key => $item)
{
if ($item['step-name'] == ucfirst($step) )
{
$items[$key]['status'] = $status;
}
}
}
return $items;
Are you locked into using an array to store $items? If so, you're going to be stuck doing a nested loop ("For each element in $this->progress, check each element in $items. If match, update $items" or something like that). If you have some flexibility, I would use a hash for $items (associative array in php-speak), where the index is the step name. So $items['Setup'] would contain 'url' => ... and 'status' => ... etc. Does that make sense? Then your algorithm breaks down to "For each element in $this->progress, get the element in $items by name ($items[$step_name]) and update it's info."
I would change how you have the $items array keyed and do it like this. Stops you from having the nested loops.
public function progress_bar()
{
$items = array(
'Setup' => array(
'url' => '/projects/new/setup/',
),
'Artwork' => array(
'url' => '/projects/new/artwork/',
),
'Review' => array(
'url' => '/projects/new/review/',
),
'Shipping' => array(
'url' => '/projects/new/shipping-info/',
),
'Billing' => array(
'url' => '/projects/new/billing/',
),
'Receipt' => array(
'url' => '/projects/new/receipt/',
)
);
// Status can be active, editing, or complete.
foreach ($this->progress as $step => $status)
{
$item[ucfirst($step)]['status'] = $status;
}
return $items;
}

Categories