Link to home
Start Free TrialLog in
Avatar of tjyoung
tjyoung

asked on

Saving 2 arrays into one combined json value for DB column

Hi,
I have a form that submits a series of checkboxes in an array and corresponding values in another array.

$_POST['specs']['checks'];
$_POST['specs']['values'];

I var_dumped to give you an idea.

Array ( [horsepower] => 1 [horsepower_rpm] => 1 [torque] => 1 [torque_rpm] => 1 [fuel_capacity] => 1 [vehicle_length] => 1 [vehicle_width] => 1 [vehicle_height] => 1 [curb_weight] => 1 )

Array ( [horsepower] => 170.0 [horsepower_rpm] => 5800 [torque] => 174.0 [torque_rpm] => 4100 [fuel_capacity] => 64.0L [vehicle_length] => 179.5 in [vehicle_width] => 70.1 in [vehicle_height] => 66.9 in [curb_weight] => 3307.0 lbs ) 

Open in new window

I need to combine these 2 as json and insert into a DB column so it ends up looking like this:
{"checks":["horsepower","horsepower_rpm","torque","torque_rpm","fuel_capacity","vehicle_length","vehicle_width","vehicle_height","curb_weight"],"values":{"horsepower":"170.0","horsepower_rpm":"5800","torque":"174.0","torque_rpm":"4100","fuel_capacity":"64.0L","vehicle_length":"179.5 in","vehicle_width":"70.1 in","vehicle_height":"66.9 in","curb_weight":"3307.0 lbs"}}

Open in new window

any idea how I can get there? I've tried a few dozen different combinations but not working out at all.
Thanks as always.
SOLUTION
Avatar of Kim Walker
Kim Walker
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here is a PHP solution to the issue of unchecked checkboxes not coming through in the request.  You can pre-load $_POST with a default value in an identically named input control.  This gives you a more predictable set of input values.
https://www.experts-exchange.com/articles/5450/Common-Sense-Examples-Using-Checkboxes-with-HTML-JavaScript-and-PHP.html
Avatar of tjyoung
tjyoung

ASKER

Hi Julian,
Thanks for your additional note. In fact I am looking to remove the value if the checkbox isn't checked. I hadn't thought to even mention that when Kim had responded. Kim's formatted correctly but of course doesn't take removing values into account as per my oversight.

I ran your final solution and found that it does remove the values (in this case I unchecked both horsepower and horsepower RPM checkboxes).

Only problem was the end format isn't correct. I can't figure that out.

Here is the var_dump of the result

array(2) { ["checks"]=> array(7) { [0]=> string(6) "torque" [1]=> string(10) "torque_rpm" [2]=> string(13) "fuel_capacity" [3]=> string(14) "vehicle_length" [4]=> string(13) "vehicle_width" [5]=> string(14) "vehicle_height" [6]=> string(11) "curb_weight" } ["values"]=> array(7) { ["torque"]=> string(5) "145.0" ["torque_rpm"]=> string(4) "4200" ["fuel_capacity"]=> string(5) "55.0L" ["vehicle_length"]=> string(8) "174.0 in" ["vehicle_width"]=> string(7) "68.5 in" ["vehicle_height"]=> string(7) "57.7 in" ["curb_weight"]=> string(10) "3109.0 lbs" } } 

Open in new window

Going forward, you might want to use var_export() when posting data that others could use to help create a coding example.  Var_dump() makes a nice printout; var_export() creates a very similar representation, which also happens to be a PHP variable.  Facilitates copy/paste, reduces transcription errors, etc.
http://php.net/manual/en/function.var-export.php
I am looking to remove the value if the checkbox isn't checked
That should happen automatically; you shouldn't have to do anything special.

Here's the var-dump() formatted so it's easy to read.
array(2) { 
  ["checks"]=> array(7) { 
  [0]=> string(6) "torque" 
  [1]=> string(10) "torque_rpm" 
  [2]=> string(13) "fuel_capacity" 
  [3]=> string(14) "vehicle_length" 
  [4]=> string(13) "vehicle_width" 
  [5]=> string(14) "vehicle_height" 
  [6]=> string(11) "curb_weight" 
  } 
  ["values"]=> array(7) { 
  ["torque"]=> string(5) "145.0" 
  ["torque_rpm"]=> string(4) "4200" 
  ["fuel_capacity"]=> string(5) "55.0L" 
  ["vehicle_length"]=> string(8) "174.0 in" 
  ["vehicle_width"]=> string(7) "68.5 in" 
  ["vehicle_height"]=> string(7) "57.7 in" 
  ["curb_weight"]=> string(10) "3109.0 lbs" 
  } 
} 

Open in new window

Here's the link to the JSON reference.
http://json.org/

Here's a link to an article about using JSON in PHP and JavaScript.
https://www.experts-exchange.com/articles/22519/Understanding-JSON-in-PHP-and-JavaScript-Applications.html

