大多数逻辑是本地AI生成的自己进行了组合和微调?php /** * PHP 程序文件有效代码行数统计工具 code_counter.php * * 统计规则: * 1. 忽略行首的空白字符。 * 2. 处理多行注释 \/* ... *\/遇到 \/* 则进入状态直到遇到 *\/ 才会退出状态。 * 3. 处理单行注释 //在非多行注释状态下以 // 开头的行不计入代码。 * 4. 整行全是空白字符的行不计入代码。 * */ define(DEBUG_MODE, false); function code_counter(string $filePath) { // 状态变量追踪是否处于多行注释块内部 $inMultilineComment false; $validCodeLines 0; $fp fopen($filePath, rb); if (!$fp) die(Error: Could not read the file $filePath.\n); $lineNo 0; while ($line fgets($fp)) { $lineNo; $trimmedLine trim($line); // 移除两边空白 if ($trimmedLine ) { if (DEBUG_MODE) echo 00: line $lineNo is empty line\n; continue; // 空白行不计入 } // 是否遇到块注释结束。 这里仅考虑同一行只会出现注释符结束标记后续没有代码和注释 // 最多错误计数1行而已。开始标记也只进行简单处理 if ($inMultilineComment strpos($trimmedLine, */) ! false) { $inMultilineComment false; if (DEBUG_MODE) echo */: line $lineNo is comment end line\n; continue; } if (!$inMultilineComment strpos($trimmedLine, /*) ! false) { $inMultilineComment true; if (DEBUG_MODE) echo /*: line $lineNo is comment start line\n; continue; } // 块注释内部的行不计入 if ($inMultilineComment) { if (DEBUG_MODE) echo **: line $lineNo is the line inside a comment block\n; continue; } // 单行注释不计入 if (str_starts_with($trimmedLine, //)) { if (DEBUG_MODE) echo //: line $lineNo is single comment line\n; continue; } // 是有效行 $validCodeLines; } fclose($fp); if (DEBUG_MODE) printf(Total %4d, valid %4d - %s\n, $lineNo, $validCodeLines, $filePath); return $validCodeLines; } /** * * 功能: 遍历指定目录及其所有子目录统计指定后缀的文件某种信息我们是代码行数 * * 使用方法: php code_counter.php 目录路径 逗号分隔的后缀列表 * * 示例: php code_counter.php /var/www/project php,html,css */ // 检查命令行参数 if ($argc ! 3) { echo Usage: php $argv[0] directory_path comma_separated_extensions\n; echo Example: php $argv[0] ./my_project php,css,js\n; exit(1); } $directoryPath $argv[1]; $extensionsInput $argv[2]; // 1. 校验目录是否存在且可读 if (!is_dir($directoryPath)) { echo Error: Directory $directoryPath does not exist or is not a directory.\n; exit(1); } // 2. 解析后缀列表 // 将逗号分隔的字符串转换为数组并转换为小写方便匹配 $allowedExtensions array_map(trim, explode(,, $extensionsInput)); $allowedExtensions array_map(strtolower, $allowedExtensions); // 3. 使用递归迭代器遍历目录 try { // RecursiveDirectoryIterator 遍历目录RecursiveIteratorIterator 遍历目录树 $dirIterator new RecursiveDirectoryIterator($directoryPath); $iterator new RecursiveIteratorIterator($dirIterator); $foundFiles 0; foreach ($iterator as $fileInfo) { // 仅处理文件跳过目录 if ($fileInfo-isFile()) { $fileName $fileInfo-getRealPath(); // https://www.php.net/manual/en/splfileinfo.getrealpath.php $fileExtension strtolower($fileInfo-getExtension()); // 扩展名不带点 // 检查文件扩展名是否在允许的列表中 if (in_array($fileExtension, $allowedExtensions)) { $validCodeLines code_counter($fileName); echo $fileName. ,. $validCodeLines. \n; } } } } catch (UnexpectedValueException $e) { echo Error accessing directory: . $e-getMessage() . \n; } ?
程序代码行数统计脚本
发布时间:2026/7/3 3:00:30
大多数逻辑是本地AI生成的自己进行了组合和微调?php /** * PHP 程序文件有效代码行数统计工具 code_counter.php * * 统计规则: * 1. 忽略行首的空白字符。 * 2. 处理多行注释 \/* ... *\/遇到 \/* 则进入状态直到遇到 *\/ 才会退出状态。 * 3. 处理单行注释 //在非多行注释状态下以 // 开头的行不计入代码。 * 4. 整行全是空白字符的行不计入代码。 * */ define(DEBUG_MODE, false); function code_counter(string $filePath) { // 状态变量追踪是否处于多行注释块内部 $inMultilineComment false; $validCodeLines 0; $fp fopen($filePath, rb); if (!$fp) die(Error: Could not read the file $filePath.\n); $lineNo 0; while ($line fgets($fp)) { $lineNo; $trimmedLine trim($line); // 移除两边空白 if ($trimmedLine ) { if (DEBUG_MODE) echo 00: line $lineNo is empty line\n; continue; // 空白行不计入 } // 是否遇到块注释结束。 这里仅考虑同一行只会出现注释符结束标记后续没有代码和注释 // 最多错误计数1行而已。开始标记也只进行简单处理 if ($inMultilineComment strpos($trimmedLine, */) ! false) { $inMultilineComment false; if (DEBUG_MODE) echo */: line $lineNo is comment end line\n; continue; } if (!$inMultilineComment strpos($trimmedLine, /*) ! false) { $inMultilineComment true; if (DEBUG_MODE) echo /*: line $lineNo is comment start line\n; continue; } // 块注释内部的行不计入 if ($inMultilineComment) { if (DEBUG_MODE) echo **: line $lineNo is the line inside a comment block\n; continue; } // 单行注释不计入 if (str_starts_with($trimmedLine, //)) { if (DEBUG_MODE) echo //: line $lineNo is single comment line\n; continue; } // 是有效行 $validCodeLines; } fclose($fp); if (DEBUG_MODE) printf(Total %4d, valid %4d - %s\n, $lineNo, $validCodeLines, $filePath); return $validCodeLines; } /** * * 功能: 遍历指定目录及其所有子目录统计指定后缀的文件某种信息我们是代码行数 * * 使用方法: php code_counter.php 目录路径 逗号分隔的后缀列表 * * 示例: php code_counter.php /var/www/project php,html,css */ // 检查命令行参数 if ($argc ! 3) { echo Usage: php $argv[0] directory_path comma_separated_extensions\n; echo Example: php $argv[0] ./my_project php,css,js\n; exit(1); } $directoryPath $argv[1]; $extensionsInput $argv[2]; // 1. 校验目录是否存在且可读 if (!is_dir($directoryPath)) { echo Error: Directory $directoryPath does not exist or is not a directory.\n; exit(1); } // 2. 解析后缀列表 // 将逗号分隔的字符串转换为数组并转换为小写方便匹配 $allowedExtensions array_map(trim, explode(,, $extensionsInput)); $allowedExtensions array_map(strtolower, $allowedExtensions); // 3. 使用递归迭代器遍历目录 try { // RecursiveDirectoryIterator 遍历目录RecursiveIteratorIterator 遍历目录树 $dirIterator new RecursiveDirectoryIterator($directoryPath); $iterator new RecursiveIteratorIterator($dirIterator); $foundFiles 0; foreach ($iterator as $fileInfo) { // 仅处理文件跳过目录 if ($fileInfo-isFile()) { $fileName $fileInfo-getRealPath(); // https://www.php.net/manual/en/splfileinfo.getrealpath.php $fileExtension strtolower($fileInfo-getExtension()); // 扩展名不带点 // 检查文件扩展名是否在允许的列表中 if (in_array($fileExtension, $allowedExtensions)) { $validCodeLines code_counter($fileName); echo $fileName. ,. $validCodeLines. \n; } } } } catch (UnexpectedValueException $e) { echo Error accessing directory: . $e-getMessage() . \n; } ?