PHP Censor 介绍与选型指南

PHP Censor 是 PHPCI 分支的自托管 PHP 持续集成服务器,本文基于 2026-10-28 官方源实查,解析其架构、52 个插件、适用边界,并与 Jenkins、Drone、Gitea Actions 做量化选型对比。

PHP CensorPHPCI持续集成DevOps2026/10/28

PHP Censor 介绍与选型指南

目标:在正式落地前,用一手资料回答「PHP Censor 是什么、由哪些部件构成、能做什么、是否还值得选」四个问题,并给出与 Jenkins、Drone、Gitea Actions 的量化对比。本文为认知与选型篇,全部信息来自官方仓库、官方文档与发布页的联网溯源,查询日期 2026-10-28,不含本地实测数据。

一、环境信息

本文是选型调研文档,不涉及软件安装,因此「环境信息」列出的是取证口径而非服务器配置:

  • 调研对象:php-censor/php-censor(PHP 编写的自托管持续集成服务器,PHPCI 分支)
  • 调研日期:2026-10-28
  • 取证渠道:GitHub 仓库页与 Releases 页、Packagist 包页、官方文档目录 docs/en(分支 release-2.1)、GitHub REST API
  • 版本口径:以 GitHub Releases 中标记为 prerelease=false 且非 draft 的最新条目为「最新稳定版」
  • 竞品口径:GitHub REST API /repos/{owner}/{repo} 与 /releases/latest,同一日期查询
取证项查询地址查询日期
仓库元数据(星数、分支、许可、最后推送)https://api.github.com/repos/php-censor/php-censor2026-10-28
最新稳定版发布说明https://github.com/php-censor/php-censor/releases2026-10-28
包版本与 PHP 约束https://packagist.org/packages/php-censor/php-censor2026-10-28
安装与配置文档https://github.com/php-censor/php-censor/tree/release-2.1/docs/en2026-10-28

说明:本文所有数字都可按上表地址复现。选型对比章节中的星数与版本号随时间变化,引用时务必带上查询日期,否则半年后即失真。

二、软件概述

2.1 身份与定位

PHP Censor 是一个面向 PHP 项目的自托管持续集成服务器,仓库自述为 「an open source self-hosted continuous integration server for PHP projects」,并且是 PHPCI 项目的分支(fork)。它把「拉代码 → 装依赖 → 跑静态检查与单元测试 → 部署 → 通知」这条流水线固化成一个由 Web 界面、命令行和后台队列 Worker 组成的单体应用。

关键身份信息(2026-10-28 实查):

属性取值来源
仓库php-censor/php-censorGitHub
许可证BSD-2-ClauseGitHub /repos 接口 license.spdx_id
星标 / Fork686 / 144GitHub /repos 接口
未关闭 Issue23GitHub /repos 接口 open_issues_count
最近一次推送2026-05-31T07:19:45ZGitHub /repos 接口 pushed_at
仓库是否归档否(archived=false)GitHub /repos 接口
官方站点http://php-censor.info(301 跳转)仓库 homepage 字段 + 实测 HTTP 响应
插件数量52 个(src/Plugin 下 52 个插件类)源码树
技术栈PHP 7.4+、Symfony 5.4 组件、Phinx 迁移、Beanstalkdcomposer.json

2.2 版本谱系与维护现状

官方 README 用一张表把各版本的支持状态写得很清楚,这是判断「还能不能用」的第一手依据:

版本线最新版分支官方状态最低 PHP
1.0(Morty Smith)1.0.16release-1.0旧版本(UNSUPPORTED)>=5.6, <8.0
1.1(Birdperson)1.1.6release-1.1旧版本(UNSUPPORTED)>=5.6, <8.0
1.2(Summer Smith)1.2.4release-1.2旧版本(UNSUPPORTED)>=5.6, <8.0
1.3(Jerry Smith)1.3.7release-1.3旧版本(UNSUPPORTED)>=5.6, <8.0
2.0(Rick Sanchez)2.0.14release-2.0上一个稳定线>=7.4
2.1(Mr. Meeseeks)2.1.6release-2.1当前稳定版>=7.4
2.2WIPmaster开发中>=7.4

「当前稳定版」为 2.1.6,发布页标记日期 2025-03-15,随版本发布的修复说明只包含安全修复项(remember me key 相关漏洞、CVE-2024-50345 开放重定向);同一天还发布了 2.0.14,修复 CVE-2024-51736。这说明 2.1 线目前处于安全维护节奏,而非功能迭代节奏。