The data in the var_dump() might merit a little discussion. PHP has two kinds of arrays, one has integer numeric keys and the other (often called "associative") has string keys, subject to the rules of loose type casting.  In the PHP var_dump() we can see both kinds of arrays.  The "checks" is a numerically indexed array, "values" is an associative array.  These two arrays are subsets of another associative array.

 JSON is a subset of JavaScript, and it obeys the rules of JavaScript.  JavaScript has only one kind of array: numerically indexed.  When there are named keys, it's not an array; it is a JavaScript object.  For this reason PHP json_encode() may appear to render an "unusual" data structure when it's applied to arrays with a mix of numeric and associative keys.

The data in the var_dump() output is redundant, and this leads to the likelihood that it could become internally inconsistent.  The "checks" array appears to be unnecessary; it has nothing but the names of the array keys that are present in the "values" array.  A smart design might omit the "checks" array completely, and just have the information in one data source.  Here is how I would probably do it.
https://iconoun.com/demo/temp_tjyoung.php
<?php // demo/temp_tjyoung.php
/**
 * https://www.experts-exchange.com/questions/28962021/Saving-2-arrays-into-one-combined-json-value-for-DB-column.html
 */
 
// ORIGINAL DATA REPRESENTATION?
/*
array(2) { 
  ["checks"]=> array(7) { 
  [0]=> string(6) "torque" 
  [1]=> string(10) "torque_rpm" 
  [2]=> string(13) "fuel_capacity" 
  [3]=> string(14) "vehicle_length" 
  [4]=> string(13) "vehicle_width" 
  [5]=> string(14) "vehicle_height" 
  [6]=> string(11) "curb_weight" 
  } 
  ["values"]=> array(7) { 
  ["torque"]=> string(5) "145.0" 
  ["torque_rpm"]=> string(4) "4200" 
  ["fuel_capacity"]=> string(5) "55.0L" 
  ["vehicle_length"]=> string(8) "174.0 in" 
  ["vehicle_width"]=> string(7) "68.5 in" 
  ["vehicle_height"]=> string(7) "57.7 in" 
  ["curb_weight"]=> string(10) "3109.0 lbs" 
  } 
} 
*/

// MORE CONCISE DATA REPRESENTATION
$values = 
[ "torque"         => "145.0" 
, "torque_rpm"     => "4200" 
, "fuel_capacity"  => "55.0L" 
, "vehicle_length" => "174.0 in" 
, "vehicle_width"  => "68.5 in" 
, "vehicle_height" => "57.7 in" 
, "curb_weight"    => "3109.0 lbs" 
]
;

// RENDERED AS A JSON STRING
$jso = json_encode($values, JSON_PRETTY_PRINT);

// SHOW THE ORIGINAL AND THE WORK PRODUCT
echo '<pre>';
print_r($values);
echo PHP_EOL;
print_r($jso);

Open in new window

Outputs:
Array
(
    [torque] => 145.0
    [torque_rpm] => 4200
    [fuel_capacity] => 55.0L
    [vehicle_length] => 174.0 in
    [vehicle_width] => 68.5 in
    [vehicle_height] => 57.7 in
    [curb_weight] => 3109.0 lbs
)

{
    "torque": "145.0",
    "torque_rpm": "4200",
    "fuel_capacity": "55.0L",
    "vehicle_length": "174.0 in",
    "vehicle_width": "68.5 in",
    "vehicle_height": "57.7 in",
    "curb_weight": "3109.0 lbs"
}

Open in new window

Here is my test script
<?php
$_POST['specs']['checks'] = array (
   "horsepower" => 1,
   "horsepower_rpm" => 1,
   "torque" => 1,
   "torque_rpm" => 1,
   "fuel_capacity" => 1,
   "vehicle_length" => 1,
   "vehicle_width" => 1,
   "vehicle_height" => 1,
   "curb_weight" => 1
 );

$_POST['specs']['values'] = array ( 
  "horsepower" => "170.0",
  "horsepower_rpm" => "5800",
  "torque" => "174.0",
  "torque_rpm" => "4100",
  "fuel_capacity" => "64.0L",
  "vehicle_length" => "179.5 in",
  "vehicle_width" => "70.1 in",
  "vehicle_height" => "66.9 in",
  "curb_weight" => "3307.0 lbs"
);
// EXPECTED
echo '{"checks":["horsepower","horsepower_rpm","torque","torque_rpm","fuel_capacity","vehicle_length","vehicle_width","vehicle_height","curb_weight"],"values":{"horsepower":"170.0","horsepower_rpm":"5800","torque":"174.0","torque_rpm":"4100","fuel_capacity":"64.0L","vehicle_length":"179.5 in","vehicle_width":"70.1 in","vehicle_height":"66.9 in","curb_weight":"3307.0 lbs"}}';
echo "<br/>";
// CORRECTED KIM SOLUTION
echo json_encode(array('checks'=>array_keys($_POST['specs']['checks']),'values'=>$_POST['specs']['values']) );


$result = array (
  'checks' => array(),
  'values' => array()
);
foreach($_POST['specs']['checks'] as $k => $v) {
  $result['checks'][] = $k;
  $result['values'][$k] = isset($_POST['specs']['values'][$k]) ? $_POST['specs']['values'][$k] : '';
}
// SOLUTION THAT ONLY INCLUDES SELECTED
echo "<br/>";
echo json_encode($result);

