From 2f040a9dcf5b92c2fed601f8dc3b0d7aa86bfdc6 Mon Sep 17 00:00:00 2001 From: Sharif Date: Sun, 5 Apr 2026 00:27:29 +0600 Subject: [PATCH] =?UTF-8?q?feat:=20remove=20serveDirectory()=20=E2=80=94?= =?UTF-8?q?=20use=20serveFromDisk()=20for=20production?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the PHP built-in web server approach (serveDirectory) that caused firewall prompts and port conflicts on consumer PCs. serveFromDisk() is the correct production method — no ports, no extra processes, uses native platform URI schemes (phpgui:// on Linux, virtual host on Windows, loadFileURL on macOS). Co-Authored-By: Claude Sonnet 4.6 --- src/Widget/WebView.php | 100 ----------------------------------------- 1 file changed, 100 deletions(-) diff --git a/src/Widget/WebView.php b/src/Widget/WebView.php index 383925a..8506041 100644 --- a/src/Widget/WebView.php +++ b/src/Widget/WebView.php @@ -20,10 +20,6 @@ class WebView private string $id; private bool $debug; - /** @var resource|null PHP built-in server process for serveDirectory() */ - private $serverProcess = null; - private ?int $serverPort = null; - /** @var array JS→PHP command handlers: name => callback(string $id, string $args) */ private array $commandHandlers = []; @@ -86,74 +82,6 @@ public function setHtml(string $html): void $this->process->sendCommand(['cmd' => 'set_html', 'html' => $html]); } - /** - * Serve a directory via PHP's built-in web server and navigate to it. - * - * Ideal for loading production frontend builds (e.g., Vite's dist/ folder). - * - * @param string $path Path to the directory containing index.html - * @param int $port Port to use (0 = auto-pick a free port) - */ - public function serveDirectory(string $path, int $port = 0): void - { - $path = realpath($path); - if (!$path || !is_dir($path)) { - throw new \RuntimeException("Directory not found: {$path}"); - } - if (!file_exists($path . '/index.html')) { - throw new \RuntimeException("No index.html found in: {$path}"); - } - - // Auto-pick a free port - if ($port === 0) { - $sock = @stream_socket_server('tcp://127.0.0.1:0', $errno, $errstr); - if (!$sock) { - throw new \RuntimeException("Could not find a free port: {$errstr}"); - } - $addr = stream_socket_get_name($sock, false); - $port = (int) substr($addr, strrpos($addr, ':') + 1); - fclose($sock); - } - - // Start PHP built-in server - $cmd = sprintf( - '%s -S 127.0.0.1:%d -t %s', - PHP_BINARY, - $port, - escapeshellarg($path) - ); - - $descriptors = [ - 0 => ['pipe', 'r'], - 1 => ['pipe', 'w'], - 2 => ['pipe', 'w'], - ]; - - $this->serverProcess = proc_open($cmd, $descriptors, $pipes); - if (!is_resource($this->serverProcess)) { - throw new \RuntimeException("Failed to start local server on port {$port}"); - } - $this->serverPort = $port; - - // Close stdin, we don't need it - fclose($pipes[0]); - fclose($pipes[1]); - fclose($pipes[2]); - - // Wait for server to be ready (up to 3 seconds) - $deadline = microtime(true) + 3.0; - while (microtime(true) < $deadline) { - $fp = @fsockopen('127.0.0.1', $port, $errno, $errstr, 0.1); - if ($fp) { - fclose($fp); - break; - } - usleep(50000); // 50ms - } - - $this->navigate("http://127.0.0.1:{$port}"); - } - /** * Serve a directory directly via the native webview engine (no HTTP server). * @@ -310,14 +238,6 @@ public function enableFetchProxy(): void JS); } - /** - * Get the port of the local server started by serveDirectory(). - */ - public function getServerPort(): ?int - { - return $this->serverPort; - } - /* ── Window ──────────────────────────────────────────────────────────── */ /** @@ -425,7 +345,6 @@ public function emit(string $event, mixed $payload = null): void */ public function destroy(): void { - $this->stopServer(); $this->process->close(); } @@ -564,7 +483,6 @@ private function handleCommand(array $event): void public function __destruct() { - $this->stopServer(); if (!$this->isClosed()) { $this->destroy(); } @@ -653,22 +571,4 @@ private function streamRequest(string $url, string $method, array $headers, ?str return [$status, $resHeaders, $resBody]; } - private function stopServer(): void - { - if ($this->serverProcess && is_resource($this->serverProcess)) { - $status = proc_get_status($this->serverProcess); - if ($status['running']) { - // Kill the server process tree - $pid = $status['pid']; - if (PHP_OS_FAMILY === 'Windows') { - exec("taskkill /F /T /PID {$pid} 2>NUL"); - } else { - exec("kill {$pid} 2>/dev/null"); - } - } - proc_close($this->serverProcess); - $this->serverProcess = null; - $this->serverPort = null; - } - } }