FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index mod_harbour The Real Difference Between mod_harbour and PHP
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
The Real Difference Between mod_harbour and PHP
Posted: Fri Feb 20, 2026 11:21 AM

The real difference between mod_harbour and PHP is not the syntax.
It is not about <?php ?> or TEMPLATE / ENDTEXT.
The real difference is the way you think.

In a PRG-first model, you think:
β€œI am building a program that produces HTML.”
The focus is on logic. The program runs, processes data, and at the end it generates HTML as the result. This is how mod_harbour normally works. The code comes first, and the HTML is just the output.

In a Markup-first model, you think:
β€œI am building an HTML page that contains code.”
The focus is on the page structure and layout. Code is only added where dynamic content is needed. This is how PHP usually works.

Both systems send HTML to the browser in the end. The technical result is the same. The difference is only the mental starting point. In one model, the program is central and HTML is the product. In the other model, the page is central and code is a tool inside it.

An interesting point is that mod_harbour can support both models. It can also work in a markup-first style, where HTML is the default and Harbour code is embedded. This makes it mentally closer to PHP and can make a future transition easier.

For a Harbour developer, PRG-first often feels clearer, more structured, and more robust. For a web developer, Markup-first usually feels more natural and familiar.

In the end, it is less a technical question and more a question of mindset and the people who work with the system.

PHP – Markup-first
I am building an HTML page that contains code.

<html>
<body>

<?php
   // logic
?>

</body>
</html>

mod_harbour – PRG-first (Standard)
I am building a program that produces HTML.

PROCEDURE Main()

   // logic

TEMPLATE
<html>
<body>

   Hallo

</body>
</html>
ENDTEXT

RETURN

mod_harbour – Markup-first Mode
I am building an HTML page that contains Harbour code.

<html>
<body>

<?prg
   // logic
?>

</body>
</html>
Posts: 129
Joined: Mon Oct 17, 2005 03:03 AM
Re: The Real Difference Between mod_harbour and PHP
Posted: Fri Feb 20, 2026 02:23 PM

my mod_harbour is:

test.html

<html>
<body>

<?prg
   // logic
?>

</body>
</html>

This way, the code runs without any issues!!

and:
test.prg

<?prg
oLoader := TLoader():New()
oLoader:assign('page_start' , cPage_start ) // replace
oLoader:assign('page_end'   , cPage_end   ) // replace
oLoader:assign('body_before', cBody_before) // replace
oLoader:assign('body_after' , cBody_after ) // replace
oLoader:assign('head'       , cHead       ) // replace
oLoader:display('test.html')      // output
?>

This way of operation is the same as in PHP, where the code is enclosed with <?prg ... ?> instead of directly executing the .prg file.

I don’t like writing large amounts of HTML code directly inside a file (that’s really foolish!!). Since I use WYSIWYG web design tools to build my pages, it’s impossible for me to copy huge chunks of web content into a file and then add them line by line like:
cHtml += '<html>'....
cHtml += '<body>'.....

line ID: ssbbstw

WeChat ID: ssbbstw
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: The Real Difference Between mod_harbour and PHP
Posted: Fri Feb 20, 2026 02:51 PM

ssbbs, yes, it was exactly you who showed me this capability of mod_harbour. I just wanted to briefly mention the differences between PHP and mod_harbour.

Best regards, Otto

Posts: 129
Joined: Mon Oct 17, 2005 03:03 AM
Re: The Real Difference Between mod_harbour and PHP
Posted: Sat Feb 21, 2026 04:19 AM

On database connections, because mod_harbour does not support keep-alive connections, it has to repeatedly open and close connections, which results in slower performance compared to PHP...

line ID: ssbbstw

WeChat ID: ssbbstw
Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: The Real Difference Between mod_harbour and PHP
Posted: Sat Feb 21, 2026 06:50 AM

mod_harbour: Persistent or Not?

The Apache module itself is persistent. The application state per-request is not.

Think of it like mod_php β€” the interpreter stays loaded, but each request starts fresh.