⚠️ 注意:仓库并未归档,但 2.1.6 之后近一年半没有新的稳定版发布(截至 2026-10-28),master 上仍在推进 2.2 与 3.0 预发布分支。把 PHP Censor 放进生产前,应把「版本冻结、只跟随安全修复」写进运维约定,而不是期待持续的新特性。

三、核心架构

3.1 进程与组件构成

PHP Censor 是单体应用,但运行时有四种角色,缺一不可:

       浏览器 / Git 平台 Webhook
                │
                ▼
   ┌────────────────────────────┐
   │  Nginx + PHP-FPM(Web 层)  │  public/index.php
   │  Symfony 5.4 HttpFoundation│
   └────────────┬───────────────┘
                │ 写入构建记录 + 投递任务
                ▼
   ┌────────────────────────────┐
   │  Beanstalkd 队列(11300)   │
   └────────────┬───────────────┘
                │ 取出任务
                ▼
   ┌────────────────────────────┐
   │  Worker(php-censor:worker)│  常驻进程,可多实例
   │  BuildFactory → Build 模型  │
   └────────────┬───────────────┘
                │ 逐阶段调用插件
                ▼
   ┌────────────────────────────┐
   │  Plugin(52 个)→ 构建产物   │
   └────────────┬───────────────┘
                │ 状态/日志/覆盖率入库
                ▼
   ┌────────────────────────────┐
   │  MySQL / MariaDB / PgSQL    │
   │  projects / builds / users  │
   └────────────────────────────┘

四个角色的职责边界:

  1. Web 层:项目增删改、构建详情展示、用户与权限、Webhook 接收。入口固定为 public/index.php,由 Nginx 把所有不存在的路径重写到 index.php。
  2. Console 层:bin/console 提供安装、建构建、重建队列、清理旧构建、Worker 等命令,是自动化与运维的入口。
  3. Worker:唯一真正执行构建的进程。它从 Beanstalkd 队列取任务,按项目配置逐阶段调用插件,把日志与状态写回数据库。
  4. 存储层:MySQL/MariaDB 或 PostgreSQL 存元数据;构建的工作副本落在应用目录的 runtime/builds/ 下。

3.2 构建执行链路

一次构建的完整链路如下(模块名均来自源码结构):

  1. Webhook 或 php-censor:create-build 触发 → 在 builds 表插入一条记录,状态为「等待」。
  2. 任务被投递到 Beanstalkd 的指定 tube(默认 php-censor)。
  3. Worker 取到任务后,BuildFactory 按项目类型(local/git/github/gitlab/bitbucket/gogs/hg/svn)实例化对应的 Build 子类。
  4. Build 子类负责把仓库内容取到 runtime/builds/{projectId}/{buildId}_{hash} 工作目录。
  5. 依次执行 setup → test → deploy → complete 四个阶段;成功/失败后再进入 success/failure/fixed/broken 收尾阶段。
  6. 每个插件的标准输出被写入 builds.log,插件结束记录 PLUGIN: SUCCESS 或 PLUGIN: FAIL。
  7. 全部阶段结束后写回构建状态、错误数、覆盖率,并删除工作副本。

技术拓展:PHP Censor 的异步执行依赖任务队列中间件。同类可选方案对比如下——

方案协议与模型特点适用场景
Beanstalkd自定义文本协议,tube + job,内存队列极轻量、无持久化要求、部署简单单机 CI、任务量中等
Redis List/Stream内存数据结构,需自行实现重试与确认生态成熟、可复用现有 Redis已有 Redis 基础设施
RabbitMQAMQP,交换机/队列/确认/死信可靠投递、路由灵活、运维成本高多消费者、需保证不丢任务
关系库轮询表数据库表 + 定时扫描无额外组件、延迟高、易锁表任务极少、追求零新增依赖

PHP Censor 2.1.6 只实现了 Beanstalkd 一种队列适配(配置项 php-censor.queue),因此本文所述方案实际采用 Beanstalkd,这也是官方安装文档要求先装 beanstalkd 的原因。

3.3 配置的两层结构

PHP Censor 的配置分两层,理解这一点是读懂后续两篇文档的前提:

层级文件作用范围谁修改
应用级app/config.yml数据库、队列、URL、语言、邮件、安全、构建保留策略运维
项目级仓库根目录 .php-censor.yml 或 Web 界面「项目配置」该项目跑哪些插件、哪些阶段、分支覆盖项目开发者

