104 lines
3.1 KiB
PHP
104 lines
3.1 KiB
PHP
#!/usr/bin/env php
|
||
<?php
|
||
/**
|
||
* 启动前自检:在项目根目录执行 php scripts/check_start.php
|
||
*/
|
||
declare(strict_types=1);
|
||
|
||
chdir(__DIR__ . '/..');
|
||
require_once __DIR__ . '/../vendor/autoload.php';
|
||
|
||
$errors = [];
|
||
$isLinux = DIRECTORY_SEPARATOR === '/';
|
||
|
||
if ($isLinux) {
|
||
foreach (['pcntl', 'posix'] as $ext) {
|
||
if (!extension_loaded($ext)) {
|
||
$errors[] = "缺少 PHP 扩展: {$ext}(Workerman 在 Linux 上必需)";
|
||
}
|
||
}
|
||
}
|
||
|
||
foreach (['pdo', 'pdo_mysql', 'json'] as $ext) {
|
||
if (!extension_loaded($ext)) {
|
||
$errors[] = "缺少 PHP 扩展: {$ext}";
|
||
}
|
||
}
|
||
|
||
if (!function_exists('cpu_count')) {
|
||
$errors[] = '函数 cpu_count() 不存在,请确认 vendor 已完整安装(composer install)';
|
||
}
|
||
|
||
$runtime = base_path() . '/runtime';
|
||
$logs = $runtime . '/logs';
|
||
foreach ([$runtime, $logs] as $dir) {
|
||
if (!is_dir($dir) && !@mkdir($dir, 0755, true)) {
|
||
$errors[] = "无法创建目录: {$dir}";
|
||
} elseif (!is_writable($dir)) {
|
||
$errors[] = "目录不可写: {$dir}(请 chown/chmod 给运行 PHP 的用户)";
|
||
}
|
||
}
|
||
|
||
$pidPath = runtime_path() . '/webman.pid';
|
||
if (is_file($pidPath) && !is_writable($pidPath) && !is_writable(dirname($pidPath))) {
|
||
$errors[] = "PID 文件目录不可写: {$pidPath}";
|
||
}
|
||
|
||
try {
|
||
require base_path() . '/support/bootstrap.php';
|
||
} catch (Throwable $e) {
|
||
$errors[] = 'bootstrap 失败: ' . $e->getMessage() . ' @ ' . $e->getFile() . ':' . $e->getLine();
|
||
}
|
||
|
||
if (empty($errors)) {
|
||
foreach (config('process', []) as $name => $proc) {
|
||
$handler = $proc['handler'] ?? '';
|
||
if (is_string($handler) && $handler !== '' && !class_exists($handler)) {
|
||
$errors[] = "进程 [{$name}] 处理器不存在: {$handler}";
|
||
}
|
||
}
|
||
}
|
||
|
||
if (empty($errors)) {
|
||
try {
|
||
support\think\Db::execute('SELECT 1');
|
||
} catch (Throwable $e) {
|
||
$errors[] = '数据库连接失败: ' . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
$listen = config('process.webman.listen', '');
|
||
if ($listen !== '' && empty($errors)) {
|
||
$parsed = parse_url($listen);
|
||
$host = $parsed['host'] ?? '0.0.0.0';
|
||
$port = $parsed['port'] ?? 80;
|
||
$bindHost = $host === '0.0.0.0' ? '127.0.0.1' : $host;
|
||
$sock = @stream_socket_server("tcp://{$bindHost}:{$port}", $errno, $errstr);
|
||
if ($sock === false) {
|
||
$errors[] = "端口 {$port} 无法监听: [{$errno}] {$errstr}";
|
||
$errors[] = "可执行: ss -lntp | grep {$port} 查看是否被占用";
|
||
} else {
|
||
fclose($sock);
|
||
}
|
||
}
|
||
|
||
if ($errors) {
|
||
echo "=== 启动自检失败 ===\n";
|
||
foreach ($errors as $i => $msg) {
|
||
echo ($i + 1) . '. ' . $msg . "\n";
|
||
}
|
||
echo "\n下一步:\n";
|
||
echo " php start.php start # 前台启动看完整报错\n";
|
||
echo " tail -n 80 runtime/logs/workerman.log\n";
|
||
echo " tail -n 80 runtime/logs/stdout.log\n";
|
||
exit(1);
|
||
}
|
||
|
||
echo "=== 启动自检通过 ===\n";
|
||
echo "监听: {$listen}\n";
|
||
echo "Worker 数: " . (config('process.webman.count') ?? '?') . "\n";
|
||
echo "路由数: " . count(Webman\Route::getRoutes()) . "\n";
|
||
echo "\n请执行: php start.php start\n";
|
||
echo "确认无误后再: php start.php start -d\n";
|
||
exit(0);
|