Two versions in the codebase:

  • mod_harbour v1 (original FiveTech) β€” VM Persistent: No (hb_vmInit/hb_vmQuit + DLL load/unload per request) β€” State Persistent: No

  • mod_harbour v3 (Manu Exposito) β€” VM Persistent: Yes (hb_vmInit once in child_init) β€” State Persistent: No (per-request fresh thread context)

How mod_harbour v3 works:

  1. Apache child starts β†’ harbour_child_init() calls hb_vmInit(HB_FALSE) once β€” Harbour VM stays resident

  2. Each HTTP request β†’ hb_vmThreadInit(NULL) / hb_vmThreadQuit() β€” lightweight thread context, fresh execution

  3. Harbour globals/memvars β†’ reset per request (clean call stack each time)

  4. hPersistent hash β†’ the ONE mechanism for intentionally shared state across requests

mod_harbour v3 vs mod_php: Performance

  • VM startup β€” mod_harbour: Once per child process | mod_php: Once per child process

  • Per-request overhead β€” mod_harbour: hb_vmThreadInit (thread context only) | mod_php: RINIT/RSHUTDOWN (module init/shutdown)

  • Language speed β€” mod_harbour: Harbour compiles to C β†’ native machine code | mod_php: Interpreted bytecode (+ OPcache JIT)

  • Raw execution β€” mod_harbour: Faster β€” compiled, no interpreter overhead | mod_php: Slower β€” even with JIT, still bytecode-based

  • String handling β€” mod_harbour: C-level string ops | mod_php: Zend string engine (optimized but managed)

  • Memory model β€” mod_harbour: Direct C memory, manual management | mod_php: Zend MM with refcounting + GC

  • Concurrency β€” mod_harbour: Thread-pool (hb_vmThreadInit) | mod_php: Prefork (process per worker) or event MPM

  • Ecosystem/libraries β€” mod_harbour: Small β€” Harbour community | mod_php: Massive β€” Composer, frameworks, extensions

mod_harbour v3 is faster per-request because Harbour compiles .prg to native C code (via the Harbour compiler), so at runtime it executes machine instructions β€” not interpreted bytecode. PHP's OPcache + JIT (PHP 8.x) narrows the gap significantly, but a compiled language with direct memory access will always win on raw compute.

Database connections: Where PHP wins

However, raw execution speed is only part of the story. Database connectivity is where mod_harbour falls behind.

Because mod_harbour does not support keep-alive (persistent) database connections, every HTTP request must open a new connection to the database server and close it when done. This connect/disconnect cycle adds latency to every single request.

PHP, on the other hand, has built-in persistent connection support:

  • mysqli_pconnect / PDO ATTR_PERSISTENT β€” reuses existing database connections across requests without reconnecting

  • Connection pooling β€” frameworks and extensions like Swoole, ProxySQL, or pgBouncer can pool connections for even better throughput

  • Result β€” a PHP request hitting MySQL/MariaDB skips the TCP handshake + authentication entirely on subsequent requests

For database-heavy applications (which most web apps are), this single difference can negate mod_harbour's raw speed advantage entirely. A typical MySQL connection takes 5-10ms to establish. If your Harbour code runs in 2ms but spends 8ms connecting to the database, while PHP runs in 5ms but reuses an existing connection (0ms), PHP delivers the response faster.

The full picture:

  • CPU-bound tasks (calculations, string processing, image manipulation) β†’ mod_harbour wins

  • I/O-bound tasks (database queries, API calls β€” i.e., most web apps) β†’ PHP wins thanks to persistent connections

  • Ecosystem (libraries, developers, tooling, hosting) β†’ PHP wins by a landslide

Configuration example:

