A complete CRUD application. Using JSON as a database, PHP, and JavaScript for theme switching.

To understand how a CRUD system works using PHP and JSON

CRUD runs the Internet

Create Read Update Delete. The four operations that run the entire internet. Every website that allows users to upload photos, comments, videos, music, etc. are using systems that allow you to create data.

It changed the internet from purely authored by the maker to allowing people to contribute on a massive scale. Of course this isn’t just limited to social media, though.

There are thousands of CRUD tutorials and videos online, but these usually include frameworks. As an academic challenge I wanted to get to the core of exactly how simple a server-side CRUD system could be.

Hypothesis

Create

To me the obvious first step was I figuring out a way for users to create something. So… that means forms!

The web is filled with text-inputs that allow users to create things. You might not think of text-inputs as forms, but that’s what they are. You type in some text, click the send/submit/done/enter button which takes that piece of text and sends it somewhere.

Look at all of those forms! That’s all they are behind the scenes, some text-inputs with a submit button wrapped in a form.

Every form needs a way for the sent data from the user to be saved so it can later be read somewhere else. JSON is a pretty popular format, and it seemed to tick all of the boxes for storing data, so I figured I’d give that a shot for my database.

Read

I’ll need to get that sent data from the user, read it, and then display it in some fashion.

Luckily PHP just creates HTML so that should be relatively easy. I should in theory be able to look at each item in my JSON database and create HTML based on that information with PHP.

Update

I can use the same form that give the user the functionality to create data. But instead of creating an item in the JSON Database, I need to find the exact comment the user wants to edit and make sure only that specific one is edited.

Delete

Deleting a comment should have a similar functionality to updating a comment. If a user clicks something to delete a comment I need to make sure only that specific one is deleted in the JSON file.

Challenges

Overwriting comments

What I wanted to do was make each comment it’s own object like so:

{
 "items": {
    "name": "Brian",
    "comment": "Hello world!",
    "date": "2022-04-02 20:25:09",
    "uniqueid": "5a677fa0f2",
 }
}

This was working great with the first comment, but the issue was when a new comment was created whatever was previously in the database would be overwritten by the new comment.

My solution to this was to go a level deeper. Right now the JSON Structure has items containing a single object, with that single object representing a comment.

But, if I had the items object containing keys with the comment object as values to those keys, then I would just be appending a bunch of keys rather than an entire object.

So, now my JSON structure looked like this:

{
 "items": {
    "bdf66eb086": {
       "name": "Brian",
       "comment": "Hello world!",
       "date": "2022-04-02 20:25:09",
       "uniqueid": "5a677fa0f2",
    },
    "5a677fa0f2": {
       "name": "Winston",
       "comment": "Hello Hello!!!",
       "date": "2022-04-08 00:00:12",
       "expireDate": "2022-04-08 00:05:12",
       "prettyDate": "April 8, 2022, 12:00 am"
    }
  }
}

Awesome! Instead of having the uniqueid as a key inside of the object, I made it the key to the entire comment object. Now I can create new comments, and then find a comment to update or delete based on the key of the comment object.

JSON to PHP conversion

I was able to add things to the JSON file, but now I needed to edit existing things inside of the JSON file.

PHP can’t loop through a JSON file. In fact, it can’t do anything to a JSON file. You need to convert it to something PHP something does know about. Like… an array!

PHP has a function to retrieve the contents of any file with file_get_contents(). This stores the JSON data inside of variable.

We can take that variable and pass it into another built-in function, json_decode(). What this does is directly translate the JSON syntax into an associative array, something PHP can easily handle.

Awesome, it’s just an associative array (technically a multidimensional associative array)! Now I can easily loop through all of the comments and do the delete and update operations.

I can take the id of the comment the user wants to delete, loop through all of the comments in the array, find the one with the specific id, and then unset() that specific comment.

If a user wants to update a comment, I can loop through all of the comments, find the comment with the correct id, and then replace its contents with the new values entered into the form. Awesome!!!