项目级配置有三条来源,优先级从高到低为:Web 界面配置 > 仓库内 .php-censor.yml > 零配置默认模板。若在项目编辑页取消勾选「用数据库配置替换文件配置」,则 Web 配置与文件配置合并,Web 侧优先——这一机制正是官方推荐的「公开仓库放通用配置、口令放 Web 界面」的用法。

四、功能特性

4.1 插件体系

src/Plugin 目录下共 52 个插件类,官方文档 docs/en/plugins 下同样有 52 篇说明,按用途可分为五组:

分组代表插件作用
依赖与构建composer、phing、grunt、gulp、phar、package_build安装依赖、执行构建任务、打包
测试php_unit、codeception、behat、atoum跑单元测试与行为测试
静态检查lint、php_parallel_lint、php_code_sniffer、php_mess_detector、php_cpd、php_loc、php_docblock_checker、pdepend、phan、technical_debt、security_checker语法、规范、重复度、复杂度、安全
数据库mysql、pgsql、sqlite为测试准备独立库、跑初始化 SQL
部署与通知deployer、deployer_org、mage、mage3、shell、copy_build、clean_build、email_notify、slack_notify、telegram_notify、xmpp_notify、irc_notify、campfire_notify、flowdock_notify、bitbucket_notify、hipchat_notify部署产物、清理环境、推送结果

插件声明方式统一为「步骤名 → plugin: 字段」,步骤名可自定义,例如 composer_step、lint_step。同一插件可以配多个步骤,用于对不同目录或不同参数分别执行。

4.2 构建阶段

阶段触发时机典型用途
setup构建开始装 Composer 依赖、建测试库、设环境变量
testsetup 成功后单测、静态检查、覆盖率
deploytest 成功后发布产物、触发下游部署
complete无论成败都会执行清理测试库、发送通知
success / failure按最终状态分状态通知
fixed / broken状态发生翻转时只发「修复了」或「挂了」的告警,抑制重复噪音

4.3 分支与环境

  • branch-<分支名> 与 branch-regex:<正则> 两套指令可对特定分支覆盖或追加配置,配合 run-option(replace/before/after)控制与默认配置的关系。
  • 项目可定义「环境(Environment)」:一个环境由默认分支 + 若干特性分支组成,向默认分支推送会为每个环境各触发一次构建,适合「预发/灰度/正式」多环境并行验证。
  • 配置内可用 %ENVIRONMENT% 变量把环境名拼进库名或部署目标。

4.4 其他能力

  • 零配置构建:不写任何配置文件,也会默认执行 Composer、PHPLoc、PHPCpd、PHPCodeSniffer、PHPMessDetector、PHPDocblockChecker、PHPParallelLint、PHPUnit、Codeception 等一组插件。
  • 鉴权:内置账号体系,可接 LDAP;支持关闭鉴权并绑定默认用户(security.disable_auth)。
  • 代码托管对接:GitHub、GitLab、Bitbucket(含 Server 与 Hg 变体)、Gogs、通用 Git、Mercurial、Subversion,以及本地目录。
  • 公开状态页:项目可开启公开构建状态,用于 README 徽章。
  • 构建保留策略:build.keep_builds 与 build.remove_builds 控制自动清理旧构建。

五、快速开始(官方最小可用示例)

本章内容直接引自官方文档(docs/en/installing.md、docs/en/workers/worker.md,分支 release-2.1,查询日期 2026-10-28),用于说明「最短路径长什么样」,文中命令未在本文档语境下重新执行;完整可复现步骤、逐条实测回显与排障见 《PHP Censor 2.1.6 Ubuntu 22.04 安装指南》。

5.1 官方给出的四步主线

步骤命令说明
1. 取代码composer create-project php-censor/php-censor php-censor.local --keep-vcs在 /var/www 下执行,Composer 自动装依赖
2. 建库手动创建空库支持 MySQL/MariaDB 或 PostgreSQL
3. 装队列apt-get install beanstalkd官方标注为「可选,仅在用 Worker 时」
4. 初始化./bin/console php-censor:install交互式;也可用参数全自动

官方给出的非交互式形态(原文照录,参数值仅作示例):

