- 添加 autoload_class.php 示例演示类自动加载功能 - 添加 check_parser_api.php 示例验证 PHP 解析器 API 正确性 - 添加 file_scanner_example.php 示例展示文件扫描器基本用法 - 添加 file_scanner_usage.php 示例演示文件扫描器高级用法 - 添加 scan_with_exclusions.php 示例展示排除模式功能 - 添加 simple_scan.php 示例演示简单扫描操作 - 添加 test_exclusions.php 示例测试排除模式有效性 - 添加 test_fnmatch.php 示例验证路径匹配函数行为 - 添加 test_php_parser_check.php 示例测试 PHP 解析器语法检查 - 添加 test_php_syntax_check.php 示例验证 PHP 语法检查功能 - 添加 trait.php 示例演示 trait 特性用法pull/1/head
parent
423c10fe47
commit
120e89ac79
11 changed files with 511 additions and 0 deletions
@ -0,0 +1,13 @@ |
||||
<?php |
||||
|
||||
use Fidry\CpuCoreCounter\CpuCoreCounter; |
||||
|
||||
function main() |
||||
{ |
||||
require __DIR__ . '/../vendor/autoload.php'; |
||||
|
||||
var_dump(__LINE__); |
||||
var_dump('auto load class: ' . CpuCoreCounter::class); |
||||
$o = new CpuCoreCounter(); |
||||
var_dump($o->getCount()); |
||||
} |
||||
@ -0,0 +1,23 @@ |
||||
<?php |
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php'; |
||||
|
||||
use PhpParser\ParserFactory; |
||||
|
||||
// 检查正确的 API 用法 |
||||
$parserFactory = new ParserFactory(); |
||||
$parser = $parserFactory->create(ParserFactory::PREFER_PHP7); |
||||
|
||||
var_dump($parser); |
||||
echo "Parser class: " . get_class($parser) . "\n"; |
||||
echo "Has parse method: " . (method_exists($parser, 'parse') ? 'yes' : 'no') . "\n"; |
||||
|
||||
// 尝试解析一个简单的 PHP 代码 |
||||
$code = '<?php echo "hello";'; |
||||
try { |
||||
$stmts = $parser->parse($code); |
||||
echo "Parse successful\n"; |
||||
var_dump($stmts); |
||||
} catch (\PhpParser\Error $e) { |
||||
echo "Parse error: " . $e->getMessage() . "\n"; |
||||
} |
||||
@ -0,0 +1,37 @@ |
||||
<?php |
||||
|
||||
require_once __DIR__ . '/../src/FileScanner.php'; |
||||
|
||||
// 创建文件扫描器实例,用于扫描 PHP 和 C++ 文件 |
||||
$scanner = new FileScanner(['.php', '.cc', '.cpp', '.cxx', '.c', '.h', '.hpp']); |
||||
|
||||
// 添加排除模式(可选) |
||||
$scanner->addExcludePattern('*/vendor/*'); |
||||
$scanner->addExcludePattern('*/node_modules/*'); |
||||
$scanner->addExcludePattern('*.log'); |
||||
$scanner->addExcludePattern('*/tests/aot/*'); |
||||
|
||||
// 扫描当前项目目录 |
||||
echo "扫描项目中的 PHP 和 C++ 文件...\n"; |
||||
|
||||
try { |
||||
$files = $scanner->scan(__DIR__ . '/..'); // 扫描项目根目录 |
||||
|
||||
echo "找到 " . count($files) . " 个文件:\n"; |
||||
|
||||
foreach ($files as $index => $file) { |
||||
echo ($index + 1) . ". " . $file . "\n"; |
||||
} |
||||
|
||||
echo "\n带统计信息的扫描:\n"; |
||||
$result = $scanner->scanWithStats(__DIR__ . '/..'); |
||||
|
||||
echo "总共找到 {$result['count']} 个文件\n"; |
||||
echo "按扩展名统计:\n"; |
||||
foreach ($result['stats'] as $ext => $count) { |
||||
echo " $ext: $count 个文件\n"; |
||||
} |
||||
|
||||
} catch (Exception $e) { |
||||
echo "错误: " . $e->getMessage() . "\n"; |
||||
} |
||||
@ -0,0 +1,53 @@ |
||||
<?php |
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php'; // 添加自动加载器 |
||||
require_once __DIR__ . '/../src/Php/FileScanner.php'; |
||||
|
||||
use PhpAot\FileScanner; |
||||
|
||||
echo "测试 FileScanner 类...\n"; |
||||
|
||||
try { |
||||
// 创建文件扫描器实例,扫描项目根目录 |
||||
$scanner = new FileScanner(__DIR__ . '/..', ['.php', '.cc', '.cpp', '.cxx', '.c', '.h', '.hpp']); |
||||
|
||||
// 添加排除模式 |
||||
$scanner->addExcludePattern('*/tests/*'); // 排除测试目录 |
||||
$scanner->addExcludePattern('*/vendor/*'); // 排除vendor目录 |
||||
|
||||
echo "扫描目录: " . $scanner->getDirectory() . "\n"; |
||||
|
||||
// 扫描文件 |
||||
$files = $scanner->scan(); |
||||
|
||||
echo "找到 " . count($files) . " 个文件:\n"; |
||||
|
||||
// 只显示前20个文件以避免输出过多 |
||||
$count = 0; |
||||
foreach ($files as $index => $file) { |
||||
if ($count >= 20) { |
||||
echo "... 还有 " . (count($files) - $count) . " 个文件\n"; |
||||
break; |
||||
} |
||||
echo ($index + 1) . ". " . $file . "\n"; |
||||
$count++; |
||||
} |
||||
|
||||
echo "\n带统计信息的扫描:\n"; |
||||
$result = $scanner->scanWithStats(); |
||||
|
||||
echo "总共找到 {$result['count']} 个文件\n"; |
||||
echo "按扩展名统计:\n"; |
||||
foreach ($result['stats'] as $ext => $count) { |
||||
echo " $ext: $count 个文件\n"; |
||||
} |
||||
|
||||
// 测试只扫描 PHP 文件 |
||||
echo "\n只扫描 PHP 文件:\n"; |
||||
$phpScanner = new FileScanner(__DIR__ . '/..', ['.php']); |
||||
$phpFiles = $phpScanner->scan(); |
||||
echo "找到 " . count($phpFiles) . " 个 PHP 文件\n"; |
||||
|
||||
} catch (Exception $e) { |
||||
echo "错误: " . $e->getMessage() . "\n"; |
||||
} |
||||
@ -0,0 +1,42 @@ |
||||
<?php |
||||
|
||||
require_once __DIR__ . '/../src/FileScanner.php'; |
||||
|
||||
// 创建文件扫描器实例,用于扫描 PHP 和 C++ 文件 |
||||
$scanner = new FileScanner(['.php', '.cc', '.cpp', '.cxx', '.c', '.h', '.hpp']); |
||||
|
||||
// 添加排除模式 |
||||
$scanner->addExcludePattern('*/tests/*'); // 排除测试目录 |
||||
$scanner->addExcludePattern('*/vendor/*'); // 排除vendor目录 |
||||
$scanner->addExcludePattern('*.phpt'); // 排除PHPT测试文件 |
||||
|
||||
echo "扫描项目中的 PHP 和 C++ 文件(排除测试文件)...\n"; |
||||
|
||||
try { |
||||
$files = $scanner->scan(__DIR__ . '/..'); // 扫描项目根目录 |
||||
|
||||
echo "找到 " . count($files) . " 个文件:\n"; |
||||
|
||||
// 只显示前20个文件以避免输出过多 |
||||
$count = 0; |
||||
foreach ($files as $index => $file) { |
||||
if ($count >= 20) { |
||||
echo "... 还有 " . (count($files) - $count) . " 个文件\n"; |
||||
break; |
||||
} |
||||
echo ($index + 1) . ". " . $file . "\n"; |
||||
$count++; |
||||
} |
||||
|
||||
echo "\n带统计信息的扫描:\n"; |
||||
$result = $scanner->scanWithStats(__DIR__ . '/..'); |
||||
|
||||
echo "总共找到 {$result['count']} 个文件\n"; |
||||
echo "按扩展名统计:\n"; |
||||
foreach ($result['stats'] as $ext => $count) { |
||||
echo " $ext: $count 个文件\n"; |
||||
} |
||||
|
||||
} catch (Exception $e) { |
||||
echo "错误: " . $e->getMessage() . "\n"; |
||||
} |
||||
@ -0,0 +1,38 @@ |
||||
<?php |
||||
|
||||
require_once __DIR__ . '/../src/FileScanner.php'; |
||||
|
||||
// 创建文件扫描器实例,用于扫描 PHP 和 C++ 文件 |
||||
$scanner = new FileScanner(['.php', '.cc', '.cpp', '.cxx', '.c', '.h', '.hpp']); |
||||
|
||||
// 扫描当前项目目录 |
||||
echo "扫描项目中的 PHP 和 C++ 文件...\n"; |
||||
|
||||
try { |
||||
$files = $scanner->scan(__DIR__ . '/..'); // 扫描项目根目录 |
||||
|
||||
echo "找到 " . count($files) . " 个文件:\n"; |
||||
|
||||
// 只显示前20个文件以避免输出过多 |
||||
$count = 0; |
||||
foreach ($files as $index => $file) { |
||||
if ($count >= 20) { |
||||
echo "... 还有 " . (count($files) - $count) . " 个文件\n"; |
||||
break; |
||||
} |
||||
echo ($index + 1) . ". " . $file . "\n"; |
||||
$count++; |
||||
} |
||||
|
||||
echo "\n带统计信息的扫描:\n"; |
||||
$result = $scanner->scanWithStats(__DIR__ . '/..'); |
||||
|
||||
echo "总共找到 {$result['count']} 个文件\n"; |
||||
echo "按扩展名统计:\n"; |
||||
foreach ($result['stats'] as $ext => $count) { |
||||
echo " $ext: $count 个文件\n"; |
||||
} |
||||
|
||||
} catch (Exception $e) { |
||||
echo "错误: " . $e->getMessage() . "\n"; |
||||
} |
||||
@ -0,0 +1,35 @@ |
||||
<?php |
||||
|
||||
require_once __DIR__ . '/../src/Php/FileScanner.php'; |
||||
|
||||
use PhpAot\FileScanner; |
||||
|
||||
echo "测试基本扫描功能...\n"; |
||||
$scanner = new FileScanner(__DIR__ . '/..', ['.php', '.cc', '.cpp', '.cxx', '.c', '.h', '.hpp']); |
||||
$allFiles = $scanner->scan(); |
||||
echo "所有文件数量: " . count($allFiles) . "\n"; |
||||
|
||||
echo "\n测试排除模式...\n"; |
||||
$scannerWithExclusions = new FileScanner(__DIR__ . '/..', ['.php', '.cc', '.cpp', '.cxx', '.c', '.h', '.hpp']); |
||||
$scannerWithExclusions->addExcludePattern('*/tests/*'); // 排除测试目录 |
||||
$filteredFiles = $scannerWithExclusions->scan(); |
||||
echo "排除测试目录后的文件数量: " . count($filteredFiles) . "\n"; |
||||
|
||||
// 检查结果中是否确实没有包含 tests 目录的文件 |
||||
$testFilesFound = 0; |
||||
foreach ($filteredFiles as $file) { |
||||
if (strpos($file, '/tests/') !== false) { |
||||
$testFilesFound++; |
||||
} |
||||
} |
||||
|
||||
echo "在过滤后的结果中找到 $testFilesFound 个在 tests 目录中的文件\n"; |
||||
|
||||
// 显示一些过滤后的文件 |
||||
echo "\n前10个过滤后的文件:\n"; |
||||
$counter = 0; |
||||
foreach ($filteredFiles as $file) { |
||||
if ($counter >= 10) break; |
||||
echo ($counter + 1) . ". " . $file . "\n"; |
||||
$counter++; |
||||
} |
||||
@ -0,0 +1,21 @@ |
||||
<?php |
||||
|
||||
// 测试 fnmatch 函数的行为 |
||||
$testPath = '/home/swoole/workspace/aot/tests/aot/strlen.phpt'; |
||||
$pattern = '*/tests/*'; |
||||
|
||||
echo "测试路径: $testPath\n"; |
||||
echo "模式: $pattern\n"; |
||||
echo "fnmatch 匹配结果: " . (fnmatch($pattern, $testPath, FNM_PATHNAME) ? 'true' : 'false') . "\n"; |
||||
echo "使用 FNM_PATHNAME 标志: " . (fnmatch($pattern, $testPath, FNM_PATHNAME) ? 'true' : 'false') . "\n"; |
||||
|
||||
// 尝试相对路径 |
||||
$basePath = '/home/swoole/workspace/aot'; |
||||
$relativePath = str_replace($basePath . '/', '', $testPath); |
||||
echo "相对路径: $relativePath\n"; |
||||
echo "相对路径 fnmatch 匹配结果: " . (fnmatch($pattern, $relativePath, FNM_PATHNAME) ? 'true' : 'false') . "\n"; |
||||
|
||||
// 测试更具体的模式 |
||||
$pattern2 = '*tests*'; |
||||
echo "模式2: $pattern2\n"; |
||||
echo "fnmatch 匹配结果: " . (fnmatch($pattern2, $testPath, FNM_PATHNAME) ? 'true' : 'false') . "\n"; |
||||
@ -0,0 +1,133 @@ |
||||
<?php |
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php'; |
||||
require_once __DIR__ . '/../src/Php/FileScanner.php'; |
||||
|
||||
use PhpAot\FileScanner; |
||||
|
||||
echo "测试使用 PHP-Parser 的语法检查功能...\n"; |
||||
|
||||
// 创建一个测试用的临时目录和文件 |
||||
$testDir = __DIR__ . '/test_temp'; |
||||
if (!is_dir($testDir)) { |
||||
mkdir($testDir); |
||||
} |
||||
|
||||
// 创建一个只包含定义的 PHP 文件 |
||||
$definitionFile = $testDir . '/definitions.php'; |
||||
file_put_contents($definitionFile, '<?php |
||||
namespace Test; |
||||
|
||||
class TestClass { |
||||
public function testMethod() { |
||||
$localVar = "world"; // 这在函数内部,是允许的 |
||||
return $localVar; |
||||
} |
||||
} |
||||
|
||||
function testFunction() { |
||||
$localVar = "hello"; // 这在函数内部,是允许的 |
||||
return $localVar; |
||||
} |
||||
|
||||
interface TestInterface { |
||||
public function interfaceMethod(); |
||||
} |
||||
|
||||
trait TestTrait { |
||||
public function traitMethod() { |
||||
return "trait"; |
||||
} |
||||
} |
||||
'); |
||||
|
||||
// 创建一个包含执行逻辑的 PHP 文件 |
||||
$executableFile = $testDir . '/executable.php'; |
||||
file_put_contents($executableFile, '<?php |
||||
namespace Test; |
||||
|
||||
// 这些是全局作用域的执行逻辑 |
||||
$var = "hello"; |
||||
echo $var; |
||||
$result = testFunction(); // 函数调用 |
||||
|
||||
class TestClass { |
||||
public function testMethod() { |
||||
$localVar = "world"; // 这在函数内部,是允许的 |
||||
return $localVar; |
||||
} |
||||
} |
||||
|
||||
function testFunction() { |
||||
return 42; |
||||
} |
||||
|
||||
// 这也是全局作用域的执行逻辑 |
||||
if (true) { |
||||
echo "conditional execution"; |
||||
} |
||||
'); |
||||
|
||||
// 创建一个包含 require 但无其他执行逻辑的文件 |
||||
$requireFile = $testDir . '/with_require.php'; |
||||
file_put_contents($requireFile, '<?php |
||||
namespace Test; |
||||
|
||||
require_once "some_file.php"; // require 在顶层是允许的 |
||||
|
||||
class TestClass { |
||||
public function testMethod() { |
||||
return "hello"; |
||||
} |
||||
} |
||||
|
||||
function testFunction() { |
||||
return 42; |
||||
} |
||||
'); |
||||
|
||||
echo "测试目录: $testDir\n"; |
||||
|
||||
try { |
||||
// 测试只扫描定义文件 |
||||
echo "\n扫描只包含定义的 PHP 文件:\n"; |
||||
$scanner = new FileScanner($testDir, ['.php'], true); // 启用语法检查 |
||||
$definitionFiles = $scanner->scan(); |
||||
|
||||
echo "找到 " . count($definitionFiles) . " 个有效定义文件:\n"; |
||||
foreach ($definitionFiles as $file) { |
||||
$basename = basename($file); |
||||
echo " - $basename\n"; |
||||
} |
||||
|
||||
// 测试扫描所有 PHP 文件(不检查语法) |
||||
echo "\n扫描所有 PHP 文件(不检查语法):\n"; |
||||
$scanner2 = new FileScanner($testDir, ['.php'], false); // 不启用语法检查 |
||||
$allFiles = $scanner2->scan(); |
||||
|
||||
echo "找到 " . count($allFiles) . " 个文件:\n"; |
||||
foreach ($allFiles as $file) { |
||||
$basename = basename($file); |
||||
echo " - $basename\n"; |
||||
} |
||||
|
||||
echo "\n预期结果:\n"; |
||||
echo "- definitions.php 应该被包含(只包含定义)\n"; |
||||
echo "- with_require.php 应该被包含(require 是允许的)\n"; |
||||
echo "- executable.php 不应该被包含(包含全局执行逻辑)\n"; |
||||
|
||||
// 清理测试文件 |
||||
unlink($definitionFile); |
||||
unlink($executableFile); |
||||
unlink($requireFile); |
||||
rmdir($testDir); |
||||
|
||||
} catch (Exception $e) { |
||||
echo "错误: " . $e->getMessage() . "\n"; |
||||
|
||||
// 清理测试文件(如果出错) |
||||
if (file_exists($definitionFile)) unlink($definitionFile); |
||||
if (file_exists($executableFile)) unlink($executableFile); |
||||
if (file_exists($requireFile)) unlink($requireFile); |
||||
if (is_dir($testDir)) rmdir($testDir); |
||||
} |
||||
@ -0,0 +1,88 @@ |
||||
<?php |
||||
|
||||
require_once __DIR__ . '/../src/Php/FileScanner.php'; |
||||
|
||||
use PhpAot\FileScanner; |
||||
|
||||
echo "测试 PHP 语法检查功能...\n"; |
||||
|
||||
// 创建一个测试用的临时目录和文件 |
||||
$testDir = __DIR__ . '/test_temp'; |
||||
if (!is_dir($testDir)) { |
||||
mkdir($testDir); |
||||
} |
||||
|
||||
// 创建一个只包含定义的 PHP 文件 |
||||
$definitionFile = $testDir . '/definitions.php'; |
||||
file_put_contents($definitionFile, '<?php |
||||
namespace Test; |
||||
|
||||
class TestClass { |
||||
public function testMethod() { |
||||
return "hello"; |
||||
} |
||||
} |
||||
|
||||
function testFunction() { |
||||
return 42; |
||||
} |
||||
|
||||
interface TestInterface { |
||||
public function interfaceMethod(); |
||||
} |
||||
'); |
||||
|
||||
// 创建一个包含执行逻辑的 PHP 文件 |
||||
$executableFile = $testDir . '/executable.php'; |
||||
file_put_contents($executableFile, '<?php |
||||
namespace Test; |
||||
|
||||
$var = "hello"; // 这是执行逻辑 |
||||
echo $var; // 这也是执行逻辑 |
||||
|
||||
class TestClass { |
||||
public function testMethod() { |
||||
$localVar = "world"; // 这在函数内部,是允许的 |
||||
return $localVar; |
||||
} |
||||
} |
||||
|
||||
$globalVar = testFunction(); // 这是执行逻辑 |
||||
'); |
||||
|
||||
echo "测试目录: $testDir\n"; |
||||
|
||||
try { |
||||
// 测试只扫描定义文件 |
||||
echo "\n扫描只包含定义的 PHP 文件:\n"; |
||||
$scanner = new FileScanner($testDir, ['.php'], true); // 启用语法检查 |
||||
$definitionFiles = $scanner->scan(); |
||||
|
||||
echo "找到 " . count($definitionFiles) . " 个有效定义文件:\n"; |
||||
foreach ($definitionFiles as $file) { |
||||
echo " - $file\n"; |
||||
} |
||||
|
||||
// 测试扫描所有 PHP 文件(不检查语法) |
||||
echo "\n扫描所有 PHP 文件(不检查语法):\n"; |
||||
$scanner2 = new FileScanner($testDir, ['.php'], false); // 不启用语法检查 |
||||
$allFiles = $scanner2->scan(); |
||||
|
||||
echo "找到 " . count($allFiles) . " 个文件:\n"; |
||||
foreach ($allFiles as $file) { |
||||
echo " - $file\n"; |
||||
} |
||||
|
||||
// 清理测试文件 |
||||
unlink($definitionFile); |
||||
unlink($executableFile); |
||||
rmdir($testDir); |
||||
|
||||
} catch (Exception $e) { |
||||
echo "错误: " . $e->getMessage() . "\n"; |
||||
|
||||
// 清理测试文件(如果出错) |
||||
if (file_exists($definitionFile)) unlink($definitionFile); |
||||
if (file_exists($executableFile)) unlink($executableFile); |
||||
if (is_dir($testDir)) rmdir($testDir); |
||||
} |
||||
@ -0,0 +1,28 @@ |
||||
<?php |
||||
|
||||
trait TraitA { |
||||
public function sayHello() { |
||||
echo 'Hello'; |
||||
} |
||||
} |
||||
|
||||
trait TraitB { |
||||
public function sayWorld() { |
||||
echo 'World'; |
||||
} |
||||
} |
||||
|
||||
class MyHelloWorld |
||||
{ |
||||
use TraitA, TraitB; // A class can use multiple traits |
||||
|
||||
public function sayHelloWorld() { |
||||
$this->sayHello(); |
||||
echo ' '; |
||||
$this->sayWorld(); |
||||
echo "!\n"; |
||||
} |
||||
} |
||||
|
||||
$obj = new MyHelloWorld(); |
||||
$obj->sayHelloWorld(); |
||||
Loading…
Reference in new issue