0

EDITED

Problem - A null value is written to the JSON file after the function runs.

Expectation - Capture data entered into HTML form, append it to an existing JSON file.

Some of the Stack resources I've used:

My JSON file looks like this:

{
"records": [
{"Date":"05/04/2016","Miles":168081,"Gallons":11.003,"Cost":28.60,"MPG":24.1,"Street":"5500 Mirage St","City":"Yorba Linda","State":"CA","Zip":92807,"Time":"07:04"},
{"Date":"04/18/2016","Miles":167815,"Gallons":10.897,"Cost":27.23,"MPG":25.7,"Street":"5500 Mirage St","City":"Yorba Linda","State":"CA","Zip":92807,"Time":"15:46"}
],
    "error" : false,
    "status" : 200
}

EDITED - My PHP script looks like this (update implements Chay's code):

<?php
  function runMyFunction() { 
    // #####
    if ($_SERVER['REQUEST_METHOD'] !== 'POST' && !isset($_POST)) { //You may add $_POST[post_name] for validation
        die('I need post method!');
    }

    // check if file exists
    $filename = 'mpg-data-file2.json';
    if ( ! file_exists($filename) ) {
        echo 'ERROR:' . $filename . ' not found' . '<BR>';
    } else {
        echo 'OK: ' . $filename . ' exists.' . '<BR>';

        $data = array(
                "Date"=> $_POST['mpg_date'],
                "Miles"=> $_POST['mpg_miles'],
                "Gallons"=> $_POST['mpg_gallons'],
                "Cost"=> $_POST['mpg_cost'],
                "MPG"=> $_POST['mpg_mpg'],
                "Street"=> $_POST['mpg_street'],
                "City"=> $_POST["mpg_city"],
                "State"=> $_POST['mpg_state'],
                "Zip"=> $_POST['mpg_zip'],
                "Time"=> $_POST['mpg_time']
            );

        //Load data from json file
        $dataFile = file_get_contents("mpg-data-file2.json");
        $dataFile = json_decode($str_data,true);

        //Merge data from post with data from file
        $formattedData = array_merge($dataFile['records'],$data);
        $formattedData = json_encode($formattedData);

        //If data from file is empty, just use data from post
        if (empty($dataFile)) {
           $formattedData = json_encode($data);
        }
        //Set a parent key
        $records['records'] = $formattedData;

        //Overwites everything
        /* $handle = fopen($filename,'a+');           
        fwrite($handle,$records);
        fclose($handle); */
            file_put_contents($filename,$records, FILE_APPEND | LOCK_EX);
        print_r($formattedData);
        echo 'OK: ' . '<BR>' . $records . '<BR>'; 
    }   
    // ##### 
  }//end runMyFunction
/*
  if (isset($_GET['hello'])) {
    runMyFunction();
  } */
  if(isset($_POST['mpg_date'],$_POST['mpg_date'],$_POST['mpg_miles'],$_POST['mpg_gallons'],$_POST['mpg_cost'],$_POST['mpg_mpg'],$_POST['mpg_street'],$_POST["mpg_city"],$_POST['mpg_state'],$_POST['mpg_zip'],$_POST['mpg_time'])) {
     runMyFunction($_POST);
 }
?>

An excerpt of the HTML form looks like this:

    <form action="_process.php" method="POST" role="form">
  <div class="form-group">
    <label for="mpg_date">Fuel Date:</label>
    <input type="text" class="form-control" id="mpg_date" name="mpg_date" placeholder="04/18/2016">
  </div>
  <div class="form-group">
    <label for="mpg_miles">Odometer (Miles):</label>
    <input type="number" min=”0″ step="any" class="form-control" id="mpg_miles" name="mpg_miles" placeholder="167815">
  </div>
  <!-- And so on... -->
  <div>
    <a href='_process.php?hello=true'>Run PHP Function</a>
    </div> 
</form>
Community
  • 1
  • 1

2 Answers2

0

This:

<a href='_process.php?hello=true'>Run PHP Function</a>

will actually submit your form. When you just link to the script that way rather than submitting the form, none of the $_POST values will be set.

It looks like your form just needs a submit button. You can put '_process.php?hello=true' into the form action if you want the if (isset($_GET['hello'])) { check to work.

In other words:

<form action="_process.php?hello=true" method="POST" role="form">
    <!-- All your inputs, etc. ...-->
    <input type="submit" value="Run PHP Function">
</form>

In order to append the new data to your existing JSON, you'll need to change the order that things happen in your function. The else part should be like this:

// First get the existing JSON from the file and decode it
$str_data = file_get_contents("mpg-data-file.json"); // Get the JSON string
$data = json_decode($str_data,true);// json_decode expects the JSON data, not a file name

// Then create a new data array from the $_POST data and add it to the 'records' key
$new_data = array(
    "Date"=> $_POST['mpg_date'],
    "Miles"=> $_POST['mpg_miles'],
    "Gallons"=> $_POST['mpg_gallons'],
    "Cost"=> $_POST['mpg_cost'],
    "MPG"=> $_POST['mpg_mpg'],
    "Street"=> $_POST['mpg_street'],
    "City"=> $_POST["mpg_city"],
    "State"=> $_POST['mpg_state'],
    "Zip"=> $_POST['mpg_zip'],
    "Time"=> $_POST['mpg_time']
);
$data['records'][] = $new_data;

// Then re-encode the JSON and write it to the file
$formattedData = json_encode($data);//format the data   
$handle = fopen($filename,'w+');//open or create the file           
fwrite($handle,$formattedData);//write the data into the file   
fclose($handle);//close the file
print_r($data);
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
0

I'm sure that your submission doesn't POST something since you're using anchor (without any javascript) to submit. In the other word, notice I change it to <button>.

<form action="_process.php" method="POST" role="form">
  <div class="form-group">
    <label for="mpg_date">Fuel Date:</label>
    <input type="text" class="form-control" id="mpg_date" name="mpg_date" placeholder="04/18/2016">
  </div>
  <div class="form-group">
    <label for="mpg_miles">Odometer (Miles):</label>
    <input type="number" min=”0″ step="any" class="form-control" id="mpg_miles" name="mpg_num" placeholder="167815">
  </div>
  <!-- And so on... -->
  <div>
    <button type="submit" role="button">Run PHP Function</button>
  </div> 
</form>

If you also noticed I also changed the second input name above to mpg_num. And this should be your backend looks.

...
...
if(isset($_POST['mpg_date'], $_POST['mpg_num'])) {
    runMyFunction($_POST);
}

Updated

if ($_SERVER['REQUEST_METHOD'] !== 'POST' && !isset($_POST)) { //You may add $_POST[post_name] for validation
    die('I need post method!');
}

// check if file exists
$filename = 'mpg-data-file.json';
if ( ! file_exists($filename) ) {
    echo 'ERROR:' . $filename . ' not found' . '<BR>';
} else {
    echo 'OK: ' . $filename . ' exists.' . '<BR>';

    $data = array(
            "Date"=> $_POST['mpg_date'],
            "Miles"=> $_POST['mpg_miles'],
            "Gallons"=> $_POST['mpg_gallons'],
            "Cost"=> $_POST['mpg_cost'],
            "MPG"=> $_POST['mpg_mpg'],
            "Street"=> $_POST['mpg_street'],
            "City"=> $_POST["mpg_city"],
            "State"=> $_POST['mpg_state'],
            "Zip"=> $_POST['mpg_zip'],
            "Time"=> $_POST['mpg_time']
        );

    //Load data from json file
    $dataFile = file_get_contents("mpg-data-file.json");
    $dataFile = json_decode($str_data,true);

    //Merge data from post with data from file
    $formattedData = array_merge($dataFile['records'],$data);

    //If data from file is empty, just use data from post
    if (empty($dataFile)) {
       $formattedData = $data;
    }
    //Set a parent key
    $records['records'] = $formattedData;
    $records['error'] = false;
    $records['status'] = 200;
    $records = json_encode($records);

    //Overwites everything
    $handle = fopen($filename,'w+');           
    fwrite($handle,$records);
    fclose($handle);

    print_r($records);        
}   

I hope this won't consume your environment RAM alot :)

Chay22
  • 2,834
  • 2
  • 17
  • 25
  • @Don't Panic suggested the submit button and it sends the data to the JSON file but the data is being overwritten not appended. – Generic Cog May 06 '16 at 21:07
  • Change `w+` to `a` or `a+` from `fopen($filename,'w+');` @GenericCog – Chay22 May 06 '16 at 21:16
  • Tried changing w+ to both 'a' and 'a+' however the data did not get written to the JSON file. – Generic Cog May 06 '16 at 21:44
  • Pass the post to the function parameter. – Chay22 May 06 '16 at 21:45
  • I tried your suggestion as well. Included the submit buton and changed the IF statement to $_POST for all fields, however, the file still has 'null' instead of the field values like so: ` if(isset($_POST['mpg_miles'],$_POST['mpg_gallons'],$_POST['mpg_cost'],$_POST['mpg_mpg'],$_POST['mpg_street'],$_POST["mpg_city"],$_POST['mpg_state'],$_POST['mpg_zip'],$_POST['mpg_time'])) { runMyFunction(); }` – Generic Cog May 06 '16 at 21:47
  • A lil update to code `runMyFunction($_POST)`. I actually recommend you to not using function such, rather than a-normal-procedural-code-without-function – Chay22 May 06 '16 at 21:49
  • 1
    Appending more JSON-encoded data directly to a JSON file typically will not produce valid JSON. – Don't Panic May 06 '16 at 22:01
  • Valid JSON is indeed an issue... [Here are the results](http://www.adamc.co/mpg/_process2.html) of this code: `{"records":{"Date":"04\/18\/2016","Miles":"167815","Gallons":"10.897","Cost":"27.23","MPG":"25.7","Street":"5500 Mirage St","City":"Yorba Linda","State":"CA","Zip":"92807","Time":"15:46"}}` – Generic Cog May 06 '16 at 22:24
  • @Don'tPanic You're right! Thanks for noticing it out! I've edited the post – Chay22 May 06 '16 at 22:42
  • @Chay22, your code helped to solve my question, however, I'll need to ask another question about ordering the JSON when it appends the data. Currently, the end of the file looks like this: `......], "error" : false, "status" : 200 }{"Date":"04\/18\/2016","Miles":"167815","Gallons":"10.897","Cost":"27.23","MPG":"25.7","Street":"5500 Mirage St","City":"Yorba Linda","State":"CA","Zip":"92807","Time":"9999"}` – Generic Cog May 07 '16 at 00:22