lh 1 месяц назад
Родитель
Сommit
db845ed56f
1 измененных файлов с 41 добавлено и 4 удалено
  1. 41 4
      app/Console/Commands/ProcessBatchEpisodeGenerationCommand.php

+ 41 - 4
app/Console/Commands/ProcessBatchEpisodeGenerationCommand.php

@@ -101,15 +101,52 @@ class ProcessBatchEpisodeGenerationCommand extends Command
      */
     private function spawnWorker($animeId)
     {
-        $process = new Process([
-            PHP_BINARY,
+        $command = [
+            $this->phpBinary(),
             base_path('artisan'),
             'batch:generate-episodes:anime',
             (string) $animeId,
-        ]);
+        ];
+
+        if (DIRECTORY_SEPARATOR === '/') {
+            // Linux:用 nohup 后台启动并立即返回,避免父进程退出时
+            // Symfony Process 析构(stop(0))把子进程一起杀掉
+            $commandLine = 'nohup ' . implode(' ', array_map('escapeshellarg', $command)) . ' > /dev/null 2>&1 &';
+            $process = Process::fromShellCommandline($commandLine);
+        } else {
+            // Windows:数组参数直接启动(开发环境)
+            $process = new Process($command);
+            $process->disableOutput();
+        }
+
         $process->setTimeout(null);
         $process->setIdleTimeout(null);
-        $process->disableOutput();
         $process->start();
     }
+
+    /**
+     * 获取当前 PHP 可执行文件的真实路径
+     *
+     * 部分编译版 PHP(如 LNMP 一键包)会在编译期把 PHP_BINARY 常量硬编码成固定路径,
+     * 与实际运行中的二进制不一致,直接用 PHP_BINARY 拉子进程会失败。
+     * 因此依次优先使用:
+     * 1. 环境变量 PHP_BINARY(可在 crontab 中显式指定);
+     * 2. Linux 下 /proc/self/exe(当前真实运行的二进制,与启动本命令的 PHP 一致);
+     * 3. 回退到 PHP_BINARY 常量。
+     *
+     * @return string
+     */
+    private function phpBinary()
+    {
+        $envBinary = getenv('PHP_BINARY');
+        if ($envBinary && is_executable($envBinary)) {
+            return $envBinary;
+        }
+
+        if (DIRECTORY_SEPARATOR === '/' && ($real = @readlink('/proc/self/exe')) && is_executable($real)) {
+            return $real;
+        }
+
+        return PHP_BINARY;
+    }
 }