diff --git a/app/process/Http.php b/app/process/Http.php new file mode 100644 index 0000000..f462c3a --- /dev/null +++ b/app/process/Http.php @@ -0,0 +1,10 @@ +paths = (array)$monitorDir; $this->extensions = $monitorExtensions; + foreach (get_included_files() as $index => $file) { + $this->loadedFiles[$file] = $index; + if (strpos($file, 'webman-framework/src/support/App.php')) { + break; + } + } if (!Worker::getAllWorkers()) { return; } @@ -134,13 +145,17 @@ class Monitor } // check mtime if (in_array($file->getExtension(), $this->extensions, true) && $lastMtime < $file->getMTime()) { + $lastMtime = $file->getMTime(); + if (DIRECTORY_SEPARATOR === '/' && isset($this->loadedFiles[$file->getRealPath()])) { + echo "$file updated but cannot be reloaded because only auto-loaded files support reload.\n"; + continue; + } $var = 0; exec('"'.PHP_BINARY . '" -l ' . $file, $out, $var); - $lastMtime = $file->getMTime(); if ($var) { continue; } - echo $file . " update and reload\n"; + echo $file . " updated and reload\n"; // send SIGUSR1 signal to master process for reload if (DIRECTORY_SEPARATOR === '/') { posix_kill(posix_getppid(), SIGUSR1); diff --git a/composer b/composer index c85d4cc..965bad1 100755 --- a/composer +++ b/composer @@ -4,8 +4,8 @@ read -r -d '' DOCKER_COMMAND <<'EOF' docker run --rm \ -v "$(pwd)":/app \ -w /app \ -quay.io/wandoubaba517/php:8.2-workerman \ -composer +quay.io/wandoubaba517/php:8.3-workerman \ +composer EOF # 检查是否有传递参数,并将它们附加到命令的末尾 diff --git a/composer.json b/composer.json index 49bc99c..f6617e2 100644 --- a/composer.json +++ b/composer.json @@ -25,8 +25,9 @@ }, "require": { "php": ">=7.2", - "workerman/webman-framework": "^1.5.0", - "monolog/monolog": "^3.5" + "workerman/webman-framework": "^1.6.6", + "monolog/monolog": "^2.0", + "workerman/workerman": "^4.2.1" }, "suggest": { "ext-event": "For better performance. " @@ -52,5 +53,7 @@ "pre-package-uninstall": [ "support\\Plugin::uninstall" ] - } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/composer.lock b/composer.lock index 49a338d..5f642e0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,45 +4,52 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c02c3a666509c2442d4834e05169b0ea", + "content-hash": "afbf9db9e4592c74428dc015992026ea", "packages": [ { "name": "monolog/monolog", - "version": "3.7.0", + "version": "2.10.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8" + "reference": "5cf826f2991858b54d5c3809bee745560a1042a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8", - "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8", - "shasum": "" + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5cf826f2991858b54d5c3809bee745560a1042a7", + "reference": "5cf826f2991858b54d5c3809bee745560a1042a7", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { - "php": ">=8.1", - "psr/log": "^2.0 || ^3.0" + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "provide": { - "psr/log-implementation": "3.0.0" + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" }, "require-dev": { - "aws/aws-sdk-php": "^3.0", + "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2.0", - "guzzlehttp/guzzle": "^7.4.5", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", + "guzzlehttp/guzzle": "^7.4", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4 || ^3", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "^10.5.17", - "predis/predis": "^1.1 || ^2", + "phpspec/prophecy": "^1.15", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.5.38 || ^9.6.19", + "predis/predis": "^1.1 || ^2.0", + "rollbar/rollbar": "^1.3 || ^2 || ^3", "ruflin/elastica": "^7", + "swiftmailer/swiftmailer": "^5.3|^6.0", "symfony/mailer": "^5.4 || ^6", "symfony/mime": "^5.4 || ^6" }, @@ -65,7 +72,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -93,7 +100,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.7.0" + "source": "https://github.com/Seldaek/monolog/tree/2.10.0" }, "funding": [ { @@ -105,7 +112,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T09:40:51+00:00" + "time": "2024-11-12T12:43:37+00:00" }, { "name": "nikic/fast-route", @@ -119,7 +126,13 @@ "type": "zip", "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", "reference": "181d480e08d9476e61381e04a71b34dc0432e812", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.4.0" @@ -169,7 +182,13 @@ "type": "zip", "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.4.0" @@ -212,17 +231,23 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "79dff0b268932c640297f5208d6298f71855c03e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", - "shasum": "" + "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", + "reference": "79dff0b268932c640297f5208d6298f71855c03e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.0" @@ -256,30 +281,25 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.1" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-08-21T13:31:24+00:00" }, { "name": "workerman/webman-framework", - "version": "v1.5.20", - "source": { - "type": "git", - "url": "https://github.com/walkor/webman-framework.git", - "reference": "6fcbf1b2a2eb448a09d1cbe44fdc4deb1516f7f8" - }, + "version": "v1.6.6", "dist": { "type": "zip", - "url": "https://api.github.com/repos/walkor/webman-framework/zipball/6fcbf1b2a2eb448a09d1cbe44fdc4deb1516f7f8", - "reference": "6fcbf1b2a2eb448a09d1cbe44fdc4deb1516f7f8", + "url": "https://mirrors.cloud.tencent.com/repository/composer/workerman/webman-framework/v1.6.6/workerman-webman-framework-v1.6.6.zip", + "reference": "9a89995796acff015d303f3a7eda62e0a6a5a361", "shasum": "" }, "require": { "ext-json": "*", "nikic/fast-route": "^1.3", - "php": ">=7.2", + "php": ">=8.0", "psr/container": ">=1.0", - "workerman/workerman": "^4.0.4 || ^5.0.0" + "workerman/workerman": "^4.2.1 || ^5.0.0 || dev-master" }, "suggest": { "ext-event": "For better performance. " @@ -295,7 +315,6 @@ "Support\\Exception\\": "./src/support/exception" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -313,31 +332,19 @@ "High Performance", "http service" ], - "support": { - "email": "walkor@workerman.net", - "forum": "https://wenda.workerman.net/", - "issues": "https://github.com/walkor/webman/issues", - "source": "https://github.com/walkor/webman-framework", - "wiki": "https://doc.workerman.net/" - }, - "time": "2024-07-04T07:12:58+00:00" + "time": "2024-11-25T06:39:00+00:00" }, { "name": "workerman/workerman", - "version": "v4.1.16", - "source": { - "type": "git", - "url": "https://github.com/walkor/workerman.git", - "reference": "405d904d33026e19497dffc3d085bbc16e66534e" - }, + "version": "v4.2.1", "dist": { "type": "zip", - "url": "https://api.github.com/repos/walkor/workerman/zipball/405d904d33026e19497dffc3d085bbc16e66534e", - "reference": "405d904d33026e19497dffc3d085bbc16e66534e", + "url": "https://mirrors.cloud.tencent.com/repository/composer/workerman/workerman/v4.2.1/workerman-workerman-v4.2.1.zip", + "reference": "cafb5a43d93d7d30a16b32a57948581cca993562", "shasum": "" }, "require": { - "php": ">=7.0" + "php": ">=8.0" }, "suggest": { "ext-event": "For better performance. " @@ -348,7 +355,6 @@ "Workerman\\": "./" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -366,35 +372,18 @@ "asynchronous", "event-loop" ], - "support": { - "email": "walkor@workerman.net", - "forum": "http://wenda.workerman.net/", - "issues": "https://github.com/walkor/workerman/issues", - "source": "https://github.com/walkor/workerman", - "wiki": "http://doc.workerman.net/" - }, - "funding": [ - { - "url": "https://opencollective.com/workerman", - "type": "open_collective" - }, - { - "url": "https://www.patreon.com/walkor", - "type": "patreon" - } - ], - "time": "2024-07-04T08:26:39+00:00" + "time": "2024-11-24T11:45:37+00:00" } ], "packages-dev": [], "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, + "minimum-stability": "dev", + "stability-flags": {}, + "prefer-stable": true, "prefer-lowest": false, "platform": { "php": ">=7.2" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..13b94e6 --- /dev/null +++ b/config/cache.php @@ -0,0 +1,30 @@ + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +return [ + 'default' => 'file', + 'stores' => [ + 'file' => [ + 'driver' => 'file', + 'path' => runtime_path('cache') + ], + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default' + ], + 'array' => [ + 'driver' => 'array' + ] + ] +]; diff --git a/config/log.php b/config/log.php index 6f1f3d7..7f05de5 100644 --- a/config/log.php +++ b/config/log.php @@ -20,7 +20,7 @@ return [ 'constructor' => [ runtime_path() . '/logs/webman.log', 7, //$maxFiles - Monolog\Level::Debug, + Monolog\Logger::DEBUG, ], 'formatter' => [ 'class' => Monolog\Formatter\LineFormatter::class, diff --git a/config/process.php b/config/process.php index f94d27f..892dc82 100644 --- a/config/process.php +++ b/config/process.php @@ -12,12 +12,32 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ +use support\Log; +use support\Request; +use app\process\Http; + global $argv; return [ + 'webman' => [ + 'handler' => Http::class, + 'listen' => 'http://0.0.0.0:8787', + 'count' => cpu_count() * 4, + 'user' => '', + 'group' => '', + 'reusePort' => false, + 'eventLoop' => '', + 'context' => [], + 'constructor' => [ + 'requestClass' => Request::class, + 'logger' => Log::channel('default'), + 'appPath' => app_path(), + 'publicPath' => public_path() + ] + ], // File update detection and automatic reload 'monitor' => [ - 'handler' => process\Monitor::class, + 'handler' => app\process\Monitor::class, 'reloadable' => false, 'constructor' => [ // Monitor these directories diff --git a/config/server.php b/config/server.php index f55ce3c..238f1aa 100644 --- a/config/server.php +++ b/config/server.php @@ -13,14 +13,6 @@ */ return [ - 'listen' => 'http://0.0.0.0:8787', - 'transport' => 'tcp', - 'context' => [], - 'name' => 'webman', - 'count' => cpu_count() * 4, - 'user' => '', - 'group' => '', - 'reusePort' => false, 'event_loop' => '', 'stop_timeout' => 2, 'pid_file' => runtime_path() . '/webman.pid', diff --git a/php b/php index 9a76f74..e42078b 100755 --- a/php +++ b/php @@ -9,12 +9,12 @@ cd "$SCRIPT_DIR" || exit 1 # 使用heredoc构建docker run命令 read -r -d '' DOCKER_COMMAND <<'EOF' docker run --rm \ ---network host \ +-p 8787:8787 \ -v "$(pwd)":/app \ -v "$(pwd)/php.ini":/usr/local/etc/php/php.ini \ -w /app \ -quay.io/wandoubaba517/php:8.2-workerman \ -php +quay.io/wandoubaba517/php:8.3-workerman \ +php EOF # 检查是否有传递参数,并将它们附加到命令的末尾 diff --git a/support/bootstrap.php b/support/bootstrap.php index d9471e6..d913def 100644 --- a/support/bootstrap.php +++ b/support/bootstrap.php @@ -19,9 +19,15 @@ use Webman\Config; use Webman\Middleware; use Webman\Route; use Webman\Util; +use Workerman\Events\Select; +use Workerman\Worker; $worker = $worker ?? null; +if (empty(Worker::$eventLoopClass)) { + Worker::$eventLoopClass = Select::class; +} + set_error_handler(function ($level, $message, $file = '', $line = 0) { if (error_reporting() & $level) { throw new ErrorException($message, 0, $level, $file, $line); diff --git a/support/helpers.php b/support/helpers.php index 8de22c0..67e7676 100644 --- a/support/helpers.php +++ b/support/helpers.php @@ -73,15 +73,25 @@ function app_path(string $path = ''): string /** * Public path * @param string $path + * @param string|null $plugin * @return string */ -function public_path(string $path = ''): string +function public_path(string $path = '', ?string $plugin = null): string { - static $publicPath = ''; - if (!$publicPath) { - $publicPath = \config('app.public_path') ?: run_path('public'); + static $publicPaths = []; + $plugin = $plugin ?? ''; + if (isset($publicPaths[$plugin])) { + $publicPath = $publicPaths[$plugin]; + } else { + $prefix = $plugin ? "plugin.$plugin." : ''; + $pathPrefix = $plugin ? 'plugin' . DIRECTORY_SEPARATOR . $plugin . DIRECTORY_SEPARATOR : ''; + $publicPath = \config("{$prefix}app.public_path", run_path("{$pathPrefix}public")); + if (count($publicPaths) > 32) { + $publicPaths = []; + } + $publicPaths[$plugin] = $publicPath; } - return path_combine($publicPath, $path); + return $path === '' ? $publicPath : path_combine($publicPath, $path); } /** @@ -187,70 +197,70 @@ function redirect(string $location, int $status = 302, array $headers = []): Res /** * View response - * @param string $template + * @param mixed $template * @param array $vars * @param string|null $app * @param string|null $plugin * @return Response */ -function view(string $template, array $vars = [], string $app = null, string $plugin = null): Response +function view(mixed $template = null, array $vars = [], ?string $app = null, ?string $plugin = null): Response { - $request = \request(); - $plugin = $plugin === null ? ($request->plugin ?? '') : $plugin; + [$template, $vars, $app, $plugin] = template_inputs($template, $vars, $app, $plugin); $handler = \config($plugin ? "plugin.$plugin.view.handler" : 'view.handler'); return new Response(200, [], $handler::render($template, $vars, $app, $plugin)); } /** * Raw view response - * @param string $template + * @param mixed $template * @param array $vars * @param string|null $app + * @param string|null $plugin * @return Response * @throws Throwable */ -function raw_view(string $template, array $vars = [], string $app = null): Response +function raw_view(mixed $template = null, array $vars = [], ?string $app = null, ?string $plugin = null): Response { - return new Response(200, [], Raw::render($template, $vars, $app)); + return new Response(200, [], Raw::render(...template_inputs($template, $vars, $app, $plugin))); } /** * Blade view response - * @param string $template + * @param mixed $template * @param array $vars * @param string|null $app + * @param string|null $plugin * @return Response */ -function blade_view(string $template, array $vars = [], string $app = null): Response +function blade_view(mixed $template = null, array $vars = [], ?string $app = null, ?string $plugin = null): Response { - return new Response(200, [], Blade::render($template, $vars, $app)); + return new Response(200, [], Blade::render(...template_inputs($template, $vars, $app, $plugin))); } /** * Think view response - * @param string $template + * @param mixed $template * @param array $vars * @param string|null $app + * @param string|null $plugin * @return Response */ -function think_view(string $template, array $vars = [], string $app = null): Response +function think_view(mixed $template = null, array $vars = [], ?string $app = null, ?string $plugin = null): Response { - return new Response(200, [], ThinkPHP::render($template, $vars, $app)); + return new Response(200, [], ThinkPHP::render(...template_inputs($template, $vars, $app, $plugin))); } /** * Twig view response - * @param string $template + * @param mixed $template * @param array $vars * @param string|null $app + * @param string|null $plugin * @return Response - * @throws LoaderError - * @throws RuntimeError - * @throws SyntaxError */ -function twig_view(string $template, array $vars = [], string $app = null): Response +function twig_view(mixed $template = null, array $vars = [], ?string $app = null, ?string $plugin = null): Response { - return new Response(200, [], Twig::render($template, $vars, $app)); + return new Response(200, [], Twig::render(...template_inputs($template, $vars, $app, $plugin))); } /** @@ -265,10 +275,10 @@ function request() /** * Get config * @param string|null $key - * @param $default - * @return array|mixed|null + * @param mixed $default + * @return mixed */ -function config(string $key = null, $default = null) +function config(?string $key = null, mixed $default = null) { return Config::get($key, $default); } @@ -299,11 +309,12 @@ function route(string $name, ...$parameters): string /** * Session - * @param mixed $key + * @param array|string|null $key * @param mixed $default * @return mixed|bool|Session + * @throws Exception */ -function session($key = null, $default = null) +function session(array|string|null $key = null, mixed $default = null): mixed { $session = \request()->session(); if (null === $key) { @@ -335,7 +346,7 @@ function session($key = null, $default = null) * @param string|null $locale * @return string */ -function trans(string $id, array $parameters = [], string $domain = null, string $locale = null): string +function trans(string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string { $res = Translation::trans($id, $parameters, $domain, $locale); return $res === '' ? $id : $res; @@ -346,7 +357,7 @@ function trans(string $id, array $parameters = [], string $domain = null, string * @param string|null $locale * @return string */ -function locale(string $locale = null): string +function locale(?string $locale = null): string { if (!$locale) { return Translation::getLocale(); @@ -441,8 +452,13 @@ function worker_bind($worker, $class) */ function worker_start($processName, $config) { - $worker = new Worker($config['listen'] ?? null, $config['context'] ?? []); - $propertyMap = [ + if (isset($config['enable']) && !$config['enable']) { + return; + } + // feat:custom worker class [default: Workerman\Worker] + $class = is_a($class = $config['workerClass'] ?? '' , Worker::class, true) ? $class : Worker::class; + $worker = new $class($config['listen'] ?? null, $config['context'] ?? []); + $properties = [ 'count', 'user', 'group', @@ -450,9 +466,10 @@ function worker_start($processName, $config) 'reusePort', 'transport', 'protocol', + 'eventLoop', ]; $worker->name = $processName; - foreach ($propertyMap as $property) { + foreach ($properties as $property) { if (isset($config[$property])) { $worker->$property = $config[$property]; } @@ -495,6 +512,32 @@ function is_phar(): bool return class_exists(Phar::class, false) && Phar::running(); } +/** + * Get template vars + * @param mixed $template + * @param array $vars + * @param string|null $app + * @param string|null $plugin + * @return array + */ +function template_inputs($template, array $vars, ?string $app, ?string $plugin): array +{ + $request = \request(); + $plugin = $plugin === null ? ($request->plugin ?? '') : $plugin; + if (is_array($template)) { + $vars = $template; + $template = null; + } + if ($template === null && $controller = $request->controller) { + $controllerSuffix = config($plugin ? "plugin.$plugin.app.controller_suffix" : "app.controller_suffix", ''); + $controllerName = $controllerSuffix !== '' ? substr($controller, 0, -strlen($controllerSuffix)) : $controller; + $path = strtolower(preg_replace('/(?action)); + $template = "$path/$actionFileBaseName"; + } + return [$template, $vars, $app, $plugin]; +} + /** * Get cpu count * @return int @@ -510,19 +553,24 @@ function cpu_count(): int if (strtolower(PHP_OS) === 'darwin') { $count = (int)shell_exec('sysctl -n machdep.cpu.core_count'); } else { - $count = (int)shell_exec('nproc'); + try { + $count = (int)shell_exec('nproc'); + } catch (\Throwable $ex) { + // Do nothing + } } } return $count > 0 ? $count : 4; } + /** * Get request parameters, if no parameter name is passed, an array of all values is returned, default values is supported * @param string|null $param param's name - * @param mixed|null $default default value - * @return mixed|null + * @param mixed $default default value + * @return mixed */ -function input(string $param = null, $default = null) +function input(?string $param = null, mixed $default = null): mixed { return is_null($param) ? request()->all() : request()->input($param, $default); } diff --git a/windows.php b/windows.php index 21fa888..32ff91f 100644 --- a/windows.php +++ b/windows.php @@ -5,7 +5,6 @@ require_once __DIR__ . '/vendor/autoload.php'; use Dotenv\Dotenv; -use process\Monitor; use support\App; use Workerman\Worker; @@ -28,12 +27,21 @@ if (isset($errorReporting)) { } $runtimeProcessPath = runtime_path() . DIRECTORY_SEPARATOR . '/windows'; -if (!is_dir($runtimeProcessPath)) { - mkdir($runtimeProcessPath); -} -$processFiles = [ - __DIR__ . DIRECTORY_SEPARATOR . 'start.php' +$paths = [ + $runtimeProcessPath, + runtime_path('logs'), + runtime_path('views') ]; +foreach ($paths as $path) { + if (!is_dir($path)) { + mkdir($path, 0777, true); + } +} + +$processFiles = []; +if (config('server.listen')) { + $processFiles[] = __DIR__ . DIRECTORY_SEPARATOR . 'start.php'; +} foreach (config('process', []) as $processName => $config) { $processFiles[] = write_process_file($runtimeProcessPath, $processName, ''); } @@ -72,6 +80,14 @@ if (is_callable('opcache_reset')) { opcache_reset(); } +if (!\$appConfigFile = config_path('app.php')) { + throw new RuntimeException('Config file not found: app.php'); +} +\$appConfig = require \$appConfigFile; +if (\$timezone = \$appConfig['default_timezone'] ?? '') { + date_default_timezone_set(\$timezone); +} + App::loadAllConfig(['route']); worker_start('$processParam', $configParam); @@ -90,7 +106,8 @@ EOF; } if ($monitorConfig = config('process.monitor.constructor')) { - $monitor = new Monitor(...array_values($monitorConfig)); + $monitorHandler = config('process.monitor.handler'); + $monitor = new $monitorHandler(...array_values($monitorConfig)); } function popen_processes($processFiles)