mschop / pathogen
通用的PHP路径库。
Requires
- php: >=7.4
- mschop/simplified-isolator: ^0.1
- symfony/polyfill-mbstring: *
Requires (Dev)
- ext-xdebug: *
- eloquent/liberator: ~3
- infection/infection: ^0.26.5
- phake/phake: ^4.2
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2024-08-24 12:36:28 UTC
README
通用的PHP路径库。
未来开发
此包是已废弃的包 eloquent/pathogen 的分支。我将继续在这个库上工作。请随时提出功能请求或错误报告。
安装和文档
什么是 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 }
特殊路径
'root'路径被认为是最高级的绝对路径,表示为一个单独的分隔符,没有原子(/
)。
'self'路径被认为是指向'当前'路径的,表示为一个单独的self原子(.
)。
创建路径
静态工厂方法
创建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'
路径归一化
路径规范化是将路径转换为最简或规范形式的过程。这意味着尽可能多地解析self和父原子。例如,路径/path/to/foo/../bar
规范化为/path/to/bar
。
规范化对绝对路径和相对路径的工作方式不同。绝对路径总是可以解析为没有self或父原子的规范形式。相对路径通常可以简化,但仍可能包含这些特殊原子。例如,路径../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'