当前位置: 首页 > news >正文

PHP利用Opcache实现保护源码的示例详解

  • 不用 IonCube(或类似的)。不知道这是啥的话,就是加密 PHP 代码但还能运行的工具。问题是太贵了。
  • 性能要好,PHP 原生支持。

后来想到,PHP 有个"opcache"功能,能把源码编译成操作码(机器语言)在 Zend VM 上跑,跟 Java 差不多 😃 厉害的是,这样既保护了代码,又提升了性能!

开始干活。要让这套方案跑起来,得把代码打包成镜像(就是个只读的存储,跟系统其他部分隔离开),因为 opcache 是全局生效的,不管哪个 PHP 项目。最好的工具就是 Docker。(Docker 比虚拟机轻量多了,分发部署都很方便)。

这次用 Laravel 做例子。为啥选它?因为组件多,依赖库也多,能遇到各种坑,学到的东西也多。

一般来说,我们的核心代码都在/app目录里,这部分需要保护。其他目录像/vendor都是开源库,不用管。

具体步骤

第一步,在项目根目录建个warm-opcache.php文件。这玩意儿会调用opcache_compile_file()手动让 PHP 编译代码。

1

2

3

4

5

6

7

8

9

10

<?php

$directory=newRecursiveDirectoryIterator('/var/www/app'); # 我们用 /var/www

$iterator=newRecursiveIteratorIterator($directory);

foreach($iteratoras$file) {

if(pathinfo($file, PATHINFO_EXTENSION) ==='php') {

echo"编译中: {$file}\n";

opcache_compile_file($file);

}

}

第二步,建个empty-preserve-time.sh脚本(记得chmod +x给执行权限)。这个脚本会把 PHP 文件内容清空,但保留时间戳。为啥要保留时间戳?因为文件修改时间一变,opcache 就会重新加载。

1

2

3

4

5

6

7

#!/bin/bash

forfilein$(find./app-typef -name"*.php");do

timestamp=$(stat -c %Y"$file")# 获取修改时间(从纪元开始的秒数)

: >"$file"# 清空文件

touch-d"@$timestamp""$file"# 恢复原始时间戳

done

第三步,把zz-opcache.ini配置文件放到/usr/local/etc/php/conf.d目录(或者你系统的 conf.d 在哪就放哪)。(记得先装好 PHP 的 opcache 扩展)

1

2

3

4

5

6

opcache.enable=1

opcache.enable_cli=1

opcache.validate_timestamps=1

opcache.revalidate_freq=10

opcache.file_cache=/var/www/.opcache

opcache.file_cache_only=1

重要:先把代码 commit 或者备份!下面的操作会删除文件内容!

接下来就是见证奇迹的时刻了。先跑php warm-opcache.php,再跑empty-preserve-time.sh,文件内容会被清空,但/app目录结构还在,Laravel 项目照样能跑。不信你试试!

这套方法对任何 PHP 项目都管用,不管你用 PSR-4 还是简单的require()。Laravel 用的是 PSR-4。

不错,概念验证成功。下一步就是打包,要能分发到客户的服务器上。(就像 Go 能编译成 .exe 一样)

直接上 Dockerfile。(这个 Dockerfile 没做层优化,主要是为了好理解)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

FROM php:8.3-fpm-alpine # 根据需要修改

# 添加更多 pecl install 或 docker-php-ext-install

# 来安装项目需要的扩展

# 启用 opcache

RUNdocker-php-ext-install opcache

WORKDIR/var/www

RUNmkdir -p /var/www/.opcache

# 复制源码

COPYapp ./app

COPYartisan ./artisan

COPYbootstrap ./bootstrap

COPYdatabase ./database

COPYconfig ./config

COPYpublic ./public

COPYresources ./resources

COPYroutes ./routes

COPYstorage ./storage

COPYcomposer.* .

# 安装 ini 文件

COPYzz-opcache.ini /usr/local/etc/php/conf.d

# Laravel 的 composer install 需要 .env

# 我们复制一个假的 .env

COPY.env.example .env

# 安装 PHP 依赖(不要把这行移到上面)

RUNcomposer install --no-dev --optimize-autoloader

# 编译并删除 /app 中的源码

RUNphp warm-opcache.php

RUN./empty-preserve-time.sh

# 恭喜!你的代码已经被清除了!

# 如果不信,你可以 `ls` 你的 /app 目录并 `cat` 它

# 如果需要,你可以创建一个 ENTRYPOINT 脚本,也可以执行

# ./artisan queue:work, 或 ./artisan schedule:work

CMD["./artisan serve"]

现在,你可以docker builddocker push到你的注册服务器,然后从客户的本地服务器pull,而不用裸露地交付代码!当你有更新时,简单的docker pull就能节省很多时间!

可能有人会问,我们能删除/app目录而不是留空吗?不行。因为"opcache"会检查文件是否存在。

额外收获

上面的 Dockerfile 不安全。为什么?因为 Docker 在每个阶段都使用层,意味着当你COPY app ./app时,它实际上复制了你未保护的代码,并创建了一个层。Docker 专家可以轻松解开这些层,获取你的原始代码。

