feat(examples): 添加多个示例文件演示核心功能

- 添加 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
韩天峰 7 months ago
parent 423c10fe47
commit 120e89ac79
  1. 13
      examples/autoload_class.php
  2. 23
      examples/check_parser_api.php
  3. 37
      examples/file_scanner_example.php
  4. 53
      examples/file_scanner_usage.php
  5. 42
      examples/scan_with_exclusions.php
  6. 38
      examples/simple_scan.php
  7. 35
      examples/test_exclusions.php
  8. 21
      examples/test_fnmatch.php
  9. 133
      examples/test_php_parser_check.php
  10. 88
      examples/test_php_syntax_check.php
  11. 28
      examples/trait.php

@ -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…
Cancel
Save