nastuzzi-samy/reflection-namespace

反射命名空间,给出其类、子命名空间等更多内容

v1.0.1 2019-05-23 22:13 UTC

This package is auto-updated.

Last update: 2024-09-26 07:20:30 UTC


README

Travis Build Issues Stars License

简介

为什么不能使用特定目录下的根命名空间来搜索所有类和子目录,而要搜索所有类和子目录?

此外,有时同一命名空间下的文件定义在不同的目录中,需要多次研究才能获取所有这些文件。

PHP 默认有多个 Reflector 类:类、参数、常量、方法等。但不存在反射命名空间的方法。现在,由于所有项目都通过 Composer 使用不同的包,这可能很有用。

ReflectionNamespace 类从 Composer 加载数据(子命名空间、类)。它使用 PSR-0(默认禁用)、PSR-4、classmap 和文件自动加载器。它还从已声明的类、特质和接口(也默认禁用)加载。

安装

通过 Composer 简单安装

composer install nastuzzi-samy/reflection-namespace

由于其与 Composer 引擎(自动加载器)协同工作,因此需要在 Composer 项目中实现。

用法

首先,ReflectionNamespace 类与其他 Reflector 类一样位于根命名空间。

Project example structure:

app/
	Http/
		Controller.php
	Models/
		User.php
vendor/
	...
	random-package/  # RandomPackage defines app/ as \App namespace also
		app/
			Console/
			Models/
				Group.php

创建

要创建一个新的 ReflectionNamespace,您需要将其作为字符串传递给它要工作的命名空间

<?php

// Regroup the namespace generated by our projet and the RandomPackage package:
new \ReflectionNamespace('App');
new \ReflectionNamespace('App\\');  // It is the same that the previous one.
new \ReflectionNamespace('\\App\\');  // Same.
new \ReflectionNamespace('\\App');  // Same.

// Regroup the namespace generated by our RandomPackage package:
new \ReflectionNamespace('App\Console');
new \ReflectionNamespace('App\Console\\');  // It is the same that the previous one.
new \ReflectionNamespace('\\App\Console');  // Same.
new \ReflectionNamespace('\\App\Console\\');  // Same.

?>

获取信息

由于其开销很大,ReflectionNamespace 只在请求时加载类和命名空间。主要来说,您可以使用该类仅解析命名空间的短名和长名,而不必担心资源消耗。

<?php

$modelsReflection = new \ReflectionNamespace('App\\Models');

echo $modelsReflection->getName();  // App\Models
echo $modelsReflection->getShortName();  // Models
echo $modelsReflection->getParentName();  // App

?>

获取类和命名空间

通过获取类或命名空间,ReflectionNamespace 类将加载所有数据,遍历所有 Composer 自动加载器,在某些情况下,如果 Composer 没有缓存所有文件/类,则搜索目录(仅限于 PSR-0 和 PSR-4)。

<?php

$modelsReflection = new \ReflectionNamespace('App\\Models');

// Equivalent to: new \ReflectionNamespace('App');
$appReflection = $modelsReflection->getParent();

/*
Get all class names under App\Models.
Equivalent to:
[
	'User' => 'App\\Models\\User',
	'Group' => 'App\\Models\\Group',
];
 */
$modelsReflection->getClassNames();

/*
Get all classes under App\Models.
Equivalent to:
[
	'User' => new \ReflectionClass('App\\Models\\User'),
	'Group' => new \ReflectionClass('App\\Models\\Group'),
];
 */
$modelsReflection->getClasses();

/*
Get all namespace full names under App.
Equivalent to:
[
	'Console' => 'App\\Console',
	'Http' => 'App\\Http',
	'Models' => 'App\\Models',
];
 */
$appReflection->getNamespaceNames();

/*
Get all namespaces under App.
Equivalent to:
[
	'Console' => new \ReflectionNamespace('App\\Console'),
	'Http' => new \ReflectionNamespace('App\\Http'),
	'Models' => new \ReflectionNamespace('App\\Models'),
];
 */
