En vous promenant sur Beamreactor, nous stockons votre IP 48h pour des raisons de sécurité.
BeamReactor Workbench
BeamReactor
System:
BeamReactor 3.0
Workbench 2.1
Mem: 0.5 MB
Time: 08:45:14

Lecteur Markdown

Knowledge Base › BEAMREACTOR_INCLUDES

Beamreactor Includes

BeamReactor – Global Includes #

> Version: 1.0

> Audience: BeamReactor core developers and integrators

> Scope: Include system architecture, authoring rules, installation discipline

1. What Are Global Includes?

Global includes are lightweight PHP files that run on every single request, regardless of which page or plugin is being loaded. They are not plugins. They have no URL, no UI, and no plugin lifecycle. They are pure execution hooks — tasks the engine must carry out unconditionally as it processes any incoming request.

Typical responsibilities:

  • Security enforcement — IP ban checking, anomaly detection, bot analysis
  • Session monitoring — authenticated session health, timeout warnings
  • Passive data collection — request statistics, geolocation, active users
  • Housekeeping — stale data cleanup (probabilistic via rand())
  • UI injection — toast system initialization, informational banners

2. Engine Startup and Include Execution

When a request enters the XDP engine (index.php), the engine starts by loading configuration (user/conf/cog.php), which defines all global variables including $cfg, $headdata, $footdata, and the $inc_allowed whitelist. The engine then iterates through $inc_allowed in declaration order:

php
// index.php
if(isset($inc_allowed))
{
	foreach($inc_allowed as $objINC)
	{
		$incfile = 'inc/'.$objINC;
		if(is_file($incfile)) include($incfile);
	}
	unset($objINC, $incfile);
}

This loop completes before any plugin, page, or HTML output is produced. At this point, no <html> has been echoed. Includes that append to $headdata, $footdata, or $cfg['body'] do so safely because those buffers are rendered later by HeaderHandler.

Order matters. Includes that depend on a function set by an earlier include (e.g. isBanned(), defined by ban.inc.php) must appear after it in $inc_allowed. The canonical boot order is:

php
$inc_allowed = [
	'ban.inc.php',		   // 1. IP ban gate — must be first
	'geos.inc.php',		  // 2. Geolocation (depends on IP being clean)
	'hax.inc.php',		   // 3. Intrusion heuristics
	'stats.inc.php',		 // 4. Request statistics
	// ... subsequent includes may depend on all of the above
];

3. Authorization: Configuration Before Installation

> � ️ This rule is mandatory and non-negotiable.

An include file that exists on disk but is not listed in $inc_allowed is never executed. Dropping a file into inc/ does not activate it. Only the whitelist in user/conf/cog.php grants execution rights.

The required installation sequence is therefore:

Step 1 — Authorize (edit user/conf/cog.php):

php
$inc_allowed = [
	'ban.inc.php', 'geos.inc.php', /* ... existing entries ... */
	'my_include.inc.php'   // ← add the entry FIRST
];

Step 2 — Deploy (create inc/my_include.inc.php):

php
<?php
if(!function_exists('isBanned')) return;
// ... logic
?>

This order enforces a deliberate review step before any code runs. Authoring the file first and hoping the engine picks it up is not acceptable — it bypasses the authorization layer and makes the inclusion accidental rather than intentional.

If the file does not exist when the engine reaches its entry in $inc_allowed, it is silently skipped (is_file() check). This is a safety net, not the intended workflow.

4. Writing a Global Include

4.1 Required Guard #

Every include must open with a dependency guard. Because includes run before most of the engine is initialized, a direct call (e.g. via the filesystem) would have no defined functions. The guard ensures the include is running inside the engine:

php
if(!function_exists('isBanned')) die('forbidden');

Use die('forbidden') for this specific guard — not return. On a shared hosting environment, a direct HTTP or filesystem call to an inc/ file would silently pass through a return, potentially exposing partial logic or globals. die() makes out-of-context execution impossible.

return is correct for conditional early exits further down in the include, where the engine context is confirmed and you simply have nothing to do (e.g. wrong page type, user not authenticated, condition not met).

4.2 Error Page Exclusion #

Includes that have side effects on the UI or database should skip error pages:

php
if(stripos($cfg['obj'] ?? '', '.err') !== false) return;

4.3 Early Exit Conditions #

Return as early as possible. Condition-based early exit keeps execution fast for the majority of requests where the include has nothing to do:

php
// Example: only run for authenticated users
if(!secure(0)) return;

