Bitadir.com, one of the longest-running Spanish-language blog directories still online, has completed a comprehensive modernization of a web application that had been living in the PHP 4/5 era for roughly two decades. The platform, active since 1996 and described internally as a living archive of early Spanish blogging, has now been upgraded to PHP 8.4, alongside a security hardening package, a full responsive redesign, performance improvements, and a long list of legacy bug fixes—all while keeping the original architecture intact rather than rewriting everything from scratch.

The project reads like a case study in what still exists under the hood of many long-lived sites: custom frameworks, deprecated functions, table-based layouts, and authentication practices that were once common but are no longer defensible. In Bitadir’s case, the starting stack included an in-house framework (qFramework, dating back to 2004), Smarty 2 templates, MySQL 4/5-era assumptions, CSS2 and HTML tables for layout, and a password system based on unsalted MD5—a combination that, in modern terms, is a maintenance nightmare and a risk magnet.

A legacy codebase with real-world breakpoints

The modernization effort began by cataloguing the issues that would prevent the application from surviving in a modern hosting environment. On the PHP side, the list was familiar: old-style class constructors, use of var instead of visibility modifiers, pass-by-reference patterns that no longer behave the same way, and removed/deprecated functions such as each(), create_function() or get_magic_quotes_gpc(). Database access also showed its age, with legacy patterns tied to mysql_* and inconsistent input handling.

Bitadir.com brings a 1996-era web relic into 2026: from PHP 4/5 to PHP 8.4 in a full overhaul | bitadir 1997 directorio
Bitadir.com brings a 1996-era web relic into 2026: from PHP 4/5 to PHP 8.4 in a full overhaul

The security gap was even more urgent. Unsalted MD5 hashes are widely considered trivial to crack at scale, and the application lacked core safeguards that are now standard: brute-force protection, consistent SQL injection mitigation, HTTP security headers, and CSRF protection on forms. In other words, it wasn’t just “old”—it was operating with assumptions that the modern internet stopped forgiving years ago.

The migration strategy: modernize in place, file by file

Rather than rebuilding Bitadir as a new application, the approach was conservative and pragmatic: update the system incrementally, module by module, preserving the existing MVC structure and user-facing behaviour.

qFramework itself was upgraded “surgically” across core components—controllers, config, locale, HTTP client, pager utilities and database layers—bringing class design and runtime behaviour up to PHP 8.4 expectations. The code was rewritten where necessary to replace outdated object patterns with modern constructors and clearer encapsulation, removing reference returns and other brittle constructs.

For database compatibility, the project moved toward an ADOdb-compatible approach suitable for PHP 8.4, prioritising safer escaping and preparing the ground for broader adoption of prepared statements later. The documentation is explicit: while many queries were made safer immediately, a full migration to PDO/prepared statements is still listed as a recommended next step.

Bitadir.com brings a 1996-era web relic into 2026: from PHP 4/5 to PHP 8.4 in a full overhaul | bitadir 2026 directorio
Bitadir.com brings a 1996-era web relic into 2026: from PHP 4/5 to PHP 8.4 in a full overhaul

Security: from MD5 to bcrypt without forcing password resets

One of the most valuable upgrades is the new password subsystem. A dedicated qPassword class now uses bcrypt with a cost factor of 12, while also supporting a smooth transition from the legacy MD5 hashes. The key detail: migration happens transparently. When a user logs in with an old MD5 hash, the system verifies it and then automatically re-hashes the password using bcrypt, updating the database without interrupting the user.

That kind of “silent migration” matters in long-running services. It avoids mass password resets, reduces user friction, and steadily upgrades security across the user base as people log in naturally.

Alongside that, Bitadir introduced a rate limiter (qRateLimiter) focused on the most sensitive endpoints: user login, admin login, password recovery, and user registration. The default policy documented is strict enough to block common brute-force patterns: a small number of attempts in a defined time window, followed by a temporary lockout.

The hardening doesn’t stop there. The .htaccess layer adds multiple HTTP security headers (anti-clickjacking, anti-MIME sniffing, a referrer policy, and a Content Security Policy), plus HTTPS enforcement and stricter session cookie flags (HttpOnly and Secure). It’s the kind of checklist many old projects never got around to—until the modern web started demanding it.