cd ./php-censor.local
./bin/console php-censor:install \
    --url='http://php-censor.local' \
    --db-type=pgsql \
    --db-host=localhost \
    --db-pgsql-sslmode=prefer \
    --db-name=php-censor \
    --db-user=php-censor \
    --db-password=php-censor \
    --db-port=default \
    --admin-name=admin \
    --admin-password=admin \
    --admin-email='admin@php-censor.local' \
    --queue-host=localhost \
    --queue-port=11300 \
    --queue-name=php-censor

⚠️ 注意:--db-port=default 是官方约定的特殊值,表示「按数据库类型取默认端口」——MySQL 取 3306、PostgreSQL 取 5432,不是字面意义上的 0 端口。原文档在该行末尾还带了一句行内注释,粘贴到 shell 时会把注释后的换行吃掉,建议手工删掉注释再执行。

5.2 最小项目配置

官方推荐在仓库根目录放 .php-censor.yml,最小可用形态如下(内容取自 README 示例):

setup:
  composer:
    action:    "install"
    directory: "."

test:
  php_unit:
    config: "phpunit.xml"
  php_mess_detector:
    allow_failures: true

这份配置表达三件事:setup 阶段按 composer install 装依赖;test 阶段按 phpunit.xml 跑单测;PHPMessDetector 的结果不计入构建失败(allow_failures: true)。

5.3 还需要补的两块

官方文档在安装章节末尾明确列出两项后续动作,缺了它们构建不会自动跑起来:

  • 为 Web 服务器添加虚拟主机,站点根目录指向 public,并把不存在的请求重写到 index.php;
  • 按 docs/en/workers/worker.md 配置 Worker 的 systemd 单元,否则任务只会堆在 Beanstalkd 里。

六、适用场景与限制

6.1 适用场景

场景为什么合适
中小型 PHP 团队(10~50 人)自建 CI单机可跑,无外部 SaaS 依赖,数据不出内网
内网/离线环境的 PHP 项目只需 PHP + 数据库 + Beanstalkd + Web 服务器,全部可离线部署
以 PHPUnit + 静态检查为主的流水线52 个插件中大半直接服务于 PHP 质量门禁
需要「零配置即可跑」的存量项目默认模板会自动识别 phpunit.xml、composer.json 等约定文件
需要把构建结果留在自有数据库里审计构建日志、错误数、覆盖率全部落在自有库表

6.2 限制与风险

  1. 只面向 PHP:插件全部围绕 PHP 工具链,非 PHP 项目没有可用插件。
  2. 强依赖 Beanstalkd:队列适配只有一种,若团队规范禁用该中间件,则无法替换(除非改源码)。
  3. 多语言/多运行时支持弱:PHP 版本切换需要在服务器侧准备对应二进制,并由 priority_path/binary_path 指过去。
  4. 发布节奏慢:2.1.6 发布于 2025-03-15,截至查询日无更新稳定版;安全修复依赖维护者单点投入。
  5. 2.x 与 3.0 存在断层:3.0 预发布线要求 PHP >= 8.1,升级时需评估配置与插件兼容性。
  6. 前端较朴素:界面为服务端渲染,实时性靠 realtime_ui 轮询,不提供现代 SPA 体验。

⚠️ 注意:判断「是否已停止维护」不能只看最后一次提交时间。该仓库 2026-05-31 仍有推送、未归档,但稳定版发布停在 2025-03;更准确的表述是「仍在维护、节奏放缓、以安全修复为主」。

七、同类选型对比

7.1 量化对比

对比维度选取「能否长期用」最相关的五项:社区规模、版本节奏、许可、配置方式、运行依赖。数据均在 2026-10-28 通过 GitHub REST API 实查。