// Example: only run 1 in 40 requests (probabilistic housekeeping)
if(rand(0, 40) !== 0) return;

4.4 Complete skeleton #

php
<?php
/**
 * XDP [name] include
 *
 * [One-line description of what this include does.]
 *
 * @subpackage Includes
 * @author	 [Author]
 * @copyright  [Year] [Author]
 * @version	1.0.0
 * @since	  [Year]
 * @date	   [Date]
 */

// Security gate — die() is mandatory here, not return.
// Prevents any execution if the file is called directly (shared hosting, misconfiguration).
if(!function_exists('isBanned')) die('forbidden');

// Early exit conditions — return is correct from here on (engine context is confirmed).
// Skip error pages
if(stripos($cfg['obj'] ?? '', '.err') !== false) return;

// Early exit condition (example)
if(empty($cfg['dbtable'])) return;

// Logic
// ...
?>

5. Injection Points

Includes have access to the three global output buffers that HeaderHandler will render later in the request. All three are plain strings — append with .=.

| Buffer | Rendered location | Typical use |

|---|---|---|

| $headdata | Inside <head> | <style>, <script>, <link> |

| $cfg['body'] | Immediately after <body> | Visible HTML (banners, overlays) |

| $footdata | End of <body> | <script src="...">, deferred JS |

php
// Inject a stylesheet
$headdata .= '<link rel="stylesheet" href="path/to/style.css">';

// Inject a top-of-page banner
$cfg['body'] = ($cfg['body'] ?? '') . '<div id="my-banner">...</div>';

// Inject a deferred script
$footdata .= '<script src="javascript/my_module.js"></script>';

Note: $cfg['body'] may not be initialized at the point the include runs. Always use the null-coalescing concatenation pattern shown above.

6. Available Globals

At the time includes run, the following are guaranteed to be available:

| Variable | Description |

|---|---|

| $cfg | Full engine configuration array |

| $cfg['obj'] | Requested object identifier (e.g. home.php, 403.err) |

| $cfg[0] | Base URL |

| $cfg[1] | Site name |

| $cfg['dbtable'] | Member table name (empty if membership disabled) |

| $headdata | HTML head buffer (string) |

| $footdata | HTML foot buffer (string) |

| $cfg['skin'] | Active skin name |

| $_SESSION | PHP session |

| $_COOKIE | PHP cookies |

| ipCheck() | Returns the verified client IP |

| isBanned() | Checks whether an IP is banned |

| secure() | Checks user permission level by string constant name |

7. Existing Includes Reference

| File | Purpose | Runs when |

|---|---|---|

| ban.inc.php | Enforces IP ban list; redirects to 403 | Always (first) |

| geos.inc.php | Geolocation lookup and logging | Always |

| hax.inc.php | Intrusion heuristics and attack detection | Always |

| stats.inc.php | Records request to stats table (deferred INSERT) | Always |

| botsniffer.inc.php | Bot and crawler identification | Always |

| currentUsers.inc.php | Active user count tracking | Always |

| tidy.inc.php | Probabilistic cleanup of unactivated accounts | ~1/40 requests |

| defense_logs.inc.php | Security event logging | Always |

| rss_gc.inc.php | RSS cache garbage collection | Probabilistic |

| displayWarnings.inc.php | Toast system injection (authenticated users) | Authenticated |

| scattags.inc.php | Tag scatter/scatter-cache operations | Always |

| session_warning.inc.php | Session timeout warning JS injection | Authenticated |

| ip_notice.inc.php | Top-of-page IP storage notice banner | Until cookie set |

8. Hard Rules

  • ✅ Use die('forbidden') for the security guard at the top (out-of-context protection)
  • ✅ Use return for all conditional early exits below the guard
  • ❌ Never use die() for anything other than the security guard
  • ❌ Never assume $cfg['body'] is initialized — always use ?? or isset()
  • ❌ Never produce output directly (echo, print) — use $headdata, $footdata, $cfg['body']
  • ❌ Never include plugin files or external libs from inside an include
  • ❌ Never deploy the file before updating $inc_allowed
  • ✅ Guard with if(!function_exists(...)) return;
  • ✅ Skip error pages with .err check when appropriate
  • ✅ Respect declaration order in $inc_allowed (dependencies first)
  • ✅ Keep execution cost minimal — includes run on every request

Includes are not plugins. They are responsibilities the engine carries on every request. That is why they require explicit authorization.

BeamReactor v3.0 • AmigaOS Workbench 2.1 Tribute • 2026