Open in new window


The output is
a) The JSON you posted as the target
b) Kim's solution - corrected with the array_keys addition
c) The output from my solution.
Output
{"checks":["horsepower","horsepower_rpm","torque","torque_rpm","fuel_capacity","vehicle_length","vehicle_width","vehicle_height","curb_weight"],"values":{"horsepower":"170.0","horsepower_rpm":"5800","torque":"174.0","torque_rpm":"4100","fuel_capacity":"64.0L","vehicle_length":"179.5 in","vehicle_width":"70.1 in","vehicle_height":"66.9 in","curb_weight":"3307.0 lbs"}}
{"checks":["horsepower","horsepower_rpm","torque","torque_rpm","fuel_capacity","vehicle_length","vehicle_width","vehicle_height","curb_weight"],"values":{"horsepower":"170.0","horsepower_rpm":"5800","torque":"174.0","torque_rpm":"4100","fuel_capacity":"64.0L","vehicle_length":"179.5 in","vehicle_width":"70.1 in","vehicle_height":"66.9 in","curb_weight":"3307.0 lbs"}}
{"checks":["horsepower","horsepower_rpm","torque","torque_rpm","fuel_capacity","vehicle_length","vehicle_width","vehicle_height","curb_weight"],"values":{"horsepower":"170.0","horsepower_rpm":"5800","torque":"174.0","torque_rpm":"4100","fuel_capacity":"64.0L","vehicle_length":"179.5 in","vehicle_width":"70.1 in","vehicle_height":"66.9 in","curb_weight":"3307.0 lbs"}}

Open in new window

Ray's suggestion above requires you duplicate the checkbox controls with a hidden control with the same name defaulting to 0 (I am assuming - I did not go too much into it). This will also work but it does mean you have to maintain a shadow set of controls - if you add a checkbox and then forget to add the shadow then you will not get the expected results.

The two solutions are a trade off - each has its pro's and cons - depending on your requirements.
Actually my suggestion was only if the author wanted the unchecked checkboxes (some people do), but now that we understand they are not wanted, then there is nothing special we need to do in order to omit them.  The HTTP request will omit them for us.

I think we might get to better answers here if we could see the original HTML form!
but now that we understand they are not wanted, then there is nothing special we need to do in order to omit them
... except there is a relationship between the check boxes and the actual values. If a checkbox is not checked then the value in the $_POST['specs']['values'] array must be ignored.

This can probably be achieved more efficiently but without knowing the exact requirement and seeing the rest of the code I am going to go with the the author's design and see how we can accommodate.
greetings tjyoung, , I see that you are dealing with the old problem of <form> checkboxes, and determining what was checked and getting a corresponding "Value" for ONLY the boxes with checks, in your checks you use a value of "1", I guess to show in the POST array that it has been checked (if it's there), but I have used another check box setup, that has a delimited "Key"  "Value" PAIR in the input value like -
     value="horsepower-170.5"
with a comma or dash string delimiter , so in thr PHP POST you just use the check boxes "name" for the POST, and then run through the POST array to get the checks "values" and then use the useful PHP explode( ) function yo separate your the "Key" "Value" pair from the string of the check box,

as the HTML checks may look lile -
horsepower of 170.5 <input type="checkbox" name="ckSpecs[]" value="horsepower-170.5"><br/>
horsepower rpm of 5825 <input type="checkbox" name="ckSpecs[]" value="horsepower_rpm-5825"><br/>
torque of 175.0 <input type="checkbox" name="ckSpecs[]" value="torque-175.0"><br/>
torque rpm of 4100 <input type="checkbox" name="ckSpecs[]" value="torque_rpm-4100"><br/>

Open in new window


and the PHP might be as -
if(!empty($_POST['ckSpecs'])) {
  $specs = array();
  foreach($_POST['ckSpecs'] as $val){
    $keyVal = explode("-", $val);
    $specs[$keyVal[0] => $keyVal[1] ];
    }


// and now in the $specs ARRAY you have ALL of the info you need as key value pairs
}

Open in new window



This is just my observation of the way you use the JSON to database, , I can NOT see as the first JSON Object with the -
    "checks":["horsepower","horsepower_rpm","torque","torque_rpm","fuel_capacity","vehicle_length","vehicle_width","vehicle_height","curb_weight"]

is usefull at all, since the second object as -
    "values":{"horsepower":"170.0","horsepower_rpm":"5800","torque":"174.0","torque_rpm":"4100","fuel_capacity":"64.0L","vehicle_length":"179.5 in","vehicle_width":"70.1 in","vehicle_height":"66.9 in","curb_weight":"3307.0 lbs"}

already has ALL of the KEYS in it, all of them, that are in the "checks" object information, so you do not need to duplicate information that you have in there already, at least that's my opinion, you could just build your JSON string with the second key value pairs object, and if you need the "checks" info, just get all of the KEYS from the "values" object
Avatar of tjyoung

ASKER

Sorry to take so long to get back. Had some family items to attend to in vancouver.
Appreciate the help.
You are welcome.