维度PHP CensorJenkinsDroneGitea Actions
仓库php-censor/php-censorjenkinsci/jenkinsharness/dronego-gitea/gitea(内置 Actions)
星标68626,69938,73458,732
Fork1449,8133,4477,313
最新版本2.1.6jenkins-2.587v2.28.2v28.2.0
最新版发布时间2025-03-152026-10-202026-04-202026-10-18
许可证BSD-2-ClauseMITApache-2.0MIT
流水线定义.php-censor.yml(YAML)Jenkinsfile(Groovy 声明式/脚本式).drone.yml(YAML).gitea/workflows/*.yml(YAML,兼容 GitHub Actions 语法)
运行依赖PHP + 数据库 + Beanstalkd + Web 服务器JVM + 插件生态独立 Runner(需单独进程/主机)Gitea 本体 + Actions Runner
插件/扩展模型52 个 PHP 插件类1800+ 插件(更新中心)官方 pipeline step 在独立执行环境中运行复用 GitHub Actions 生态
构建隔离进程级,共享主机环境进程级或代理节点每次构建独立执行环境Runner 上按 job 隔离
多语言支持仅 PHP全语言全语言全语言
学习成本低(YAML 直白)高(Groovy + 插件治理)中中(熟悉 GitHub Actions 则低)

关键差异解读:

  • 生态量级差两个数量级:686 星对 26,699 / 38,734 / 58,732 星,意味着遇到疑难问题时可获得的外部经验差距明显;PHP Censor 的问题基本只能靠读源码解决。
  • 版本节奏差一个量级:Jenkins 与 Gitea 在查询日前 10 天内都有新版本,Drone 约半年一版,PHP Censor 已 19 个月无稳定版。
  • 运行依赖决定运维成本:PHP Censor 需要四类进程协同;Jenkins 是单一 JVM 主进程加代理;Gitea Actions 则依附于已部署的 Gitea。若团队已有 Gitea,后者的边际成本最低。
  • 构建隔离是硬差距:PHP Censor 的插件直接在服务器进程里跑,构建间的环境污染只能靠 clean_build/wipe 类插件弥补;这一点在多语言、多版本并存的团队里会持续制造「本地能跑、CI 不能跑」的偏差。

7.2 选型建议

如果你的情况是…建议
团队只写 PHP,想要最轻的自建 CI,机器资源紧张选 PHP Censor,单机 2 核 4GB 即可
需要跑多语言、多 PHP 版本矩阵、要求构建环境隔离选 Jenkins(代理节点)或 Gitea Actions(Runner)
已在使用 Gitea 做代码托管优先 Gitea Actions,避免再维护一套 CI
已有 Kubernetes 或需要声明式流水线编排选 Drone 或 Gitea Actions,PHP Censor 无此能力
内网离线、审批要求「组件数量最少」PHP Censor(PHP + 数据库 + Beanstalkd)与 Jenkins(JVM 单体)二选一,取团队更熟的栈
需要长期商业支持或合规审计报告四者均无官方商业支持,需自建;Jenkins 的第三方支持生态最完整

说明:本文的对比结论基于「功能面 + 维护节奏 + 运维依赖」三项,不涉及性能压测。若需要吞吐量数据,应在自有环境按固定并发做基准测试,而不是引用他人结论。

八、常见问题

Q1:PHP Censor 已经停止维护了吗?

没有归档,archived=false,最近推送为 2026-05-31,master 上仍有 2.2/3.0 的开发活动。但最新稳定版 2.1.6 发布于 2025-03-15,此后只有安全修复性质的同版本更新(2.0.14 与 2.1.6 同日发布)。准确表述是「维护中,节奏放缓,以安全修复为主」。

Q2:2.1.6 修了哪些安全问题?

发布说明列出两项:一是认证模块 remember me key 的安全问题;二是 CVE-2024-50345(浏览器净化 URL 导致的开放重定向)。同日的 2.0.14 修复 CVE-2024-51736(Windows 下 Process 类的命令执行劫持)。使用 2.0 线的部署应同步升级到 2.0.14 及以上。

Q3:能在 Windows 上跑吗?

不能。官方系统要求首条即写明「Unix-like OS(Windows isn't supported)」。

Q4:必须装 Beanstalkd 吗?

若使用 Worker 异步执行构建,必须。官方把 Beanstalkd 列为系统要求之一,队列配置项只有 host/port/name/lifetime 四个,没有其他队列后端的适配层。

Q5:PHP 8.4 能用吗?

composer.json 的约束是 php: >=7.4.0,没有上限,但 extra.platform.php 固定为 7.4.*,意味着依赖解析按 7.4 的兼容矩阵进行。8.x 的实际可用性取决于所装 Symfony 5.4 小版本与扩展,建议在目标 PHP 版本上先跑一次完整构建再上线。

Q6:和 PHPCI 有什么区别?

PHP Censor 是 PHPCI 的分支,composer.json 的 description 直接写明 "(PHPCI fork)",作者列表同时保留 PHPCI 原作者 Dan Cryer。PHPCI 上游已多年无更新,PHP Censor 在其基础上迁移到 Symfony 5.4、补充 PHP 8 支持并持续做安全修复。

九、参考链接