diff --git a/README.md b/README.md index 34821f0..159aea6 100644 --- a/README.md +++ b/README.md @@ -707,4 +707,4 @@ sudo apt install php-cli php-sockets MIT — see [LICENSE](LICENSE). -Part of the [Qbix Platform](https://github.com/Qbix/Platform). \ No newline at end of file +Part of the [Qbix Platform](https://github.com/Qbix/Platform). diff --git a/build-binary.sh b/build-binary.sh index d944517..dcd66e0 100644 --- a/build-binary.sh +++ b/build-binary.sh @@ -11,7 +11,7 @@ # - Docker (for cross-compilation) or local build tools # - ~2GB disk space for the build # -# Output: bin/qbix-server (or bin/qbix-server-$OS-$ARCH) +# Output: bin/qbixserver (or bin/qbixserver-$OS-$ARCH) # set -e @@ -85,12 +85,12 @@ build_with_static_php_cli() { php -d phar.readonly=0 "$SCRIPT_DIR/build-phar.php" echo "Combining micro.sfx + PHAR..." - cat "$MICRO_SFXN" "$BIN_DIR/qbix-server.phar" > "$BIN_DIR/qbix-server" - chmod +x "$BIN_DIR/qbix-server" + cat "$MICRO_SFXN" "$BIN_DIR/qbixserver.phar" > "$BIN_DIR/qbixserver" + chmod +x "$BIN_DIR/qbixserver" echo "" - echo "Binary built: $BIN_DIR/qbix-server" - ls -lh "$BIN_DIR/qbix-server" + echo "Binary built: $BIN_DIR/qbixserver" + ls -lh "$BIN_DIR/qbixserver" } # ── Method 2: Docker-based build ───────────────── @@ -125,24 +125,24 @@ RUN spc download --with-php=8.3 --for-extensions=pcntl,sockets,openssl,mbstring, RUN spc build pcntl,sockets,openssl,mbstring,filter --build-micro # Combine -RUN cat buildroot/bin/micro.sfx bin/qbix-server.phar > bin/qbix-server && \ - chmod +x bin/qbix-server +RUN cat buildroot/bin/micro.sfx bin/qbixserver.phar > bin/qbixserver && \ + chmod +x bin/qbixserver FROM scratch -COPY --from=builder /build/bin/qbix-server /qbix-server +COPY --from=builder /build/bin/qbixserver /qbix-server DOCKERFILE - docker build -t qbix-server-builder "$TMPDIR" - docker create --name qbix-extract qbix-server-builder - docker cp qbix-extract:/qbix-server "$BIN_DIR/qbix-server" + docker build -t qbixserver-builder "$TMPDIR" + docker create --name qbix-extract qbixserver-builder + docker cp qbix-extract:/qbixserver "$BIN_DIR/qbixserver" docker rm qbix-extract - docker rmi qbix-server-builder 2>/dev/null || true + docker rmi qbixserver-builder 2>/dev/null || true rm -rf "$TMPDIR" echo "" - echo "Binary built: $BIN_DIR/qbix-server" - ls -lh "$BIN_DIR/qbix-server" + echo "Binary built: $BIN_DIR/qbixserver" + ls -lh "$BIN_DIR/qbixserver" } # ── Method 3: Manual build (fallback) ──────────── @@ -156,7 +156,7 @@ build_manual() { echo " Method A: curl -sL https://github.com/crazywhalecc/static-php-cli/... | tar xz" echo " Method B: $0 --docker" echo "" - echo "The PHAR works identically: php bin/qbix-server.phar --port=8080" + echo "The PHAR works identically: php bin/qbixserver.phar --port=8080" } # ── Choose build method ────────────────────────── diff --git a/build-phar.php b/build-phar.php index 4ac7788..c582422 100644 --- a/build-phar.php +++ b/build-phar.php @@ -1,13 +1,13 @@ #!/usr/bin/env php startBuffering(); // Add source files @@ -43,12 +43,12 @@ $phar->buildFromIterator( $stub = <<<'STUB' #!/usr/bin/env php null, 'app' => null, @@ -66,7 +66,7 @@ foreach ($argv as $i => $arg) { if ($i === 0) continue; if ($arg === '--help' || $arg === '-h') { echo "Qbix Server v" . QBIX_SERVER_VERSION . " (PHAR)\n\n"; - echo "Usage: php qbix-server.phar [options]\n\n"; + echo "Usage: php qbixserver.phar [options]\n\n"; echo " --root=DIR Document root (default: ./web)\n"; echo " --app=DIR Qbix app directory\n"; echo " --host=IP Bind address (default: 0.0.0.0)\n"; @@ -127,6 +127,6 @@ $phar->stopBuffering(); chmod($pharFile, 0755); $size = filesize($pharFile); -echo "Built: bin/qbix-server.phar (" . round($size / 1024) . " KB)\n"; -echo "Run: php bin/qbix-server.phar --root=./web --port=8080\n"; -echo "Or: chmod +x bin/qbix-server.phar && ./bin/qbix-server.phar --port=8080\n"; +echo "Built: bin/qbixserver.phar (" . round($size / 1024) . " KB)\n"; +echo "Run: php bin/qbixserver.phar --root=./web --port=8080\n"; +echo "Or: chmod +x bin/qbixserver.phar && ./bin/qbixserver.phar --port=8080\n"; diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..e631b3c --- /dev/null +++ b/composer.json @@ -0,0 +1,25 @@ +{ + "name": "qbix/server", + "description": "Pure PHP web server — static files, PHP execution, WebSocket, live dashboard", + "type": "project", + "license": "MIT", + "keywords": ["server", "http", "webserver", "php", "static", "websocket"], + "homepage": "https://github.com/Qbix/Server", + "require": { + "php": ">=8.1", + "ext-sockets": "*" + }, + "require-dev": { + "revolt/event-loop": "^1.0" + }, + "suggest": { + "ext-pcntl": "Required for graceful shutdown (SIGTERM/SIGINT) and --workers=N", + "ext-openssl": "Required for HTTPS/TLS support", + "revolt/event-loop": "Enables Revolt event loop driver (epoll/kqueue, better performance under high concurrency)", + "amphp/http-server": "Enables HTTP/2 support with multiplexed streams and HPACK compression" + }, + "autoload": { + "classmap": ["src/"] + }, + "bin": ["qbixserver.php"] +} diff --git a/qbixserver.phar b/qbixserver.phar index d0adcc8..a84fc55 100644 Binary files a/qbixserver.phar and b/qbixserver.phar differ diff --git a/qbixserver.php b/qbixserver.php index 871230c..fc93906 100644 --- a/qbixserver.php +++ b/qbixserver.php @@ -3,8 +3,8 @@ /** * Qbix Server — pure PHP web server. * - * Standalone: php server.php --root=./web --port=8080 - * With Qbix: php server.php --app=/path/to/myapp --port=8080 + * Standalone: php qbixserver.php --root=./web --port=8080 + * With Qbix: php qbixserver.php --app=/path/to/myapp --port=8080 * * Options: * --root=DIR Document root (default: ./web) @@ -38,7 +38,7 @@ foreach ($argv as $i => $arg) { if ($i === 0) continue; if ($arg === '--help' || $arg === '-h') { echo "Qbix Server v" . QBIX_SERVER_VERSION . "\n\n"; - echo "Usage: php server.php [options]\n\n"; + echo "Usage: php qbixserver.php [options]\n\n"; echo "Options:\n"; echo " --root=DIR Document root (default: ./web)\n"; echo " --app=DIR Qbix app directory (uses full Q framework)\n"; @@ -200,19 +200,21 @@ Q_WebServer::$onRequest = function ($method, $uri, $status, $ms) use ($colors, $ // ── Start server ──────────────────────────────────── +$W = 38; // inner width of the box + echo "\n"; -echo " ┌──────────────────────────────────────┐\n"; -echo " │ Qbix Server v" . QBIX_SERVER_VERSION . str_repeat(' ', 22 - strlen(QBIX_SERVER_VERSION)) . "│\n"; -echo " ├──────────────────────────────────────┤\n"; -echo " │ http://{$opts['host']}:{$opts['port']}" . str_repeat(' ', max(0, 24 - strlen("{$opts['host']}:{$opts['port']}"))) . "│\n"; -echo " │ Root: " . basename($webDir) . str_repeat(' ', max(0, 29 - strlen(basename($webDir)))) . "│\n"; -echo " │ Mode: " . ($qbixMode ? 'Qbix Platform' : 'Standalone') . str_repeat(' ', $qbixMode ? 16 : 19) . "│\n"; -echo " │ PHP: " . ($opts['workers'] ? $opts['workers'] . ' workers' : 'in-process') . str_repeat(' ', max(0, 30 - strlen($opts['workers'] ? $opts['workers'] . ' workers' : 'in-process'))) . "│\n"; -echo " ├──────────────────────────────────────┤\n"; -echo " │ Dashboard: /Q/dashboard │\n"; -echo " │ Health: /Q/health │\n"; -echo " │ Ctrl+C to stop │\n"; -echo " └──────────────────────────────────────┘\n"; +echo " ┌" . str_repeat('─', $W) . "┐\n"; +echo " │" . str_pad(" Qbix Server v" . QBIX_SERVER_VERSION, $W) . "│\n"; +echo " ├" . str_repeat('─', $W) . "┤\n"; +echo " │" . str_pad(" http://{$opts['host']}:{$opts['port']}", $W) . "│\n"; +echo " │" . str_pad(" Root: " . basename($webDir), $W) . "│\n"; +echo " │" . str_pad(" Mode: " . ($qbixMode ? 'Qbix Platform' : 'Standalone'), $W) . "│\n"; +echo " │" . str_pad(" PHP: " . ($opts['workers'] ? $opts['workers'] . ' workers' : 'in-process'), $W) . "│\n"; +echo " ├" . str_repeat('─', $W) . "┤\n"; +echo " │" . str_pad(" Dashboard: /Q/dashboard", $W) . "│\n"; +echo " │" . str_pad(" Health: /Q/health", $W) . "│\n"; +echo " │" . str_pad(" Ctrl+C to stop", $W) . "│\n"; +echo " └" . str_repeat('─', $W) . "┘\n"; echo "\n"; Q_WebServer::start( diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index 081e53c..0000000 Binary files a/src/.DS_Store and /dev/null differ diff --git a/src/Q/Evented/Revolt.php b/src/Q/Evented/Revolt.php index c8ee40c..d9c34b2 100644 --- a/src/Q/Evented/Revolt.php +++ b/src/Q/Evented/Revolt.php @@ -1,30 +1,87 @@ running = true; + EventLoop::run(); + $this->running = false; + } + + function tick($timeout = 0) + { + EventLoop::delay($timeout ?: 0.0, function () {}); + EventLoop::run(); + } + + function stop() + { + $this->running = false; + } + + function running() + { + return $this->running; } - function cancel($id) { \Revolt\EventLoop::cancel($id); } - function disable($id) { \Revolt\EventLoop::disable($id); } - function enable($id) { \Revolt\EventLoop::enable($id); } - function run() { $this->running = true; \Revolt\EventLoop::run(); $this->running = false; } - function tick($t = 0) { \Revolt\EventLoop::delay($t?:0.0,function(){}); \Revolt\EventLoop::run(); } - function stop() { $this->running = false; } - function running() { return $this->running; } }