原文链接https://www.mywaiting.com/weblogs/pyenv-install-for-virtualenv-and-accelerate-in-mainland-china/

使用 Python 的人时常会精神错乱,因为 Python 的版本太多了,有些 Python Package 还会挑版本,这让开发、维护甚至生产环境出现很多很恼人的问题。于是针对这个问题,一系列的 Python 独立包环境出现了,比如有名的 virtualenv 使用空间换时间的战术,通过复制一份已有的 Python 环境,修改系统,特别是 Linux 系统的 PATH 变量使得在该虚拟包环境中的 Python 路径指向自己,这样就可以不受系统的 Python 版本影响。

但是 virtualenv 的出现只是部分地解决 Python 的独立环境问题,并没有完全地解决其独立环境的构建问题。如果我需要在同一个系统里,同时存在 Python2.6 、Python2.7 、Python3.5 的版本环境,甚至是 jython、 pypy 这样的环境,并且可以根据需要来切换需要的 Python 版本,使用 virtualenv 会比较麻烦。

这个就是 Pyenv 出现的原因,作为一个 Python 的版本管理工具,实现无缝的 Python 版本切换,并且整合 pyenv-virtualenv 的插件,也使得 Pyenv 具备 virtualenv 一样的创建具体 Python 版本的虚拟包环境的能力。
pyenv 原理

Pyenv 实现的原理其实很简单。如果你有仔细地观察过 Linux 系统的 PATH ,可以在 Linux Shell 中使用命令 $ echo $PATH 查看,那么你就会发现 Pyenv 简单的魔法。简单说来,就是 Pyenv 会在系统的 Shell 环境 PATH 变量中首先插入类似的路径 ~/.pyenv/shims;~/.pyenv/plugins/pyenv-virtualenv/shims 所有在该系统 Shell 环境执行的 Python 程序都会首先第被这个 shims 路径截获,而 shims 路径指向哪个 Python 的版本,那就看你激活的是哪个 Python 的版本啦!
pyenv 安装

Pyenv 的安装异常简单,只需要使用作者提供的一键安装脚本即可

# Github
# curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
# recommand
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
# simple
curl https://pyenv.run | bash

然后将 Pyenv 的相关初始化实现放入自己的 ~/.bashrc 以方便使用

echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"'               >> ~/.bashrc
echo 'eval "$(pyenv virtualenv-init -)"'    >> ~/.bashrc

世界就是这么简单!
pyenv 国内加速

虽然是安装好了 Pyenv ,但是当你需要具体的 Python 的环境,也是需要下载对应的 Python 二进制程序包来安装的啊!这时候,非常蛋疼的事情就出现了,因为 Pyenv 是直接从 python.org 官网上下载对应版本的 Python 程序包的。你想想那网速,还有那众所周知原因不时发神经的网络,目测喝几天的咖啡都不一定能安装好。

其实呢, Pyenv 下载各种 Python 的二进制程序包,都是会首先放到自己的这个 ~/.pyenv/cache 目录下面的。在需要下载什么文件之前, Pyenv 会先到这个目录找以前是否下载过了,如果已经下载好就直接使用这个目录里面对应的文件。

有上面的思路就很简单啦!利用国内的各种 Python 镜像来下载 Python 的二进制程序包,然后放入到 Pyenv 对应的这个目录里面!这样就可以简单地加速 Pyenv 的安装过程。

国内的 Python 镜像有很多,大概罗列如下,自己找自己对应的速度最快的吧

http://mirrors.sohu.com/python/ (UPDATE 2020/02/22 时常无法访问)
# 强烈推荐
https://npm.taobao.org/mirrors/python/

顺便提供一键安装的脚本,用于简化这个世界

$ export v=2.7.6; wget https://npm.taobao.org/mirrors/python/$v/Python-$v.tar.xz -P ~/.pyenv/cache/; pyenv install $v 

解释一下这个意思,就是从 https://npm.taobao.org/mirrors/python/ 上下载对应版本的 Python,放入到 ~/.pyenv/cache 目录里面,然后使用 pyenv install $v 即可,$v 变量代表 Python 的版本,自己需要哪个版本,就把这个改成自己需要的版本号!

注意 ~/.pyenv/cache 需要自己建立,假如不存在的话 (UPDATE 2020/02/22)

