bolt / 病原体
pathogen 的分支,pathogen 是一个通用的 PHP 路径库,但不使用 isolator。
Requires
- php: >=5.3
- symfony/polyfill-mbstring: ^1.0
Requires (Dev)
- eloquent/liberator: ~2
- icecave/archer: ~1
This package is not auto-updated.
Last update: 2020-01-24 15:58:48 UTC
README
PHP 的通用路径库。
注意:这是 Bolt 对 pathogen 的分支
它不包含也不与 isolator 包一起使用。
安装和文档
- 作为 Composer 包 eloquent/pathogen 可用。
- API 文档 可用。
什么是 Pathogen?
Pathogen 是一个路径操作库。 Pathogen 支持文件系统路径,包括 Unix 和 Windows 风格的路径,但它是一个真正的通用路径实现,能够表示 URI 路径和其他类似结构,同时提供全面的 API。
目录
Pathogen 概念
路径部分
Pathogen 路径的整体结构可以分解成更小的部分。此图显示了这些命名部分中的一些,它们适用于典型的路径
A A ___ A ___
/ \ / \ / \
/foo/bar/baz.qux.pop
\_________/
name
\__________________/
path
A = atom
“名称”部分可以进一步分解如下
NWE E
/ \ / \
baz.qux.pop
\_/ \_____/
NP NS
NWE = name without extension
E = extension
NP = name prefix
NS = name suffix
路径原子
在 Pathogen 中,一个路径由一系列“原子”组成。原子是路径层次结构中的单个部分。对于路径 /path/to/foo
,原子序列将是 path
、to
、foo
。斜杠字符称为“分隔符”。
在Pathogen中,点.
和点点..
具有特殊含义。单个点.
被称为“自身原子”,通常用于引用当前路径。双点..
被称为“父级原子”,用于引用当前路径之上的路径。任何熟悉典型文件系统路径的人应该已经熟悉它们的行为了。
给定一个路径实例,路径的原子可以按以下方式确定
$atoms = $path->atoms(); // returns an array of strings
路径名
路径的“名称”部分只是路径的最后一个原子。如果一个路径没有原子,它的名称是一个空字符串。给定一个路径实例,路径的名称可以这样确定
$name = $path->name(); // returns a string
路径名扩展
路径的名称可以使用扩展分隔符(.
)进一步分割。例如,给定路径名foo.bar.baz
,Pathogen可以确定“无扩展名称”(foo.bar
)、“名称前缀”(foo
)、“名称后缀”(bar.baz
)和“扩展”(baz
)。
给定一个路径实例,可以使用以下方式检索各个部分
$nameWithoutExtension = $path->nameWithoutExtension(); // returns a string $namePrefix = $path->namePrefix(); // returns a string $nameSuffix = $path->nameSuffix(); // returns a string or null $extension = $path->extension(); // returns a string or null
尾部分隔符
Pathogen能够表示带有尾部分隔符(/
)的路径。这在某些逻辑中尾部分隔符有特殊意义时很有用,例如Unix cp命令的行为。尾部分隔符的支持完全是针对使用Pathogen的开发者;它不影响Pathogen本身使用的任何逻辑。
值得注意的是,Pathogen生成的所有新路径实例都会删除任何尾部斜杠,除非明确指定不这样做。
绝对路径和相对路径
在Pathogen中,绝对路径和相对路径由两个不同的类表示。虽然这两个类都实现了共同的PathInterface,但分别由AbsolutePathInterface或RelativePathInterface提供了其他方法。
这种区分提供了许多好处,其中之一是利用PHP的类型提示来限制所需的路径类型
use Eloquent\Pathogen\AbsolutePathInterface; use Eloquent\Pathogen\PathInterface; use Eloquent\Pathogen\RelativePathInterface; function anyPath(PathInterface $path) { // accepts any path } function absoluteOnly(AbsolutePathInterface $path) { // accepts only absolute paths } function relativeOnly(RelativePathInterface $path) { // accepts only relative paths }
特殊路径
“根”路径被认为是最高级别的绝对路径,表示为不带原子的单个分隔符(/
)。
“自身”路径被认为是指向“当前”路径,表示为单个自身原子(.
)。
创建路径
静态工厂方法
创建Pathogen路径的最简单方法是使用静态工厂方法。要有效地使用此方法,只需选择最合适的类来表示路径类型
use Eloquent\Pathogen\AbsolutePath; use Eloquent\Pathogen\FileSystem\FileSystemPath; use Eloquent\Pathogen\Path; use Eloquent\Pathogen\RelativePath; use Eloquent\Pathogen\Unix\UnixPath; use Eloquent\Pathogen\Windows\AbsoluteWindowsPath; use Eloquent\Pathogen\Windows\WindowsPath; $path = Path::fromString('/path/to/foo'); // absolute path $path = Path::fromString('bar/baz'); // relative path $path = AbsolutePath::fromString('/path/to/foo'); // only creates absolute paths $path = RelativePath::fromString('bar/baz'); // only creates relative paths $path = FileSystemPath::fromString('/path/to/foo'); // Unix path $path = FileSystemPath::fromString('C:\path\to\foo'); // Windows path $path = UnixPath::fromString('/path/to/foo'); // only creates Unix paths $path = WindowsPath::fromString('C:\path\to\foo'); // only creates Windows paths $path = AbsoluteWindowsPath::fromString('C:\path\to\foo'); // only creates absolute Windows paths
除了fromString()
方法之外,还有其他工厂方法,一些是所有路径共有的,一些更专业
use Eloquent\Pathogen\Path; use Eloquent\Pathogen\Windows\AbsoluteWindowsPath; // Equivalent to '/path/to/foo' $path = Path::fromAtoms(array('path', 'to', 'foo')); // Equivalent to 'C:\path\to\foo' $path = AbsoluteWindowsPath::fromDriveAndAtoms(array('path', 'to', 'foo'), 'C');
工厂对象
Pathogen 提供用于创建路径的工厂类。所有路径工厂都实现了 PathFactoryInterface 接口,该接口允许从各种输入类型创建路径。
路径工厂的使用示例如下:
use Eloquent\Pathogen\FileSystem\Factory\FileSystemPathFactory; $factory = new FileSystemPathFactory; $pathFoo = $factory->create('/path/to/foo'); $pathBar = $factory->create('C:/path/to/bar');
路径解析
路径解析涉及从一个可能是相对或绝对路径中,确定该路径指向的位置,给定一个已知的“基础”路径。路径解析的结果始终是一个绝对路径。
例如,考虑当前路径为 /path/to/foo
。相对路径 bar/baz
将解析为 /path/to/foo/bar/baz
。相反,绝对路径 /path/to/qux
在解析后不会改变,因为它已经是绝对路径。
解析方法
使用 Pathogen 实现路径解析的最简单方法是在路径上使用最合适的方法
use Eloquent\Pathogen\FileSystem\FileSystemPath; $basePath = FileSystemPath::fromString('/path/to/foo'); $relativePath = FileSystemPath::fromString('bar/baz'); $absolutePath = FileSystemPath::fromString('/path/to/qux'); echo $basePath->resolve($relativePath); // outputs '/path/to/foo/bar/baz' echo $basePath->resolve($absolutePath); // outputs '/path/to/qux' echo $relativePath->resolveAgainst($basePath); // outputs '/path/to/foo/bar/baz'
解析对象
路径解析器也是 Pathogen 中的一个独立概念。下面是一个简单的使用示例
use Eloquent\Pathogen\FileSystem\FileSystemPath; use Eloquent\Pathogen\Resolver\PathResolver; $resolver = new PathResolver; $basePath = FileSystemPath::fromString('/path/to/foo'); $relativePath = FileSystemPath::fromString('bar/baz'); $absolutePath = FileSystemPath::fromString('/path/to/qux'); echo $resolver->resolve($basePath, $relativePath); // outputs '/path/to/foo/bar/baz' echo $resolver->resolve($basePath, $absolutePath); // outputs '/path/to/qux'
路径归一化
路径归一化是将路径转换为最简单或 规范 形式的过程。这意味着尽可能多地解析自身和父元素。例如,路径 /path/to/foo/../bar
归一化后变为 /path/to/bar
。
对于绝对路径和相对路径,归一化工作方式不同。绝对路径始终可以解析为没有自身或父元素的规范形式。相对路径通常可以简化,但仍可能包含这些特殊元素。例如,路径 ../foo/../..
实际上归一化后为 ../..
。
注意,对于绝对路径,根路径(/
)是父元素将归一化的最高路径。也就是说,具有比常规元素更多父元素的路径,如 /..
、/../..
或 /foo/../..
,都将归一化为根路径(/
)。
通常,在 Pathogen 中,除非需要用于计算,或者通过 API 手动进行,否则不会进行归一化。如果需要某种原因的归一化路径,这留给开发者处理。
归一化方法
归一化路径的最简单方法是使用 normalize()
方法
use Eloquent\Pathogen\FileSystem\FileSystemPath; $path = FileSystemPath::fromString('/path/./to/foo/../bar'); echo $path->normalize(); // outputs '/path/to/bar'
归一化对象
路径归一化器也是 Pathogen 中的一个独立概念。下面是一个简单的使用示例
use Eloquent\Pathogen\FileSystem\FileSystemPath; use Eloquent\Pathogen\FileSystem\Normalizer\FileSystemPathNormalizer; $normalizer = new FileSystemPathNormalizer; $path = FileSystemPath::fromString('/path/./to/foo/../bar'); echo $normalizer->normalize($path); // outputs '/path/to/bar'
文件系统路径
Pathogen 以 平台无关 的方式支持处理文件系统路径。根据情况,Pathogen 支持两种方法。
第一种方法是检查路径字符串,并根据“最佳猜测”创建适当的路径实例。这由 FileSystemPath 类处理
use Eloquent\Pathogen\FileSystem\FileSystemPath; $pathFoo = FileSystemPath::fromString('/path/to/foo'); // creates a Unix-style path $pathBar = FileSystemPath::fromString('C:/path/to/bar'); // creates a Windows path
第二种方法是根据代码运行的当前平台创建路径。也就是说,在 Linux 或 Unix 下运行时,创建 Unix 风格的路径,在 Windows 下运行时,创建 Windows 路径。这由 PlatformFileSystemPath 处理
use Eloquent\Pathogen\FileSystem\PlatformFileSystemPath; // creates a path to match the current platform $path = PlatformFileSystemPath::fromString('/path/to/foo');
请注意,FileSystemPath 和 PlatformFileSystemPath 仅是具有静态方法的工具类。实际使用的路径类将取决于输入。如果需要为文件系统路径进行类型提示,应使用 FileSystemPathInterface 或其更专业的子接口。
路径的不可变性
Pathogen 中的路径是 不可变的,这意味着一旦创建,就不能修改。在对路径执行一些修改操作,如规范化或解析时,会生成一个新的路径实例,而不是修改原始实例。这允许将路径作为接口的一部分暴露,而不会创建泄漏的抽象。
Windows 路径支持
Pathogen 提供了对 Windows 路径的支持。除了 Unix 风格路径可用的方法外,Windows 路径还包含一个可选的驱动器指定符。驱动器指定符可通过 drive()
方法访问。
$drive = $path->drive(); // returns a single-character string, or null
依赖消费者特性
Pathogen 提供了一些 特性,以便针对 PHP 5.4 及更高版本进行代码编写时,可以极其简单地消费其服务。
依赖消费者特性的概念很简单。如果一个类需要,例如,路径工厂,它可以简单地使用一个 PathFactoryTrait
。这给类提供了 setPathFactory()
和 pathFactory()
方法,用于管理路径工厂依赖。
以下示例演示了如何使用文件系统路径工厂特性
use Eloquent\Pathogen\FileSystem\Factory\Consumer\FileSystemPathFactoryTrait; class ExampleConsumer { use FileSystemPathFactoryTrait; } $consumer = new ExampleConsumer; echo get_class($consumer->pathFactory()); // outputs 'Eloquent\Pathogen\FileSystem\Factory\FileSystemPathFactory'
可用的依赖消费者特性
使用示例
将用户提供的路径解析为当前工作目录
use Eloquent\Pathogen\FileSystem\Factory\PlatformFileSystemPathFactory; $factory = new PlatformFileSystemPathFactory; $workingDirectoryPath = $factory->createWorkingDirectoryPath(); $path = $workingDirectoryPath->resolve( $factory->create($_SERVER['argv'][1]) );
将路径解析为另一个任意路径
use Eloquent\Pathogen\Path; $basePath = Path::fromString('/path/to/base'); $path = Path::fromString('../child'); $resolvedPath = $basePath->resolve($path); echo $resolvedPath->string(); // outputs '/path/to/base/../child' echo $resolvedPath->normalize()->string(); // outputs '/path/to/child'
确定一个路径是否在另一个路径内部存在
use Eloquent\Pathogen\Path; $basePath = Path::fromString('/path/to/foo'); $pathA = Path::fromString('/path/to/foo/bar'); $pathB = Path::fromString('/path/to/somewhere/else'); var_dump($basePath->isAncestorOf($pathA)); // outputs 'bool(true)' var_dump($basePath->isAncestorOf($pathB)); // outputs 'bool(false)'
将扩展名追加到路径中
use Eloquent\Pathogen\Path; $path = Path::fromString('/path/to/foo.bar'); $pathWithExtension = $path->joinExtensions('baz'); echo $pathWithExtension->string(); // outputs '/path/to/foo.bar.baz'
替换路径的扩展名
use Eloquent\Pathogen\Path; $path = Path::fromString('/path/to/foo.bar'); $pathWithNewExtension = $path->replaceExtension('baz'); echo $pathWithNewExtension->string(); // outputs '/path/to/foo.baz'
替换路径的一部分
use Eloquent\Pathogen\Path; $path = Path::fromString('/path/to/foo/bar'); $pathWithReplacement = $path->replace(1, array('for', 'baz'), 2); echo $pathWithReplacement->string(); // outputs '/path/for/baz/bar'