A complete redesign: from tables and fixed width to responsive UI

Modernizing a legacy application often fails at the “last mile”: the interface. Bitadir tackled it head-on, replacing table layouts and fixed-width typography with a CSS system built on modern patterns: custom properties (variables), component-style UI blocks (cards, badges, alerts), and a mobile-first responsive layout using Flexbox and Grid.

Navigation was also rebuilt with usability in mind: a hamburger toggle on mobile, clearer active-section cues, breadcrumbs, and friendlier URL rewrites. Even small details—such as replacing old GIF icons with CSS-based folder icons—show a consistent focus on maintainability and performance, not just aesthetics.

Admin screens received special attention too, with redesigned tables, clearer status labels, and a filter panel that makes large directories manageable without feeling like a 2005 control panel.

Performance and caching: Redis when possible, disk when not

A hybrid caching system was introduced to stabilise performance and reduce database load. The architecture supports Redis when available, with a file-based cache as a reliable fallback. Cached datasets include categories, news blocks, latest blogs, and total counts, typically with a 24-hour TTL. The RSS cron job also clears and refreshes relevant caches automatically when feeds update.

Internal project metrics claim a dramatic improvement in day-to-day experience: faster load times, higher Lighthouse scores, and real mobile compatibility—shifting the site from a “works on desktop if you’re lucky” posture to something that feels viable in 2026.

The unglamorous but essential work: bug fixes and legacy quirks

Much of the modernization value comes from the bugs that had silently shaped the product for years. The changelog lists practical issues that users notice instantly: query parameters being dropped during pagination due to missing QSA flags, double slashes appearing in redirects, role filtering that prevented administrators from using the standard login, duplicated navigation menus in admin templates, and a classic copy/paste mistake that caused admin pages to show the wrong dataset.

One particularly telling detail: a page named /adminUsersList historically displayed blogs rather than users—an inherited design choice that the modernization preserved for compatibility, while also creating a new, genuinely user-focused admin listing where needed.

The acceleration factor: AI-assisted modernization and cost estimates

The project documentation highlights heavy use of an AI assistant to speed up the migration across dozens of files, citing approximately 62 modified files, around 4,800 updated lines, and roughly 600,000 tokens processed over 2 work sessions. Total hands-on time is reported at about 8 hours, including design, debugging, and documentation.

It also includes internal cost comparisons: estimates for a traditional rewrite (months and five figures), a manual migration (weeks), and the AI-assisted path (hours plus token costs). Those figures are framed as internal approximations rather than audited budgets, but they point to a broader reality: modern tooling can dramatically compress the calendar time required to keep old web infrastructure alive—if the work is scoped carefully and verified properly.

A 29-year-old platform built to survive another decade

Bitadir’s modernization is ultimately a reminder that “legacy” doesn’t have to mean “obsolete.” With incremental upgrades, careful security remediation, and a pragmatic focus on usability, a 1996-era directory can remain functional—and relevant—without losing what makes it historically valuable. In an internet that routinely forgets its own past, projects like this are not just maintenance jobs. They are preservation work, done with modern standards.


Frequently asked questions

How can a PHP 4/5 application be upgraded to PHP 8.4 without rewriting everything?
By modernizing incrementally: update the framework core first, replace deprecated PHP patterns, fix the most fragile runtime behaviours, and keep the architecture stable while migrating risky components (auth, database, routing) in stages.

What is the safest way to migrate unsalted MD5 passwords to bcrypt?
A transparent login-time migration: validate the legacy hash on login, then immediately re-hash using bcrypt and update the database, so accounts are upgraded without forcing mass password resets.

What baseline protections should a legacy login system add in 2026?
Rate limiting with lockouts, stricter session cookies, HTTPS enforcement, consistent input validation, and security headers. For admin access, adding 2FA is strongly recommended.

Is Redis required to make an old site fast after modernization?
Not necessarily. A hybrid cache design—Redis when available and file cache as fallback—can provide meaningful performance gains without making Redis a single point of failure.

Scroll to Top