PHP to JSON

So, this is all fine and dandy but I need to save all of this newly created / updated / deleted data back to the JSON file.

PHP has a built in function similar to json_decode() called json_encode(). I’m sure you can imagine what that does! It takes the associative array I’ve made all of the changes to and then transforms it back into JSON.

Now all that’s left is to save the newly updated JSON to a file. Again, PHP has a built-in function for this file_put_contents(), where it’ll take any form of data and put it directly into a file.

In this case I assigned the json_encode() contents to a variable, so all I needed to do was file_put_contents('comments.json', $jsonEncodedFile) and boom! The “database” was updated with the new values.

It works!

I’m able to:

  • Capture user input (Create)
  • Format it into an array
  • Get the contents of the JSON
  • Decode the JSON to an array
  • Append the user input to that array
  • Encode the array back to JSON
  • Save the new JSON to the comments.json file, overwriting whatever was previously there

There’s reusable functionality here that can apply to Updating and Deleting comments.

For example, with updating a comment:

  • Capture the id of the comment to update, and the data entered by the user
  • Get the contents of the JSON
  • Decode the JSON to an array
  • Loop through every comment until the id captured matches an id in the JSON file
  • Take the new data entered by the user and overwrite whatever was there
  • Encode the array back to JSON
  • Save the new JSON to the comments.json file, overwriting whatever was previously there

The same thing can be said for deleting a comment with a few steps modified.

Figuring out the workflow for one thing lead the way for the rest of the operations needed in the project.

What I learned

It’s uncommon for someone to build a “CRUD app” with just PHP and JSON as the database. I had to figure out a lot of the workflow on my own. Figuring out how to create and append a new item to the JSON file was an “ah-ha” moment. I knew exactly what was happening, and all I did was apply the same concept to the update and delete parts.

One of the most beneficial things I learned was code reusability. I noticed the same 4 things happening over, and over, and over:

  • Get the contents of the JSON file.
  • Decode the JSON structure to a PHP array.
  • insert CRUD operation stuff here
  • Encode the PHP array back to a JSON structure.
  • Put the contents into a file.

I ended up taking 4 of those steps and breaking them into 2 functions.

Function 1: Getting the comments

This requires 2 steps, getting the contents from the .json file, decoding the contents, and then returning the resulting associative array.

function getComments() {
  $json = file_get_contents("comments.json");
  $jsonToAssociativeArray = json_decode($json, true);
  return $jsonToAssociativeArray;
}

Since this returns an associative array I can do something like this:

$comments = getComments()["items"];

Now $comments contains an associative array of every single comment.

The getComments() function was referenced seven times throughout the entire codebase, and the codebase is pretty small.

This function is called when:

  • Adding a comment (create)
  • Displaying the comments back to the user (read)
  • Updating a comment (update)
  • Deleting a comment (delete)

Literally every single CRUD operation requires this function.

Function 2: Encoding the comments

The last step in the process to ensure all of the CRUD operations work properly is to take the modified PHP Array and transform it back into JSON.

Take the updated $data  (like when the user creates a comment, updates a comment, or deletes a comment), transform it into JSON, then put that JSON into a file called ‘comments.json’, or whatever filename you want.

function encodeComments($data) {
   $json = json_encode($data, JSON_PRETTY_PRINT);
   file_put_contents("comments.json", $json);
}

This function was referenced four times, and every reference to it is inside of another function.

Taking repetitive code and abstracting it away into their own functions was a nice learning experience for me, and I’ve already started using this mindset towards other projects.

Next Steps

I think an interesting problem would be to figure out how to reply to a comment. It would use all of the same functions as the other CRUD operations, but you’d need to go one level deeper, I think.

Maybe each comment would have a reply key with an empty object as its value to start off, and whenever someone replied on that post you could insert that comment into that empty object.

I’d love to hear what you think, send me a tweet! https://twitter.com/bdlowery2