- 添加 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