【PHP入门系列】4-PHP命名空间与包管理
在现代的PHP项目中,OOP已经普及伴随着生态的不断扩大,也带了项目的管理问题。命名空间和包管理已经是实际项目中必不可少的组成。
命名空间
什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 可以同时在目录 /home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问 foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/greg/foo.txt。这个原理应用到程序设计领域就是命名空间的概念。
在 PHP 中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:
- 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
- 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
PHP 命名空间提供了一种将相关的类、函数和常量组合到一起的途径。因此把你的代码放在你的命名空间下就非常重要,避免其他开发者担心与第三方类库冲突。
PSR-4 提供了一种命名空间的推荐使用方式,它提供一个标准的文件、类和命名空间的使用惯例,进而让代码做到随插即用。如果你在新应用或扩展包中使用自动加载标准,应优先考虑使用 PSR-4。
基础
- 命名空间通过关键字 namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间,除了一个以外:declare关键字。
- 访问当前命名空间内部元素的方法,__NAMESPACE__ 魔术常量和 namespace 关键字。
- 通过操作符 use 来使用namespace的类
- 如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。在名称前加上前缀 \ 表示该名称是全局空间中的名称,即使该名称位于其它的命名空间中时也是如此。
包管理
PHP 有很多可供使用的库、框架和组件。目前 PHP 有两个使用较多的包管理系统 Composer 和 PEAR。Composer是PHP最流行的包管理器,受益于命名空间和自动加载, 通过Composer可以随时可以在你的项目中使用第三方优秀的项目。Composer 有点类似于 Node.js 世界里的 NPM。
安装
可以从官网查看完整的流程:官方地址, 国内的话你可能需要国内的加速镜像
Composer是一个 杰出 的依赖管理器。在 composer.json 文件中列出你项目所需的依赖包,加上一点简单的命令,Composer 将会自动帮你下载并设置你的项目依赖。完整学习可以查看 官方文档,或者国内的翻译文档 composer中文文档
composer.json设置
{
"require": {
"monolog/monolog": "1.0.*"
}
}
你可以看到, require 需要一个 包名称 (例如 monolog/monolog) 映射到 包版本 (例如 1.0.*) 的对象。
包版本约束可以用几个不同的方法来指定。
名称 | 实例 | 描述 |
---|---|---|
确切的版本号 | 1.0.2 | 你可以指定包的确切版本 |
范围 | >=1.0 >=1.0,<2.0 >=1.0,<1.1丨>=1.2 | 通过使用比较操作符可以指定有效的版本范围。 有效的运算符:> 、>= 、< 、<= 、!= 。 你可以定义多个范围,用逗号隔开,这将被视为一个逻辑AND处理。一个管道符号丨 将作为逻辑OR处理。 AND 的优先级高于 OR。 |
通配符 | 1.0.* | 你可以使用通配符* 来指定一种模式。1.0.* 与>=1.0,<1.1 是等效的。 |
赋值运算符 | ~1.2 | 这对于遵循语义化版本号的项目非常有用。~1.2 相当于>=1.2,<2.0 。想要了解更多,请阅读下一小节。 |
下一个重要版本(波浪号运算符)~ 最好用例子来解释: ~1.2 相当于 >=1.2,<2.0,而 ~1.2.3 相当于 >=1.2.3,<1.3。
安装依赖包
获取定义的依赖到你的本地项目,只需要调用 composer.phar 运行 install 命令:php composer.phar install
将创建一个 composer.lock 文件到你项目的根目录中,并把第三方的代码下载到一个指定的目录 vendor。composer.lock 文件,这将锁定改项目的特定版本。这意味着如果你的依赖更新了新的版本,你将不会获得任何更新。
此时要更新你的依赖版本请使用 update 命令:php composer.phar update
自动加载
对于库的自动加载信息,Composer 生成了一个 vendor/autoload.php 文件。你可以简单的引入这个文件,你会得到一个免费的自动加载支持。
你甚至可以在 composer.json 中添加一个 autoload 指令,来添加自己的自动加载声明
{
...
"autoload": {
"psr-4": {"Acme\\": "src/"}
}
}
命令行工具
composer命令行工具可以通过composer help获取帮助。下面是常用的一些命令以及参数
composer require参数
- --dev: 将依赖添加到
require-dev
。 - --prefer-source: 尽可能从
源码
安装。 - --prefer-dist: 尽可能从
发布
安装。 - --no-progress: 移除进度条的显示来避免和一些终端或不支持退格字符的脚本冲突。
- --no-suggest: 跳过输出中建议的依赖。
- --no-update: 禁止依赖自动升级。
- --no-scripts: 跳过执行在
composer.json
定义的脚本。 - --update-no-dev: 用
--no-dev
选项执行依赖升级。 - --update-with-dependencies: 升级最近引入的依赖,排除根依赖。
- --update-with-all-dependencies: 升级最近引入的依赖,包括根依赖。
- --ignore-platform-reqs: 忽略
php
,hhvm
,lib-*
和ext-*
依赖并强制安装,即使本地计算机不能完全支持这些特性。详见 platform。 详见platform
。 - --prefer-stable: 稳定版本优先。
- --prefer-lowest: 最低版本优先。测试依赖的最低版本时候很有用,一般和
--prefer-stable
联用。 - --sort-packages: 保持
composer.json
中的依赖排列顺序。 - --optimize-autoloader (-o): 转换 PSR-0/4 自动加载到 classmap 以获取更快的加载速度。很建议在生产环境中这样做,但执行比较耗时,所以默认是关闭的。
- --classmap-authoritative (-a): 只自动加载 classmap 中的类名。需要开启
--optimize-autoloader
。 - --apcu-autoloader: 使用 APCu 来缓存找到和没找到的类名。
常用的composer install参数有
- --prefer-source: 有两种方式下载扩展包:
源代码版
和可执行版
。对于稳定版本,Composer 会默认使用可执行版
。源码版
来自版本控制工具的,如果启用了--prefer-source
, Composer 会安装源码版
。这有一个小提示,如果你想修复 bug ,那么从依赖关系中,直接本地克隆一个仓库。 - --prefer-dist: 和
--prefer-source
相反,如果可执行版本
存在,Compser 会直接安装。这会加快服务器上构建速度同时不用更新 vendor 。你没有正确安装, git 克隆该扩展包也是一种方式。 - --dry-run: 如果想运行时指明不安装某一扩展包,你可以使用
--dry-run
。这会模拟该安装并提示会出现的问题。 - --dev: 安装
require-dev
中的扩展列表(默认执行)。 - --no-dev: 跳过
require-dev
中的扩展列表。. 自动加载中会跳过autoload-dev
规则。 - --no-autoloader: 跳过自动加载。
- --no-scripts: 跳过
composer.json
中声明的脚本。 - --no-progress: 移除进度的展示,有的命令或脚本不处理退格字符,引起显示混乱。
- --no-suggest: 跳过扩展包建议。
- --optimize-autoloader (-o): 转换 PSR-0/4 autoloading 到 classmap 可以获得更快的加载支持。特别是在生产环境下建议这么做,但由于运行需要一些时间,因此并没有作为默认值。
- --classmap-authoritative (-a): 仅从 classmap 加载类。会附带启动
--optimize-autoloader
。 - --apcu-autoloader: 启用 APCu 来缓存所有类。
- --ignore-platform-reqs: 忽略
php
,hhvm
,lib-*
和ext-*
要求并强制安装,就算本地环境不完全要求。平台配置选项可见platform
常用的composer update
- --prefer-source: 如果可以的话从
源码
安装依赖。 - --prefer-dist: 如果可以的话从
发布
安装依赖。 - --dry-run: 模拟执行命令但事实上不做任何更改。
- --dev: 安装
require-dev
列出的依赖(这也是默认行为)。 - --no-dev: 不安装
require-dev
列出的依赖。自动加载生成也会跳过autoload-dev
。 - --lock: 只升级 lock 文件的哈希以消除 lock 文件过期的警告。
- --no-autoloader: 不生成自动加载。
- --no-scripts: 跳过执行
composer.json
中定义的脚本。 - --no-progress: 移除进度条的显示来避免和一些终端或不支持退格字符的脚本冲突。
- --no-suggest: 跳过输出中建议的依赖。
- --with-dependencies: 添加白名单中的依赖到白名单,除了那些根依赖。
- --with-all-dependencies: 添加所有白名单中的依赖到白名单,包括那些根依赖。
- --optimize-autoloader (-o): 转换 PSR-0/4 自动加载到 classmap 以获取更快的加载速度。很建议在生产环境中这样做,但执行比较耗时,所以默认是关闭的。
- --classmap-authoritative (-a): 只自动加载 classmap 中的类名。需要开启
--optimize-autoloader
。 - --apcu-autoloader: 使用 APCu 来缓存找到和没找到的类名。
- --ignore-platform-reqs: 忽略
php
,hhvm
,lib-*
和ext-*
依赖并强制安装,即使本地计算机不能完全支持这些特性。详见platform
。 - --prefer-stable: 稳定版本优先。
- --prefer-lowest: 最低版本优先。测试依赖的最低版本时候很有用,一般和
--prefer-stable
联用。 - --interactive: 交互式的选择哪些依赖要被升级,带自动补全。
- --root-reqs: 限制根依赖的升级。