Laravel控制器无法运行Node.js翻译脚本的问题排查
我尝试从Laravel 7.29的控制器函数中调用项目根目录下的Node.js脚本translate.js实现翻译功能(英文转印地语)。直接在命令行执行node translate.js "I want to try convert my text into hindi language." hi能正常得到结果,但通过控制器执行时总是报错。
报错信息
The command ""node D:\Laragon\www\krutech\translate.js ""I want to try convert my text into hindi language."" hi"" failed. Exit Code:1(General error) Working directory: D:\Laragon\www\krutech\public Output: ================ Error Output: ================ The filename, directory name, or volume label syntax is incorrect.
相关代码
translate.js 代码
const { translate } = require('@vitalets/google-translate-api'); function translateText(text, targetLang) { return translate(text, { to: targetLang }) .then(res => { return res.text; }) .catch(err => { console.error(err); return "Translation failed"; }); } module.exports = { translateText: translateText }; const textToTranslate = process.argv[2]; const targetLang = process.argv[3]; if (textToTranslate && targetLang) { translateText(textToTranslate, targetLang) .then(res => console.log(res)) .catch((err) => console.error(`Translation failed: ${err}`)); } else { console.error('Please provide text to translate and target language code'); }
Laravel控制器函数代码
public function index() { $text = 'I want to try convert my text into hindi language.'; $targetLang = 'hi'; $pathToTranslateJS = base_path('translate.js'); $command = "node " . $pathToTranslateJS . " " . escapeshellarg($text) . " " . $targetLang; $process = new Process([$command]); $process->run(); if (!$process->isSuccessful()) { throw new ProcessFailedException($process); } $translatedText = $process->getOutput(); return $translatedText; }
问题原因
错误的核心是Process类的参数使用方式错误。将整个命令字符串作为单一元素传入Process数组,导致底层解析命令时出现多余的引号嵌套,触发路径语法错误。
Process类的正确用法是将命令和每个参数拆分为数组的独立元素,而非拼接成完整字符串再传入。当前写法会让系统把整个拼接后的字符串当作一个命令执行,无法识别node是命令、后续内容是参数。
解决方案
修改控制器代码,将命令和参数拆分为数组元素传入Process,同时确保执行环境与命令行一致:
public function index() { $text = 'I want to try convert my text into hindi language.'; $targetLang = 'hi'; $pathToTranslateJS = base_path('translate.js'); // 将命令与各参数拆分为数组独立元素 $process = new Process([ 'node', $pathToTranslateJS, $text, $targetLang ]); // 设置工作目录为项目根,匹配命令行执行环境 $process->setWorkingDirectory(base_path()); $process->run(); if (!$process->isSuccessful()) { throw new ProcessFailedException($process); } // 去除输出结果中的多余换行符 $translatedText = trim($process->getOutput()); return $translatedText; }
额外优化点
- 无需手动使用
escapeshellarg()转义参数,Process类会自动处理参数的空格与转义问题 - 添加
trim()处理输出结果,避免返回包含多余换行的内容 - 明确设置工作目录,避免因默认工作目录(public)导致的路径或依赖加载问题
内容的提问来源于stack exchange,提问作者NIKUNJ KOTHIYA