$appReflection->getNamespaces();

?>

当然,您可以使用 getClassgetNamespace 获取精确的类或命名空间。或者,您可以使用 hasClasshasNamespace 检查命名空间是否拥有类或子命名空间。

<?php

// Equivalent to: new \ReflectionClass('App\\Models\\User');
$modelsReflection->getClass('User');
// Throw an exception.
$modelsReflection->getClass('NoModel');

echo $appReflection->hasNamespace('Models'); // TRUE
echo $modelsReflection->hasNamespace('User'); // FALSE

?>

高级用法

启用 PSR-0 加载

默认情况下,PSR-0 加载器不处理(因为它已被弃用),反射可能会导致不完整搜索。为此,要使用 PSR-0 加载器,您可以通过调用静态方法启用其使用

<?php

// Ask the class to load also from PSR-0.
\ReflectionNamespace::loadPRS0(TRUE);

// Refresh all loaded data:
$modelsReflection->reload();
$appReflection->reload();

// Ask the class not to load from PSR-0.
\ReflectionNamespace::loadPRS0(FALSE);

?>

启用从已加载的类、接口和特质加载

默认情况下,不处理加载所有已声明的类、接口和特质,反射可能会导致不完整搜索。这是因为在大型项目中,使用大量重型包可能会非常昂贵。由于其很少使用,通常由 Composer 列出所有已声明的类。由于任何原因,如果想要加载所有这些,可以通过调用静态方法启用其使用

<?php

// Ask the class to load also from loaded classes, interfaces and traits.
\ReflectionNamespace::loadDeclaredClasses(TRUE);

// Refresh all loaded data:
$modelsReflection->reload();
$appReflection->reload();

// Ask the class not to load from loaded classes, interfaces and traits.
\ReflectionNamespace::loadDeclaredClasses(FALSE);

?>

操作加载器

您可以使用静态方法 getLoaders 获取基本加载器。加载器对所有 ReflectionNamespace 对象都是通用的。

如测试代码 tests/0-DefinitionTest.php 中所述,您可以在任何时候创建自己的自动加载器。重要的是要请求类重新加载所有加载器,并重新加载每个对象以使用完整的加载器列表

<?php

// Ask to reload all loaders:
\ReflectionNamespace::getLoaders(TRUE);

// Refresh all loaded data to use the full loader list:
$modelsReflection->reload();
$appReflection->reload();

?>

如果加载器只会影响一个对象,您还可以要求ReflectionNamespace对象从新的加载器中加载。

<?php

$myNewLoader = new \Composer\Autoload\ClassLoader();

/* work on $myNewLoader... */

$appReflection->fillWithLoader($myNewLoader);

?>

您还可以填充一个简单的类映射。

<?php

$modelsReflection->fillWithClassMap([
	'App\\Models\\Article',
	'App\\Models\\Comment',
]);

?>

扩展类。

当然,类是可扩展的。所有方法和属性都是受保护的,以便您可以在子类中编辑它们。

请务必在使用前充分理解其工作原理。

贡献

报告错误

如果您遇到奇怪的行为,某些类未检测到,命名空间缺失,检测到异常?请打开一个包含尽可能多信息的工单,让我们帮助您 :)。

开发

首先,在您的组织中分叉项目。完成后,显然您需要克隆您的仓库。

克隆后,您需要通过运行以下命令准备所有未来的测试:composer prepare-test

进行您的修改,在推送和打开PR之前,运行此命令并确保它工作良好:composer test

当然,如果您添加功能或代码,或简单地修复一个显著的错误,您需要编写测试 :)。

提前感谢您的贡献 ;)

捐赠

因为它花费了我时间,而且我仍然是一个需要咖啡的简单学生,请不要犹豫在此捐赠,这将是我工作的荣幸和认可 :)。

PayPal