bolt/病原体

此包已被弃用且不再维护。未建议替代包。

pathogen 的分支,pathogen 是一个通用的 PHP 路径库,但不使用 isolator。

0.6.2 2017-06-10 08:28 UTC

This package is not auto-updated.

Last update: 2020-01-24 15:58:48 UTC


README

PHP 的通用路径库。

注意:这是 Bolt 对 pathogen 的分支

它不包含也不与 isolator 包一起使用。

The most recent stable version is 0.6.1 Current build status image Current coverage status image

安装和文档

什么是 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,原子序列将是 pathtofoo。斜杠字符称为“分隔符”。

Pathogen中,点.和点点..具有特殊含义。单个点.被称为“自身原子”,通常用于引用当前路径。双点..被称为“父级原子”,用于引用当前路径之上的路径。任何熟悉典型文件系统路径的人应该已经熟悉它们的行为了。

给定一个路径实例,路径的原子可以按以下方式确定

$atoms = $path->atoms(); // returns an array of strings

路径名

路径的“名称”部分只是路径的最后一个原子。如果一个路径没有原子,它的名称是一个空字符串。给定一个路径实例,路径的名称可以这样确定

$name = $path->name(); // returns a string

路径名扩展

路径的名称可以使用扩展分隔符(.)进一步分割。例如,给定路径名foo.bar.bazPathogen可以确定“无扩展名称”(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,但分别由AbsolutePathInterfaceRelativePathInterface提供了其他方法。

这种区分提供了许多好处,其中之一是利用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');

请注意,FileSystemPathPlatformFileSystemPath 仅是具有静态方法的工具类。实际使用的路径类将取决于输入。如果需要为文件系统路径进行类型提示,应使用 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'