Sign inSign up

greicodex/corephp-vm

By greicodex

β€’Updated 2 months ago

Persistent, hardened PHP 8.4 runtime β€” RoadRunner + typed std library. Zero silent failures.

Image
0

2.2K

greicodex/corephp-vm repository overview

Greicodex ⁠

CorePHP Logo

⁠CorePHP β€” PHP 8.4 Base Docker Image

Build & Push Docs Docker Hub PHP 8.4 License: MIT

A production-grade, persistent PHP 8.4 runtime that brings JVM-like stability to PHP.

PHP traditionally re-initializes on every request. CorePHP eliminates this by running PHP inside RoadRunner as a long-lived process β€” just like the JVM. It also replaces PHP's silent-failure standard library with one that throws typed exceptions on every error.


⁠🐳 Pull from Docker Hub

# Latest stable release
docker pull greicodex/corephp-vm:latest

# Specific version
docker pull greicodex/corephp-vm:1.0.0

# Latest development build (main branch)
docker pull greicodex/corephp-vm:edge

Use as your base image:

FROM greicodex/corephp-vm:latest
COPY . /app

β πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Docker Container                   β”‚
β”‚                                                 β”‚
β”‚  RoadRunner (port 8080)                         β”‚
β”‚    └── worker.php (long-lived PHP process)      β”‚
β”‚          └── bootstrap.php (auto_prepend_file)  β”‚
β”‚                β”œβ”€β”€ Error handler β†’ ErrorExceptionβ”‚
β”‚                β”œβ”€β”€ FunctionOverrider (runkit7)  β”‚
β”‚                └── StrictObject                 β”‚
β”‚                                                 β”‚
β”‚  php.ini hardening                              β”‚
β”‚    β”œβ”€β”€ disable_functions (unserialize, exec...) β”‚
β”‚    β”œβ”€β”€ allow_url_fopen = Off                    β”‚
β”‚    └── runkit.internal_override = 1             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
⁠Three Enforcement Layers
LayerMechanismWhen
StaticPHPStan Level 9 + PHP-CS-FixerCI / pre-commit
Bootrunkit7 FunctionOverriderOnce at process startup
Runtimebootstrap.php error handlerEvery request

β πŸš€ Quick Start

⁠1. Use as a base image in your project
FROM greicodex/corephp-vm:latest

WORKDIR /app
COPY . .
RUN composer install --no-dev --optimize-autoloader

CMD ["rr", "serve", "-c", "/app/.rr.yaml"]
⁠2. Start with Docker Compose
services:
  app:
    image: greicodex/corephp-vm:latest
    ports:
      - "8080:8080"
    volumes:
      - .:/app
docker compose up -d

Your application is now running at http://localhost:8080.


β πŸ“¦ Standard Library (std)

All classes are under the core\ namespace and are automatically available via Composer autoload.

⁠Pillar 1 β€” Type-Safe Collections
use core\Internal\Array\TypedCollection;

// Class type enforcement
$users = new TypedCollection(User::class);
$users->add(new User('Alice')); // OK
$users->add('not a user');      // throws InvalidArgumentException immediately

// Primitive type enforcement
$ids = new TypedCollection('int');
$ids->add(42);    // OK
$ids->add('foo'); // throws InvalidArgumentException

// Iteration + filtering
foreach ($users as $user) {
    echo $user->name . PHP_EOL;
}
$admins = $users->filter(fn(User $u) => $u->isAdmin());
⁠Pillar 2 β€” HTTP Client (no silent failures)
use core\Net\Http\HttpClient;
use core\Net\Http\HttpException;

$client = new HttpClient(timeout: 10, strictStatus: true);

try {
    $response = $client->get('https://api.example.com/users');
    $users    = $response->json(associative: true);   // throws on non-JSON body
    $status   = $response->statusCode();               // 200
    $type     = $response->header('content-type');     // string or null

    // POST with JSON body (array β†’ auto-encoded)
    $created = $client->post('https://api.example.com/users', ['name' => 'Alice']);

} catch (HttpException $e) {
    // curl error, connection refused, timeout, or 4xx/5xx (in strictStatus mode)
}
⁠Pillar 3 β€” Global s_*() Function Shims

Backed by azjezz/psl⁠, these replace PHP's silent-failure built-ins. No use statement required β€” always available:

// JSON β€” throws on invalid input (never returns null/false)
$data = s_json('{"key":"value"}');       // array
$json = s_enc(['key' => 'value']);       // string
$json = s_enc(['key' => 'value'], true); // pretty-printed

// Type coercion β€” throws CoercionException (not silent 0)
$id  = s_int('42');    // 42
$id  = s_int('hello'); // throws CoercionException
$n   = s_float('3.14');
$str = s_str(42);      // "42"

// File I/O β€” throws on error (never returns false)
$contents = s_file('/etc/hostname');
$bytes    = s_write('/tmp/out.txt', 'hello');
$bytes    = s_append('/tmp/out.txt', ' world');

// Regex β€” throws on bad pattern (never returns false)
s_match('/^\d+$/', '123');           // true / false
s_regex('/(\d+)-(\d+)/', '10-99');  // ['10', '99'] or null

// Environment β€” throws if missing (never returns empty string silently)
s_env('APP_KEY');                    // string or throws
s_env_or('APP_ENV', 'production');  // string with fallback

// HTTP β€” throws HttpException on any failure
$r = s_get('https://api.example.com/users');
$r = s_post('https://api.example.com', ['name' => 'Alice']);

β πŸ”’ Security Hardening

⁠Disabled Functions (php.ini)

The following functions are permanently disabled at the PHP engine level:

unserialize, serialize, exec, shell_exec, system, passthru,
proc_open, popen, pcntl_exec, pcntl_fork, pcntl_signal,
posix_kill, posix_setuid, posix_setgid, dl, phpinfo,
symlink, link, putenv, ini_set, ini_restore, show_source, highlight_file
⁠runkit7 Native Function Overrides (boot-time)
FunctionOld FailureNew Behaviour
json_decode()returns nullthrows JsonException
json_encode()returns falsethrows JsonException
file_get_contents()returns falsethrows FileReadException
file_put_contents()returns falsethrows FileWriteException
intval()returns 0 silentlythrows TypeCoercionException
floatval()returns 0.0 silentlythrows TypeCoercionException
preg_match()returns falsethrows RegexException
preg_replace()returns nullthrows RegexException
curl_exec()returns falsethrows HttpException
base64_decode()returns falsethrows EncodingException

⁠🏠 Shared Hosting Mode (no Docker)

If you cannot use Docker (cPanel, Plesk), a subset of features is available via .user.ini:

FeatureDocker + RoadRunnerShared Hosting
Persistent processβœ…βŒ (restarts per request)
runkit7 overridesβœ…βŒ
bootstrap.php sandboxβœ…βœ…
StrictObjectβœ…βœ…
Global s_*() shimsβœ…βœ…
Error β†’ Exceptionβœ…βœ…

β πŸ“– Source & Documentation


⁠License

GPL-3.0 β€” see LICENSE⁠

Tag summary

Content type

Image

Digest

sha256:5ac10a7f7…

Size

67.6 MB

Last updated

2 months ago

docker pull greicodex/corephp-vm