解决方案是使用多阶段构建。这是修订后的 Dockerfile。注意我们在第 1 行添加了as build

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

FROM php:8.3-fpm-alpine as build # 根据需要修改

# 添加更多 pecl install 或 docker-php-ext-install

# 来安装项目需要的扩展

# 启用 opcache

RUNdocker-php-ext-install opcache

WORKDIR/var/www

RUNmkdir -p /var/www/.opcache

# 复制源码

COPYapp ./app

COPYartisan ./artisan

COPYbootstrap ./bootstrap

COPYdatabase ./database

COPYconfig ./config

COPYpublic ./public

COPYresources ./resources

COPYroutes ./routes

COPYstorage ./storage

COPYcomposer.* .

# 安装 ini 文件

COPYzz-opcache.ini /usr/local/etc/php/conf.d

# Laravel 的 composer install 需要 .env

# 我们复制一个假的 .env

COPY.env.example .env

# 安装 PHP 依赖(不要把这行移到上面)

RUNcomposer install --no-dev --optimize-autoloader

# 编译并删除 /app 中的源码

RUNphp warm-opcache.php

RUN./empty-preserve-time.sh

# 恭喜!你的代码已经被清除了!

# 如果不信,你可以 `ls` 你的 /app 目录并 `cat` 它

# ======== 这里是多阶段层构建 ===========

FROM php:8.3-fpm-alpine # 根据需要修改

WORKDIR/var/www

# (重复上面完全相同的步骤)

# 添加更多 pecl install 或 docker-php-ext-install

# 来安装项目需要的扩展

# 启用 opcache

RUNdocker-php-ext-install opcache

# 安装 ini 文件

COPYzz-opcache.ini /usr/local/etc/php/conf.d

# 从 `build` 复制清空的文件和 opcache 代码到这里

COPY--from=build /var/www .

# 如果需要,你可以创建一个 ENTRYPOINT 脚本,也可以执行

# ./artisan queue:work, 或 ./artisan schedule:work

CMD["./artisan serve"]

到此这篇关于PHP利用Opcache实现保护源码的示例详解的文章就介绍到这了,

http://www.jsqmd.com/news/584511/

相关文章:

  • DeepSeek LintCode 3706 · 满足条件的数对的数量 public long countValidPairs(int[] nums1, int[] nums2, int dif
  • 深夜调车的时候突然发现,Apollo的泊车轨迹优化藏着不少“骚操作“。咱们今天不聊虚的,直接扒开代码看三个核心模块怎么打架...哦不,怎么配合的
  • 甜菜捡拾装卸机的设计【开题报告+任务书+毕业论文+答辩ppt+CAD图纸+solidworks三维】
  • OpenClaw技能开发:为Qwen2.5-VL-7B添加PDF图文提取能力
  • Phi-4-mini-reasoning商业落地:教育场景中自动解题与逻辑推演实战案例
  • 圣女司幼幽-造相Z-Turbo应用场景:国漫IP角色图批量生成与同人创作实战
  • OpenClaw语音交互:Qwen3-14b_int4_awq对接Whisper实现语音指令控制
  • PHP解决跨域请求问题的两种实用方法详解
  • 别只盯着 Claw 了,这波“真香”技能才是真的生产力神器!
  • InfluxDB(一)——一个高效处理数据的时序数据库
  • @pixi/react Hook系统深度解析:useTick、useApplication、useExtend的完整用法
  • Qwen3.5-9B-AWQ-4bit部署教程:双卡RTX 4090 D显存优化与AWQ量化优势解析
  • DeepSeek LeetCode 1125.最小的必要团队 public int[] smallestSufficientTeam(String[] req_skills, List<List
  • OpenClaw省钱全攻略,掌握这5招,每月少花几百块冤枉钱
  • PhotoGIMP完全指南:从Photoshop到开源图像编辑的无缝迁移
  • PHP中HTML标签过滤的5种有效方法
  • 低成本运行方案:OpenClaw+千问3.5-27B量化模型调优
  • GLM-OCR GPU算力优化实践:vLLM推理加速+令牌下采样,吞吐提升2.3倍
  • 使用PHP Imagick扩展将PDF转换为图片功能的完整方案
  • 光伏混合储能直流微电网simulink模型 1.直流微电网由锂电池,超级电容,光伏和直流负载组成 2
  • linux编译qt项目
  • 2026年评价高的滑台直线模组用户口碑推荐厂家 - 品牌宣传支持者
  • Nature Microbiology|质粒驱动的抗菌素耐药性进化:插入序列介导的基因失活新机制
  • 使用PHP和LibreOffice实现高效Word转PDF的完整方案
  • lingbot-depth-pretrain-vitl-14多场景落地:AR实时遮挡、3D重建、工业检测一文详解
  • 中文版Charles抓包工具,详细安装教程(附安装包)
  • YOLOv8n-face人脸检测架构:6MB模型实现92%精度与25ms延迟的企业级方案
  • 阶跃星辰(Step):前微软小冰之父的 AI 豪赌
  • 美团LongCat-AudioDiT:革新波形潜空间的TTS模型
  • Qwen3.5-9B快速上手:3步启动WebUI(supervisorctl restart)超详细步骤