#!/usr/bin/env php \n"; exit(1); } $protoDir = __DIR__ . '/protos'; $outputDir = rtrim($argv[1], '/'); // 检查 protoc 是否可用 exec('protoc --version 2>&1', $output, $retval); if ($retval !== 0) { echo "Error: protoc compiler not found. Please install it first.\n"; echo "On macOS: brew install protobuf\n"; echo "On Linux: sudo apt-get install protobuf-compiler\n"; echo "On Windows: choco install protoc\n"; exit(1); } // 创建输出目录 if (!file_exists($outputDir)) { mkdir($outputDir, 0755, true); } // 递归查找所有 .proto 文件 $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($protoDir), RecursiveIteratorIterator::LEAVES_ONLY ); $protoFiles = []; foreach ($files as $file) { if ($file->getExtension() === 'proto') { $protoFiles[] = $file->getRealPath(); } } if (empty($protoFiles)) { echo "No .proto files found in {$protoDir}\n"; exit(0); } // 编译每个文件 $successCount = 0; foreach ($protoFiles as $protoFile) { $relativePath = substr($protoFile, strlen($protoDir) + 1); echo "Compiling {$relativePath}... "; $command = sprintf( 'protoc --php_out=%s --proto_path=%s %s 2>&1', escapeshellarg($outputDir), escapeshellarg(dirname($protoFile)), escapeshellarg($protoFile) ); exec($command, $output, $retval); if ($retval === 0) { echo "OK\n"; $successCount++; } else { echo "FAILED\n"; echo "Error output:\n" . implode("\n", $output) . "\n"; } } echo "\nResult: {$successCount}/" . count($protoFiles) . " files compiled successfully\n"; // 生成自动加载文件 generateAutoload($outputDir); /** * 生成 composer 自动加载配置 */ function generateAutoload(string $outputDir) { $autoloadFile = $outputDir . '/composer.json'; if (!file_exists($autoloadFile)) { file_put_contents($autoloadFile, json_encode([ 'name' => 'generated/protobuf-messages', 'autoload' => [ 'psr-4' => [ '' => './' ] ] ], JSON_PRETTY_PRINT)); echo "\nGenerated composer.json for autoloading. Run 'composer dump-autoload' if needed.\n"; } }