pip 安装国内加速

既然说到国内安装加速,还是顺便说说这个 pip 安装 Python 程序包加速的问题吧。pip 在国内有很多的镜像,比较稳定有

http://mirrors.aliyun.com/pypi/simple
http://pypi.douban.com/simple
http://pypi.v2ex.com/simple
https://pypi.tuna.tsinghua.edu.cn/simple (特别推荐)

根据自己所在位置的速度来选用吧,一般说来,TUNA 的速度是比较不错的

只使用镜像来加速一个 Python 程序包的安装可以一个命令搞定,比如说安装 Tornado Web 框架

pip install tornado -i http://pypi.douban.com/simple

但如果为了方便工作,可以配置成默认的 pip 安装镜像,创建或者修改以下文件 ~/.pip/pip.conf 写入以下文件内容

[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host = pypi.tuna.tsinghua.edu.cn

这样在使用 pip 来安装时,会默认调用该镜像。

以上,就是我使用 pyenv 一些小总结,希望你看到的话,能觉得有用。

Docker redis 启动问题, 采用 redis:6.2.6 未提示错误...

:C 06 Sep 2023 05:27:08.924 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo

1:C 06 Sep 2023 05:27:08.924 # Redis version=6.2.13, bits=64, commit=00000000, modified=0, pid=1, just started

1:C 06 Sep 2023 05:27:08.924 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf

1:M 06 Sep 2023 05:27:08.924 * monotonic clock: POSIX clock_gettime

1:M 06 Sep 2023 05:27:08.927 * Running mode=standalone, port=6379.

1:M 06 Sep 2023 05:27:08.927 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

1:M 06 Sep 2023 05:27:08.927 # Server initialized

1:M 06 Sep 2023 05:27:08.927 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

1:M 06 Sep 2023 05:27:08.928 # Fatal: Can't initialize Background Jobs.

Alpha、Beta、RC、GA版本的区别


开发期

Pre-alpha

有时候软件会在Alpha或Beta版本前先发布Pre-alpha版本。一般而言相对于Alpha或Beta版本,Pre-alpha版本是一个功能不完整的版本。

Alpha

Alpha版本仍然需要测试,其功能亦未完善,因为它是整个软件发布周期中的第一个阶段,所以它的名称是“Alpha”,希腊字母中的第一个字母“α”。
Alpha版本通常会送到开发软件的组织或某群体中的软件测试者作内部测试。在市场上,越来越多公司会邀请外部客户或合作伙伴参与其测试。这令软件在此阶段有更大的可用性测试.

Beta

Beta版本是软件最早对外公开的软件版本,由公众(通常为公司外的第三方开发者和业余玩家)参与测试。 因为是Alpha的下一个阶段,所以为希腊字母的第二个字Beta (β)。 一般来说,Beta包含所有功能,但可能有一些已知问题和较轻微的程序错误(BUG),要进行调试(debug)。Beta版本的测试者通常是开发软件的组织的客户,他们会以免费或优惠价钱得到软件。Beta版本亦作为测试产品的支持和市场反应等。
其他情况不同企业有不同的称法,例如微软曾以Community Technology Preview(简称CTP,中文称为“社群技术预览”)为发布软件的测试版本之一,微软将这个阶段的软件散布给有需要先行试用的用户或厂商,并收集这些人的使用经验,以便作为进一步修正软件的参考。

Release Candidate

Release Candidate(简称RC)指可能成为最终产品的候选版本,如果未出现问题则可发布成为正式版本。在此阶段的产品通常包含所有功能、或接近完整,亦不会出现严重问题。
多数开源软件会推出两个RC版本,最后的RC2则成为正式版本。闭源软件较少公开使用,微软公司Windows 7上应用此名称。苹果公司把在这阶段的产品称为“Golden Master Candidate”(简称GM Candidate),而最后的GM即成为正式版本。而 iOS 自 14.2 开始亦采用 RC 称呼处于此阶段的版本状态。

完成期

生产商发放(Release to Manufacturing,RTM)

生产商发放(Release to Manufacturing,缩写RTM)是软件产品准备交付时使用的术语,来自于以前还需要使用实体载具(光盘,硬盘等)来进行安装的时代。[1]某些计算机程序以“RTM”作为软件版本代号,例如微软Windows 7发行零售版前的RTM版本主要是发放给组装机生产商用,使制造商能够提早进行集成工作或解决软件与硬件设备可能遇到的错误。RTM版本并不一定意味着创作者解决了软件所有问题;仍有可能向公众发布前更新版本。以Windows 7为例:RTM版与零售版的版本号是一样的。[2]

一般可用(General availability,GA)

一般可用(General availability, 缩写GA)是所有必要的商业活动已经完成,该软件产品已经可以发售的阶段。然而,这取决于语言、地域和电子设备与媒体的可用性,有些地区之间可能会有上市时间的延迟。商业活动可能也包括安全性和合法测试,以及本地化和全球销售的可能性评估。RTM与GA的间隔可能会是1周或几个月,因为在此过程中需要进行许多商业活动。在这个阶段,可以说软件已经“上线”了。

网络分发(Release to Web,RTW)

网络分发(Release to Web,缩写RTW),或称Web发布是一种利用互联网进行分发的软件交付方式。制造商在这种类型的发布中并不生产实体软件工具,而会借由OTA来进行发放。随着互联网使用人数的增长,RTW变得越来越普遍。

稳定版(Stable)

稳定版本来自预览版本释出使用与改善而修正完成,通常是初始版本进行几个小更新后的版本。为目前所使用的软件在符合需求规格的硬件与操作系统中运行不会造成严重的不兼容或是硬件冲突,其已受过某定量的测试无误后所释出者。

软件支持

在软件的生命周期内,有时会发布新版本、补丁服务包。例如Windows XP,其32位有3个服务包,64位版本有两个。这些服务包包含以单个可安装软件包的形式提供的更新、补丁和功能增强,也有新功能提供。一些软件,例如防病毒软件和游戏,需要长期的更新支持。

软件寿命结束

主条目:产品寿命结束

当软件不再销售并已被停止支持时,该产品即达到使用寿命终止阶段。但忠实用户群可能会继续存在,甚至是持续很久。例如Windows XP在中国大陆的占有率依然很高。

转载自:https://zh.wikipedia.org/zh-cn/%E8%BB%9F%E4%BB%B6%E7%89%88%E6%9C%AC%E9%80%B1%E6%9C%9F

发布于 2021-10-12 21:05

来源: https://zhuanlan.zhihu.com/p/420745873

https://semver.org/lang/zh-CN/
https://github.com/semver/semver.org.git


title: 语义化版本 2.0.0
language: zh-CN

author: Wayou Liu

语义化版本 2.0.0

摘要

版本格式:主版本号.次版本号.修订号,版本号递增规则如下:

  1. 主版本号:当你做了不兼容的 API 修改,
  2. 次版本号:当你做了向下兼容的功能性新增,
  3. 修订号:当你做了向下兼容的问题修正。

先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

简介

在软件管理的领域里存在着被称作“依赖地狱”的死亡之谷,系统规模越大,加入的包越多,你就越有可能在未来的某一天发现自己已深陷绝望之中。

在依赖高的系统中发布新版本包可能很快会成为噩梦。如果依赖关系过高,可能面临版本控制被锁死的风险(必须对每一个依赖包改版才能完成某次升级)。而如果依赖关系过于松散,又将无法避免版本的混乱(假设兼容于未来的多个版本已超出了合理数量)。当你项目的进展因为版本依赖被锁死或版本混乱变得不够简便和可靠,就意味着你正处于依赖地狱之中。

作为这个问题的解决方案之一,我提议用一组简单的规则及条件来约束版本号的配置和增长。这些规则是根据(但不局限于)已经被各种封闭、开放源码软件所广泛使用的惯例所设计。为了让这套理论运作,你必须先有定义好的公共 API。这可能包括文档或代码的强制要求。无论如何,这套 API 的清楚明了是十分重要的。一旦你定义了公共 API,你就可以透过修改相应的版本号来向大家说明你的修改。考虑使用这样的版本号格式:X.Y.Z(主版本号.次版本号.修订号)修复问题但不影响 API 时,递增修订号;API 保持向下兼容的新增及修改时,递增次版本号;进行不向下兼容的修改时,递增主版本号。

我称这套系统为“语义化的版本控制”,在这套约定下,版本号及其更新方式包含了相邻版本间的底层代码和修改内容的信息。

语义化版本控制规范(SemVer)

以下关键词 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、 RECOMMENDED、MAY、OPTIONAL 依照 RFC 2119 的叙述解读。

  1. 使用语义化版本控制的软件必须(MUST)定义公共 API。该 API 可以在代码中被定义或出现于严谨的文档内。无论何种形式都应该力求精确且完整。
  2. 标准的版本号必须(MUST)采用 X.Y.Z 的格式,其中 X、Y 和 Z 为非负的整数,且禁止(MUST NOT)在数字前方补零。X 是主版本号、Y 是次版本号、而 Z 为修订号。每个元素必须(MUST)以数值来递增。例如:1.9.1 -> 1.10.0 -> 1.11.0。
  3. 标记版本号的软件发行后,禁止(MUST NOT)改变该版本软件的内容。任何修改都必须(MUST)以新版本发行。
  4. 主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共 API 不应该被视为稳定版。
  5. 1.0.0 的版本号用于界定公共 API 的形成。这一版本之后所有的版本号更新都基于公共 API 及其修改内容。
  6. 修订号 Z(x.y.Z | x > 0)必须(MUST)在只做了向下兼容的修正时才递增。这里的修正指的是针对不正确结果而进行的内部修改。
  7. 次版本号 Y(x.Y.z | x > 0)必须(MUST)在有向下兼容的新功能出现时递增。在任何公共 API 的功能被标记为弃用时也必须(MUST)递增。也可以(MAY)在内部程序有大量新功能或改进被加入时递增,其中可以(MAY)包括修订级别的改变。每当次版本号递增时,修订号必须(MUST)归零。
  8. 主版本号 X(X.y.z | X > 0)必须(MUST)在有任何不兼容的修改被加入公共 API 时递增。其中可以(MAY)包括次版本号及修订级别的改变。每当主版本号递增时,次版本号和修订号必须(MUST)归零。
  9. 先行版本号可以(MAY)被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。数字型的标识符禁止(MUST NOT)在前方补零。先行版的优先级低于相关联的标准版本。被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。范例:1.0.0-alpha、1.0.0-alpha.1、1.0.0-0.3.7、1.0.0-x.7.z.92。
  10. 版本编译信息可以(MAY)被标注在修订版或先行版本号之后,先加上一个加号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。当判断版本的优先层级时,版本编译信息可(SHOULD)被忽略。因此当两个版本只有在版本编译信息有差别时,属于相同的优先层级。范例:1.0.0-alpha+001、1.0.0+20130313144700、1.0.0-beta+exp.sha.5114f85。
  11. 版本的优先层级指的是不同版本在排序时如何比较。
    1. 判断优先层级时,必须(MUST)把版本依序拆分为主版本号、次版本号、修订号及先行版本号后进行比较(版本编译信息不在这份比较的列表中)。
    2. 由左到右依序比较每个标识符,第一个差异值用来决定优先层级:主版本号、次版本号及修订号以数值比较。

      例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。

    3. 当主版本号、次版本号及修订号都相同时,改以优先层级比较低的先行版本号决定。

      例如:1.0.0-alpha < 1.0.0。

    4. 有相同主版本号、次版本号及修订号的两个先行版本号,其优先层级必须(MUST)透过由左到右的每个被句点分隔的标识符来比较,直到找到一个差异值后决定:
      1. 只有数字的标识符以数值高低比较。
      2. 有字母或连接号时则逐字以 ASCII 的排序来比较。
      3. 数字的标识符比非数字的标识符优先层级低。
      4. 若开头的标识符都相同时,栏位比较多的先行版本号优先层级比较高。

      例如:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0。

合法语义化版本的巴科斯范式语法

<valid semver> ::= <version core>
                 | <version core> "-" <pre-release>
                 | <version core> "+" <build>
                 | <version core> "-" <pre-release> "+" <build>

<version core> ::= <major> "." <minor> "." <patch>

<major> ::= <numeric identifier>

<minor> ::= <numeric identifier>

<patch> ::= <numeric identifier>

<pre-release> ::= <dot-separated pre-release identifiers>

<dot-separated pre-release identifiers> ::= <pre-release identifier>
                                          | <pre-release identifier> "." <dot-separated pre-release identifiers>

<build> ::= <dot-separated build identifiers>

<dot-separated build identifiers> ::= <build identifier>
                                    | <build identifier> "." <dot-separated build identifiers>

<pre-release identifier> ::= <alphanumeric identifier>
                           | <numeric identifier>

<build identifier> ::= <alphanumeric identifier>
                     | <digits>

<alphanumeric identifier> ::= <non-digit>
                            | <non-digit> <identifier characters>
                            | <identifier characters> <non-digit>
                            | <identifier characters> <non-digit> <identifier characters>

<numeric identifier> ::= "0"
                       | <positive digit>
                       | <positive digit> <digits>

<identifier characters> ::= <identifier character>
                          | <identifier character> <identifier characters>

<identifier character> ::= <digit>
                         | <non-digit>

<non-digit> ::= <letter>
              | "-"

<digits> ::= <digit>
           | <digit> <digits>

<digit> ::= "0"
          | <positive digit>

<positive digit> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

<letter> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J"
           | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T"
           | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" | "c" | "d"
           | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n"
           | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x"
           | "y" | "z"

为什么要使用语义化的版本控制?

这并不是一个新的或者革命性的想法。实际上,你可能已经在做一些近似的事情了。问题在于只是“近似”还不够。如果没有某个正式的规范可循,版本号对于依赖的管理并无实质意义。将上述的想法命名并给予清楚的定义,让你对软件使用者传达意向变得容易。一旦这些意向变得清楚,弹性(但又不会太弹性)的依赖规范就能达成。

举个简单的例子就可以展示语义化的版本控制如何让依赖地狱成为过去。假设有个名为“救火车”的函数库,它需要另一个名为“梯子”并已经有使用语义化版本控制的包。当救火车创建时,梯子的版本号为 3.1.0。因为救火车使用了一些版本 3.1.0 所新增的功能,你可以放心地指定依赖于梯子的版本号大于等于 3.1.0 但小于 4.0.0。这样,当梯子版本 3.1.1 和 3.2.0 发布时,你可以将直接它们纳入你的包管理系统,因为它们能与原有依赖的软件兼容。

作为一位负责任的开发者,你理当确保每次包升级的运作与版本号的表述一致。现实世界是复杂的,我们除了提高警觉外能做的不多。你所能做的就是让语义化的版本控制为你提供一个健全的方式来发行以及升级包,而无需推出新的依赖包,节省你的时间及烦恼。

如果你对此认同,希望立即开始使用语义化版本控制,你只需声明你的函数库正在使用它并遵循这些规则就可以了。请在你的 README 文件中保留此页链接,让别人也知道这些规则并从中受益。

FAQ

在 0.y.z 初始开发阶段,我该如何进行版本控制?

最简单的做法是以 0.1.0 作为你的初始化开发版本,并在后续的每次发行时递增次版本号。

如何判断发布 1.0.0 版本的时机?

当你的软件被用于正式环境,它应该已经达到了 1.0.0 版。如果你已经有个稳定的 API 被使用者依赖,也会是 1.0.0 版。如果你很担心向下兼容的问题,也应该算是 1.0.0 版了。

这不会阻碍快速开发和迭代吗?

主版本号为零的时候就是为了做快速开发。如果你每天都在改变 API,那么你应该仍在主版本号为零的阶段(0.y.z),或是正在下个主版本的独立开发分支中。

对于公共 API,若即使是最小但不向下兼容的改变都需要产生新的主版本号,岂不是很快就达到 42.0.0 版?

这是开发的责任感和前瞻性的问题。不兼容的改变不应该轻易被加入到有许多依赖代码的软件中。升级所付出的代价可能是巨大的。要递增主版本号来发行不兼容的改版,意味着你必须为这些改变所带来的影响深思熟虑,并且评估所涉及的成本及效益比。

为整个公共 API 写文档太费事了!

为供他人使用的软件编写适当的文档,是你作为一名专业开发者应尽的职责。保持项目高效的一个非常重要的部份是掌控软件的复杂度,如果没有人知道如何使用你的软件或不知道哪些函数的调用是可靠的,要掌控复杂度会是困难的。长远来看,使用语义化版本控制以及对于公共 API 有良好规范的坚持,可以让每个人及每件事都运行顺畅。

万一不小心把一个不兼容的改版当成了次版本号发行了该怎么办?

一旦发现自己破坏了语义化版本控制的规范,就要修正这个问题,并发行一个新的次版本号来更正这个问题并且恢复向下兼容。即使是这种情况,也不能去修改已发行的版本。可以的话,将有问题的版本号记录到文档中,告诉使用者问题所在,让他们能够意识到这是有问题的版本。

如果我更新了自己的依赖但没有改变公共 API 该怎么办?

由于没有影响到公共 API,这可以被认定是兼容的。若某个软件和你的包有共同依赖,则它会有自己的依赖规范,作者也会告知可能的冲突。要判断改版是属于修订等级或是次版等级,是依据你更新的依赖关系是为了修复问题或是加入新功能。对于后者,我经常会预期伴随着更多的代码,这显然会是一个次版本号级别的递增。

如果我变更了公共 API 但无意中未遵循版本号的改动怎么办呢?(意即在修订等级的发布中,误将重大且不兼容的改变加到代码之中)

自行做最佳的判断。如果你有庞大的使用者群在依照公共 API 的意图而变更行为后会大受影响,那么最好做一次主版本的发布,即使严格来说这个修复仅是修订等级的发布。记住, 语义化的版本控制就是透过版本号的改变来传达意义。若这些改变对你的使用者是重要的,那就透过版本号来向他们说明。

我该如何处理即将弃用的功能?

弃用现存的功能是软件开发中的家常便饭,也通常是向前发展所必须的。当你弃用部份公共 API 时,你应该做两件事:(1)更新你的文档让使用者知道这个改变,(2)在适当的时机将弃用的功能透过新的次版本号发布。在新的主版本完全移除弃用功能前,至少要有一个次版本包含这个弃用信息,这样使用者才能平顺地转移到新版 API。

语义化版本对于版本的字符串长度是否有限制呢?

没有,请自行做适当的判断。举例来说,长到 255 个字符的版本已过度夸张。再者,特定的系统对于字符串长度可能会有他们自己的限制。

“v1.2.3” 是一个语义化版本号吗?

“v1.2.3” 并不是的一个语义化的版本号。但是,在语义化版本号之前增加前缀 “v” 是用来表示版本号的常用做法。在版本控制系统中,将 “version” 缩写为 “v” 是很常见的。比如:git tag v1.2.3 -m "Release version 1.2.3" 中,“v1.2.3” 表示标签名称,而 “1.2.3” 是语义化版本号。

是否有推荐的正则表达式用以检查语义化版本号的正确性?

有两个推荐的正则表达式。第一个用于支持按组名称提取的语言(PCRE[Perl 兼容正则表达式,比如 Perl、PHP 和 R]、Python 和 Go)。

参见:https://regex101.com/r/Ly7O1x/3/

^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$

第二个用于支持按编号提取的语言(与第一个对应的提取项按顺序分别为:major、minor、patch、prerelease、buildmetadata)。主要包括 ECMA Script(JavaScript)、PCRE(Perl 兼容正则表达式,比如 Perl、PHP 和 R)、Python 和 Go。
参见:https://regex101.com/r/vkijKf/1/

^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$

关于

语义化版本控制的规范是由 Gravatars 创办者兼 GitHub 共同创办者 Tom Preston-Werner 所建立。

如果您有任何建议,请到 GitHub 上提出您的问题

许可证

知识共享 署名 3.0 (CC BY 3.0)

PHP 入门笔记


PHP 简介

PHP: Hypertext Preprocessor,超文本预处理器的字母缩写

示例:

<?php
echo "Hi, I'm a PHP script!";

PHP官网:https://www.php.net
PHP 手册:https://www.php.net/manual/zh/intro-whatis.php
PHP 下载:http://php.p2hp.com/downloads.php
PHP Windows: https://windows.php.net/download
Zend 引擎是开源的解释php语言的脚本引擎


PHP 中文镜像站:http://php.p2hp.com/
PHP 中文手册:http://php.p2hp.com/manual/zh/


PHP 解释器安装

以 Windows 环境 为例,下载 php-8.2.8-Win32-vs16-x64.zip 文件后解压到自定义目录下,以 表示安装目录。降 添加到系统或用户环境变量 PATH 下,例如以管理员身份运行 path-edit 编辑添加到 path 变量里。

编辑 php.ini 配置文件

解压后默认无 php.ini 文件,例如复制 php.ini-development 为 php.ini, 并编辑 php.ini 内配置:

; php 扩展库目录 (<php-path> 表示 PHP 解释器解压目录)
extension_dir=<php-path>/ext

;根据需要开启扩展插件
extension=curl
;extension=ffi
;extension=ftp
extension=fileinfo
extension=gd
;extension=gettext
;extension=gmp
;extension=intl
;extension=imap
extension=mbstring
;extension=exif      ; Must be after mbstring as it depends on it
;extension=mysqli
;extension=oci8_12c  ; Use with Oracle Database 12c Instant Client
;extension=oci8_19  ; Use with Oracle Database 19 Instant Client
;extension=odbc
extension=openssl
;extension=pdo_firebird
extension=pdo_mysql
;extension=pdo_oci
;extension=pdo_odbc
extension=pdo_pgsql
extension=pdo_sqlite
;extension=pgsql
;extension=shmop

; xdebug 配置(详见后续 xdebug 安装和配置说明)
zend_extension = xdebug
xdebug.mode = debug
;xdebug.start_with_request = yes

phpinfo() 测试

php 解释器解压和正常配置后,可以在任意工作目录,新建一个phpinfo.php 并编辑:

<?php
   phpinfo();

在命令行执行 ‘php phpinfo.php’,终端会打印一下信息:

$ php phpinfo.php
phpinfo()
PHP Version => 8.2.8

System => Windows NT HD-IRON-PC 10.0 build 22621 (Windows 11) AMD64
Build Date => Jul  4 2023 15:48:56
Build System => Microsoft Windows Server 2019 Datacenter [10.0.17763]
Compiler => Visual C++ 2019
Architecture => x64
<略...>

在命令行执行 ‘php -S localhost:8000’,在浏览器地址栏输入 “http://localhost:8000/phpinfo.php”,终端会打印一下信息:

$ php -S localhost:8000
[Mon Aug 28 17:03:21 2023] PHP 8.2.8 Development Server (http://localhost:8000) started
[Mon Aug 28 17:04:06 2023] [::1]:58578 Accepted
[Mon Aug 28 17:04:06 2023] [::1]:58578 [404]: GET / - No such file or directory
[Mon Aug 28 17:04:06 2023] [::1]:58578 Closing
[Mon Aug 28 17:04:06 2023] [::1]:58579 Accepted
[Mon Aug 28 17:04:06 2023] [::1]:58580 Accepted
[Mon Aug 28 17:04:06 2023] [::1]:58579 [404]: GET /favicon.ico - No such file or directory
[Mon Aug 28 17:04:06 2023] [::1]:58579 Closing
[Mon Aug 28 17:04:12 2023] [::1]:58580 [200]: GET /phpinfo.php
[Mon Aug 28 17:04:12 2023] [::1]:58580 Closing
[Mon Aug 28 17:04:12 2023] [::1]:58597 Accepted

此时浏览器降显示如下截图:

windows 环境下 xdebug 安装和配置

在命令行执行 ‘php phpinfo.php > phpinfo.txt’ 或 ‘php -i > phpinfo.txt’, 此时会在当前目录下生成一个 ‘phpinfo.txt’ 文件,复制其内容后备用,进入xdbug 网站 https://xdebug.org/wizard, 粘贴 php 版本信息,点击下面的分析按钮,则会获取到对应 PHP 版本的 xdebug 插件,以及配置信息。

VScode PHP 调试

使用 VSCODE 打开 PHP 应用文件夹,点击左侧 DEBUG 按钮进入调试界面,点击创建 launch.json, 选择 php 环境模板,注意修改相关调试参数,其中调试侦听端口不能为0,常用调试端口例如 “localhost:8000” ,根据需要修改,启动调试后则可在 php 代码里实现断点调试和变量查看。

PHP Web 开发框架

ThinPHP: https://www.thinkphp.cn/
Laravel: https://laravel.com/
Laravel 中文网: http://laravel.p2hp.com/