HarbourPersistentVM On        # Keep HVM loaded between requests
HarbourPreload .../*.hrb      # Pre-load framework classes at startup
HarbourSessionEnabled On
HarbourCacheEnabled On

Bottom line:

mod_harbour v3 = persistent interpreter, stateless requests β€” same model as mod_php but faster per-request on raw compute due to compiled execution. However, the lack of persistent database connections means that for real-world database-driven applications, PHP often delivers faster end-to-end response times. The VM + pre-loaded symbols stay in memory, each request gets a clean execution environment. Cross-request state requires explicitly using the hPersistent hash mechanism.

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: The Real Difference Between mod_harbour and PHP
Posted: Sat Feb 21, 2026 07:00 AM

The architecture already supports it. The hPersistent hash in mod_harbour v3 is the mechanism, but has not been wired database connections into it yet.

The idea is straightforward:

harbour_child_init() already creates pGD->hPersistent β€” a Harbour hash that lives for the entire Apache child process lifetime Store the database connection handle in that hash on first request Subsequent requests check hPersistent first β€” if a connection exists and is alive, reuse it In Harbour pseudocode:

FUNCTION GetConnection() LOCAL oConn

oConn := hb_HGetDef( hPersistent, "db_conn", NIL )

IF oConn == NIL .OR. !oConn:IsAlive() oConn := TMySQLConnect():New( cHost, cUser, cPass, cDB ) hPersistent[ "db_conn" ] := oConn ENDIF

RETURN oConn That's it. The connection survives across requests because hPersistent is never cleared β€” it lives as long as the Apache child process does (typically thousands of requests before Apache recycles the child).

What would need to be built: Connection pool manager β€” store N connections in hPersistent, hand them out per-thread, return them after hb_vmThreadQuit() Health check β€” detect dead connections (MySQL timeout, network drop) and reconnect Thread safety β€” the apr_thread_mutex already exists in pGD->lock, just needs to wrap the pool access Cleanup hook β€” harbour_child_exit() to close all pooled connections gracefully The gap today: Nobody has implemented this because most mod_harbour users come from desktop Harbour (DBF files, no SQL server) or use it for simple web pages where the connect/disconnect overhead is acceptable.

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 129
Joined: Mon Oct 17, 2005 03:03 AM
Re: The Real Difference Between mod_harbour and PHP
Posted: Sun Feb 22, 2026 04:40 AM
Bayron wrote:
FUNCTION GetConnection()
LOCAL oConn


oConn := hb_HGetDef( hPersistent, "db_conn", NIL )


IF oConn == NIL .OR. !oConn:IsAlive()
   oConn := TMySQLConnect():New( cHost, cUser, cPass, cDB )
   hPersistent[ "db_conn" ] := oConn
ENDIF


RETURN oConn

change to:

static oConn
FUNCTION GetConnection()
IF oConn == NIL .OR. !oConn:IsAlive()
   oConn := TMySQLConnect():New( cHost, cUser, cPass, cDB )
ENDIF

RETURN oConn
line ID: ssbbstw

WeChat ID: ssbbstw
Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: The Real Difference Between mod_harbour and PHP
Posted: Sun Feb 22, 2026 05:54 AM

Why mod_harbour v3's Persistence Isn't Enough for Production

mod_harbour v3 does have persistent state. The Harbour VM stays alive inside the Apache child process β€” your statics survive, your publics survive, your variables stay in memory between requests. That's a huge step up from CGI.

But raw persistence and production-grade persistence infrastructure are two very different things. mod_harbour v3 gives you a chunk of memory that stays alive. What you do with it is entirely up to you.

mod_harbour v3:     Request β†’ VM runs β†’ statics/publics survive β†’ next Request
                                        ↑
                              raw memory β€” you build everything yourself

mod_WebX:           Request β†’ VM runs β†’ hPersistent β†’ next Request
                                        ↑
                              code cache, DB pool, sessions,
                              rate limits, cache β€” organized, thread-safe,
                              with APIs and lifecycle management

What mod_harbour v3 gives you:

  • Harbour VM embedded in Apache (persistent across requests)

  • Static and public variables survive between requests

  • AP_RPuts(), AP_GetEnv(), AP_HeadersIn() β€” basic request/response

  • Raw building blocks β€” the rest is your problem

What mod_WebX builds on top of that persistence:

1. Compiled Code Cache
Your statics persist in v3, sure β€” but do you have automatic bytecode caching with file fingerprinting? mod_WebX stores compiled .hrb in hPersistent["codecache"], checks the file's date+time+size on each request, and only recompiles when the source actually changes. You get 20-80ms back on every request without writing a single line of cache management code.

2. Database Connection Pool
In v3 you could store a database connection in a static variable. But what about health checks? What if the connection drops? What about multiple named pools for different databases? mod_WebX provides hPersistent["dbpool"] with automatic health validation, named pools, usage stats, and clean teardown on shutdown. Connect once, reuse forever β€” without writing your own connection manager.

3. In-Memory Cache with TTL
In v3 you could stuff values into a static hash. But when do they expire? How do you track hit rates? mod_WebX provides hPersistent["cache"] with automatic TTL expiration, hit/miss statistics, and a "remember" pattern that only runs the expensive query when the cache is cold. Zero latency, zero serialization β€” no Redis server needed.

4. In-Memory Sessions
In v3 you could roll your own session system with statics. But you'd need to handle cookie generation, HttpOnly flags, SameSite policy, IP tracking, timeout eviction, and session ID regeneration after login (to prevent fixation attacks). mod_WebX provides all of this in hPersistent["sessions"] out of the box. No disk I/O, no file locking, no external session store.

5. Rate Limiting
This one you'd have to build from scratch in v3. Sliding window counters per IP, per endpoint, with configurable limits and automatic cleanup of old entries. mod_WebX provides hPersistent["ratelimit"] with named limits β€” 5 logins per 5 minutes, 60 API calls per minute, 10 uploads per hour β€” all in-process, zero latency.

6. Thread Safety
This is the one that bites you. In v3, if two requests hit the same static variable simultaneously, you have a race condition. mod_WebX wraps all persistent access in an APR mutex. Every read and write to hPersistent goes through a lock. You don't think about threading β€” it just works.

The Performance Gap:

Requests per second

  • mod_harbour v3 (raw): 50-100 req/s

  • mod_webx (with infrastructure): 520+ req/s

Response time

  • mod_harbour v3: 20-50ms (recompiling, reconnecting)

  • mod_webx: 2ms (cached code, pooled connections)

Memory usage (100 concurrent users)

  • mod_harbour v3 (naive): 200MB (no shared framework)

  • mod_webx: 5.6MB (600KB shared framework + 50KB per app)

Database connections (100 concurrent users)

  • mod_harbour v3 (no pool): 100 open/close cycles

  • mod_webx: 1 pooled connection, reused

Code compilation

  • mod_harbour v3 (no cache): Every request

  • mod_webx: Once, then fingerprint check only

Sessions

  • mod_harbour v3: Roll your own or use external store

  • mod_webx: Built-in, in-process, with security hardening

Rate limiting

  • mod_harbour v3: Not available (build from scratch)

  • mod_webx: Built-in, sliding window, per-endpoint

TL;DR

TL;DR

mod_harbour v3 gives you a persistent VM. That's the foundation β€” and it's good.

But between "my statics survive" and "I have a production web server" there's a massive gap: code caching, connection pooling, session management, cache TTL, rate limiting, and thread safety. That's what mod_WebX fills.

mod_harbour v3 = persistent engine
mod_WebX = persistent engine + transmission + fuel system + dashboard + safety systems

You can build all of this yourself on top of v3. But that's months of work, and you'll be solving problems (thread safety, session fixation, connection health checks, cache eviction) that have nothing to do with your actual application.

Standing on the shoulders of giants

None of this would exist without the work of Antonio Linares (mod_harbour) and Manu ExpΓ³sito (the v3 fork). Both are jewels of engineering β€” embedding a full Harbour VM inside Apache, with clean request handling and persistent state, is no small feat. They just never got the attention they deserve.

mod_WebX doesn't replace their work. It builds on it. The persistent VM is the foundation that makes everything else possible. We just added the production infrastructure that turns that foundation into something you can deploy without writing your own web framework from scratch.

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: The Real Difference Between mod_harbour and PHP
Posted: Sun Feb 22, 2026 07:32 AM

mod_harbour: Technology Without a Market

Before we discuss performance details, the issue of adoption and ecosystem needs to be addressed first. Without a solid user base, no system can be sustainable. And unfortunately, the Harbour developers have not yet presented a convincing solution for that.
The real question is: how do you bring thousands of existing FiveWin/harbour developers into the web world?
As Bayron mentioned, most FiveWin developers never even migrated from DBF to SQL. Expecting them to jump directly into modern web architecture is unrealistic. The problem is not technology β€” it’s transition.
This is where something like WebX from xBasePHP could potentially become relevant: not as a competitor to PHP or modern frameworks, but as a bridge. If FiveWin applications could be moved to a PHP-based web backend while preserving familiar Harbour/FiveWin syntax and development style, that would lower the barrier significantly.
The only realistic growth strategy for Harbour on the web is not competing head-to-head with mainstream stacks β€” it is offering an easy migration path for existing FiveWin applications.
Without that bridge, adoption will remain limited.
Best regards,
Otto

Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: The Real Difference Between mod_harbour and PHP
Posted: Sun Feb 22, 2026 07:11 PM

Thanks Otto for that insightful observation. You nailed the key points.

🛤️ The Journey
We started with an idea: create a way for Harbour to access the web. So we built new classes to do it. We got there β€” it worked. But then we recognized what we had actually created: a new product, not what was truly needed. Not the bridge you described.

Then HIX (beautiful engineering work from Carles Arubia) came along, and we thought β€” that's interesting, but it's still not the bridge either, because it means yet another learning curve for developers who already have thousands of lines of FiveWin code they don't want to rewrite.

💡 The Breakthrough
So we took a different approach entirely: translate existing FiveWin applications directly to PHP. Not rewrite. Not "learn a new framework." Translate.

Months ago we achieved that. We were able to transpile:

βœ… FiveDBU β€” a full database browser application
βœ… A complete Point-of-Sale system β€” ticket management, article browsing, family filtering, database relations, all running in a web browser
βœ… Mr. Alfredo Arteaga's ERP code β€” 150+ .prg files, at 97% success rate. Not yet a commercial turnkey product, but close.

These aren't demos. These are real applications with real DBF databases, real memo fields, real bitmap resources, real dialog layouts β€” running as native PHP in Apache.

👨‍👩‍👦‍👦 The Cousins
But then we realized something important: Harbour isn't alone. There are cousins β€” xBase++, Microsoft Visual FoxPro, xHarbour, and others.

And half a bridge is equal to no bridge. 99.9999999% is still not 100%

So we started adding support for those ecosystems as well. We already have VFP and a FoxPro 2.x preprocessor handling 97% of a real-world FoxPro codebase (205 files from a ERP production system).

🔬 More Than Translation
As you can see, we're not just doing a mechanical translation. This is a forensic study of what an xBase application actually needs to become web-acceptable:

🖼️ How do dialog resources map to HTML layouts?
📐 How do FiveWin pixel coordinates scale across screen resolutions?
🗄️ How do database work areas, aliases, and relations work in a stateless HTTP world?
⚑ How do codeblock closures, dynamic buttons, and AJAX interactions preserve state?
🎨 How do you handle bitmap resources embedded in .res files?
Every one of these required a specific engineering solution. And every one of them is invisible to the developer β€” their .prg code just works.

That's the bridge you are talking about. Not "learn something new." Instead:

Your code, on the web, now.
📊 Where We Stand
Realistically, we're about 80% there. And the transpiled code runs on every deployment target:

Target Status
Pure PHP βœ…
mod_apache βœ…
CGI βœ…
FastCGI βœ…
Standalone server βœ…
Desktop βœ…
All sharing the exact same source code, with excenption of PHP, that requires Harbour RTL transpiled to .PHP to back it up. It sounds absurd, but it's true.

Unfortunately, that remaining 20% doesn't mean 20% of the time. It may take longer than everything that came before it. The last mile is always the hardest.

🤔 "Why not release what you have now?"
Because everything is so internally interconnected that anything we change risks breaking what already works.

A product that breaks creates disgust, not clients.

We'd rather arrive late and solid than early and fragile.

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: The Real Difference Between mod_harbour and PHP
Posted: Sun Feb 22, 2026 07:20 PM

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Continue the discussion