../courses.php
CRM
CRM101
90
Contacts And Customers
Understand how a CRM stores people, companies, emails, phone numbers, and relationships.
Adding a new contact through an HTML form, then reloading the page, shows the new contact correctly. Reloading it a second time still shows it. What actually made the new contact stick around, when nothing about the page itself changed?
The form submission didn't just display the new contact — it triggered PHP to read the existing JSON file, add the new contact to the array in memory, and write that whole array back out to the same file on disk. The page reloading and still showing it isn't the form "remembering" anything — it's PHP reading the file fresh every single time, and the file itself now actually contains the new contact, because it was genuinely rewritten.
Lecture 1 only read contacts. A real CRM needs to add them too — which means going beyond reading JSON to actually writing it back out, the missing half of the read/write pair that earlier JSON lessons covered conceptually.
An HTML form's
<input name="name">
sends its value to PHP, where it shows up in
$_POST['name']
— the bridge between something a person typed in a browser and a value PHP can actually use.
Adding to a PHP array works the same way it did for JavaScript arrays in an earlier course —
$contacts[] = $newContact;
appends a new item onto the end, the PHP equivalent of
.push().
json_encode()
is the reverse of
json_decode()
from lecture 1 — it turns a PHP array back into JSON text, ready to be written to a file, the same round trip
JSON.stringify()
performed for JavaScript data in an earlier course.
This lesson adds a form to the page from lecture 1, and the PHP logic that actually appends a new contact to the JSON file when that form is submitted — the first genuinely new capability layered onto the foundation.
The CRM, stage two: a form that actually adds a contact
<?php
$contactsFile = __DIR__ . '/contacts.json';
$contacts = json_decode(file_get_contents($contactsFile), true);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$contacts[] = [
'name' => $_POST['name'],
'email' => $_POST['email']
];
file_put_contents($contactsFile, json_encode($contacts));
}
?>
<form method="POST">
<input name="name" placeholder="Name">
<input name="email" placeholder="Email">
<button type="submit">Add Contact</button>
</form>
<?php foreach ($contacts as $contact) { ?>
<div><?php echo $contact['name']; ?></div>
<?php } ?>
if ($_SERVER['REQUEST_METHOD'] === 'POST') — Checks whether this page load is a normal visit or an actual form submission — the code inside only runs on submission, not every time the page loads.
$contacts[] = [...] — Appends a new associative array — one contact, with its own
name
and
email
keys — onto the existing
$contacts
array, the exact same shape every contact in the JSON file already has.
$_POST['name'] — Reads whatever was typed into the form's
name field, matched by the
name="name"
attribute on the actual
<input> tag — the names on both sides have to match exactly for this to work.
file_put_contents($contactsFile, json_encode($contacts)); — This is the actual answer to the question at the top of this lesson: the full, updated array is turned back into JSON text and written to the same file, completely replacing whatever was there before.
The display loop runs after the write — Because the
foreach
loop comes after the form-handling code, it always shows the freshest version of
$contacts — including a contact that was just added a moment earlier in this exact same page load.
Writing the whole array back, not just the new contact, is what makes this work
file_put_contents() always overwrites the entire file with whatever string it's given — there's no way to "append one contact" directly to a JSON file, which is exactly why the full array has to be read, modified in memory, and written back out in its entirety.
A mismatched input name silently breaks the form
If the input were written as
name="fullname"
but the PHP read
$_POST['name'], the form would submit successfully with no error at all, and the new contact would simply have an empty name field — nothing crashes, the mistake just produces quietly wrong data.
The page reloads after submitting because that's how a plain HTML form works
Without any JavaScript involved, submitting this form sends a full new request to the same page, and PHP runs from the top again — which is exactly why the write-then-read order inside the file matters: the read for display has to happen after the write, not before it.
Unvalidated form input ends up directly in the stored data
Submitting the form with the email field left completely blank still works without error — the contact gets added with an empty string for
email, since nothing in this version actually checks that the field was filled in before writing it to the file.
This read-modify-write pattern is the shape every later lecture in this course reuses
Adding a task, updating a status, or removing a contact later in this course all follow the exact same three steps as this lesson: read the JSON, change the array in memory, write the whole thing back — only what changes inside the array differs.
Trusting form input with no validation — avoid
$contacts[] = [
'name' => $_POST['name'],
'email' => $_POST['email']
];
Checking for an empty name before adding it — use this
if (trim($_POST['name']) !== '') {
$contacts[] = [
'name' => $_POST['name'],
'email' => $_POST['email']
];
}
Paste your PHP form-handling code into ChatGPT and ask: "Does this check for an empty name before adding the contact, and could the form's input names ever mismatch what PHP is actually reading from $_POST?" It's good at spotting a missing check, though actually submitting the form with an empty field yourself is the fastest way to confirm what really happens.
Add the form from this lesson to your lecture-1 page, and confirm a new contact actually appears in the JSON file after submitting.
Submit the form with the name field left empty, and observe what actually gets written to the file.
Add the empty-name check from the good_code example, and confirm an empty submission no longer adds anything.
Deliberately mismatch one input's
name attribute against what PHP reads from
$_POST, and confirm the form still submits without error, just with missing data.
Open
contacts.json directly in a text editor after adding two new contacts, and confirm both are actually present in the file.
Assuming
file_put_contents() appends to a file, when it actually overwrites the entire thing — which is exactly why the full array has to be read and rewritten, not just the new piece.
Mismatching an input's
name attribute against the key read from
$_POST, producing a contact with a silently missing field instead of an error.
Adding form input directly to the stored data with no check for an empty or missing value first.
Forgetting that
json_encode() is the reverse of
json_decode(), and writing the in-memory array directly to the file without encoding it back into JSON text first.
Reading the JSON file for display before the form-handling code has run, instead of after, and missing the contact that was just added in the same page load.
Read a form submission in PHP, append a new item to an in-memory array, and write that array back to a JSON file — completing the read-modify-write pattern this entire course builds on.
Login - Jit4All
Login
Welcome back to Jit4All