Building Dynamic Websites with PHP & JSON
When I started rebuilding my portfolio, I wanted something faster than WordPress but simpler than a full MVC framework. The answer? PHP reading and writing JSON files.
Why JSON Over MySQL?
For content that updates weekly—not every second—flat files are perfect:
- Zero database latency (no connection overhead)
- Git-friendly (content is version-controlled)
- Portable (drag-and-drop to any host)
- Cache-friendly (OPcache loves static reads)
The Architecture
<?php
// core/JsonStore.php
class JsonStore {
private string $filePath;
public function __construct(string $filename) {
$this->filePath = __DIR__ . '/../data/' . $filename;
}
public function all(): array {
if (!file_exists($this->filePath)) return [];
$json = file_get_contents($this->filePath);
return json_decode($json, true) ?? [];
}
public function findBySlug(string $slug): ?array {
$items = $this->all();
return array_values(array_filter($items,
fn($item) => $item['slug'] === $slug
))[0] ?? null;
}
public function save(array $data): bool {
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
return file_put_contents($this->filePath, $json, LOCK_EX) !== false;
}
}
Usage in Your Pages
<?php
// blog.php
require_once 'core/JsonStore.php';
$blogStore = new JsonStore('posts.json');
$posts = array_filter($blogStore->all(), fn($p) => $p['published']);
// Sort by date descending
usort($posts, fn($a, $b) => strtotime($b['date']) - strtotime($a['date']));
?>
<?php foreach ($posts as $post): ?>
<article class="blog-card">
<h2><?= htmlspecialchars($post['title']) ?></h2>
<time datetime="<?= $post['date'] ?>"><?= date('M j, Y', strtotime($post['date'])) ?></time>
<p><?= htmlspecialchars($post['excerpt']) ?></p>
<a href="/post.php?slug=<?= urlencode($post['slug']) ?>">Read more →</a>
</article>
<?php endforeach; ?>
The Admin Interface
I built a simple admin panel that updates the JSON without touching code:
// admin.js - Save new post via fetch
async function savePost(postData) {
const response = await fetch('/api/save-post.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postData)
});
if (!response.ok) throw new Error('Save failed');
return await response.json();
}
When NOT to Use This
Don't use JSON storage if:
- You have multiple concurrent editors
- You need complex relational queries
- Content exceeds ~10,000 entries
The Result
My site now loads in under 200ms with zero database connections. For a portfolio and blog, that's perfect.
Sometimes the best database is no database at all.