PHP代码编译为OPCODE

简介

OPCODE是PHP编译后的二进制代码,生成的Opcode作为一种中间语言,可以帮助实现PHP源程序代码的不开源,当然,这种代码也很容易被反编译,不过对于一些简单的场景也是很足够了。
编译的基本思路是首先在php.ini中配置加载opcache扩展,并配置相关参数,然后执行一个PHP脚本遍历源代码目录,并进行编译,核心的函数是opcache_compile_file(),该函数会根据php.ini中的参数,编译并输出二进制代码。

准备工作

首先,配置PHP.INI文件中的opcache相关参数,以开启OPCACHE功能:

zend_extension=php_opcache.dll
[opcache]
; Determines if Zend OPCache is enabled
opcache.enable=1

; Determines if Zend OPCache is enabled for the CLI version of PHP
opcache.enable_cli=1

; The amount of memory for interned strings in Mbytes.
opcache.interned_strings_buffer=8

; The maximum number of keys (scripts) in the OPcache hash table.
; Only numbers between 200 and 100000 are allowed.
opcache.max_accelerated_files=8000

; When disabled, you must reset the OPcache manually or restart the
; webserver for changes to the filesystem to take effect.
opcache.validate_timestamps=0

; If disabled, all PHPDoc comments are dropped from the code to reduce the
; size of the optimized code.
opcache.save_comments=0

; Enables and sets the second level cache directory.
; It should improve performance when SHM memory is full, at server restart or
; SHM reset. The default "" disables file based caching.
opcache.file_cache=C:\MyApp\www\cache

; Enables or disables opcode caching in shared memory.
opcache.file_cache_only=0

编译

从网上得到一段编译的代码,自己根据实际情况修改了一下,代码如下:

<?php
/**
 * Created by PhpStorm.
 * User: Lancelot
 * Date: 2018-02-09
 * Time: 14:04
 */

$dir = $argv[1];
opcache_compile_files($dir);

function opcache_compile_files($dir) {
   $cacheMd5 = file_get_contents("cacheMd5.txt");
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) as $v) {
        if(!$v->isDir() && preg_match(‘%\.php$%‘, $v->getRealPath())) {
            $phpFile = $v->getRealPath();
            if (filesize($phpFile) > 2) {
                if (opcache_compile_file($phpFile)) {
                    $search = $dir;
               $append = str_replace(‘:‘, ‘‘, $dir);
                    $repl = ‘C:\BeyondScreen\www\cache\\‘ . $cacheMd5 . ‘\\‘ . $append;
                    $cachePath = str_replace($search, $repl, $phpFile) . ‘.bin‘;
                    if (file_exists($cachePath)) {
                        echo "{$phpFile}\n";
                        file_put_contents($phpFile, ‘‘); //清空原来的PHP脚本
                    }
                }
            }
        }
    }
}

上面代码的思路是遍历传入的源文件目录,对找到的PHP文件进行编译,然后检查输出路径中是否有已经编译成功的文件,如果有,则把源PHP文件内容清空,这样服务器就会直接调用编译后的代码,而不是重新编译了。

使用方法(假设上面代码的php文件名为opcache_compile_file.php),第一个参数的值为待编译的PHP源代码目录:

php opcache_compile_file.php "C:\BeyondScreen\www\byserver"

几个问题

在实现上面的PHP代码编译过程中,遇到了一些问题,如下:
1、 源目录中的文件没有全部编译;
我们的框架是Yii2,编译后发现框架的很多代码没有编译,没有时间去查找原因,只是在编译脚本中增加了一些逻辑,只对内容不为空的PHP文件进行编译,然后编译时执行两遍编译命令来确保全部PHP文件都被编译。
2、 部分PHP文件编译失败;
大多数问题是XXX类已经存在,所以编译失败,处理方案是编译脚本中检查编译结果,对于编译失败的PHP文件不清空。

原文地址:http://blog.51cto.com/lancelot/2083165

时间: 2024-08-06 15:42:19

PHP代码编译为OPCODE的相关文章

如何把iOS代码编译为Android应用

新闻 <iPhone 6/6 Plus中国销量曝光:单月销量650万>:据iSuppli Corp.中国研究总监王阳爆料,iPhone 6和iPhone 6 Plus在国内受欢迎的情况大大超过预期,苹果在中国的单月销量在11月超过了650万台,全年在中国的销量将超过4000万台. 教程 < Date parsing performance on iOS>:文章介绍了一个关于格式化时间的”黑科技“,作者使用 sqlite 替换 NSDateFormatter,提高了16倍的转换效率.

Linux - Unix环境高级编程(第三版) 代码编译

Unix环境高级编程(第三版) 代码编译 本文地址:http://blog.csdn.net/caroline_wendy 时间:2014.10.2 1. 下载代码:http://www.apuebook.com/code3e.html 2. 安装依赖库:sudo apt-get install libbsd-dev  3. 进入下载目录make 4. 复制头文件和动态链接库 sudo cp ./include/apue.h /usr/include/ sudo cp ./lib/libapue

Java代码编译和执行的整个过程

Java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码编译机制 类加载机制 类执行机制 Java源码编译机制 Java 源码编译由以下三个过程组成: 分析和输入到符号表 注解处理 语义分析和生成class文件 流程图如下所示: 最后生成的class文件由以下部分组成: 结构信息.包括class文件格式版本号及各部分的数量与大小的信息 元数据.对应于Ja

利用Roslyn把C#代码编译到内存中并进行执行

Tugberk Ugurlu在其博文<Compiling C# Code Into Memory and Executing It with Roslyn>中给大家介绍了一种使用.NET下一代编译器(或称编译服务)--Roslyn的小技巧.即把C#代码编译到内存中(而非保存到文件中),并执行这些代码. 简单说来,就是先安装Microsoft.CodeAnalysis.CSharp这个Nuget包,然后在代码中调用Roslyn的API,然后把代码编译输出到一个MemoryStream中,再从内存

Keil C减小代码编译量大小的方法

keil-C减小代码编译大小的方法整理 方法一:(通过优化代码减小) 1.1少做乘除运算,使用左/右移位来实现乘除 Eg ,普通:a = 0x80*4: 优化:a = 0x80<<2: 1.2在不影响运算条件下,使用短类型代替长类型 Eg ,普通: int a: 优化: char a: 1.3尽量使用无符号类型数据 Eg ,普通:char a = 56; 优化:unsigned char a = 56; 1.4回避使用浮点类型数据做乘除运算,这样代码量很大 Eg ,普通:float a = 5

用代码编译数字图形

1 121 12321 1234321 123454321 打印上述图形 #include <stdio.h>void main(){ int i,j; for (i=0;i<5;i++) { for (j=0;j<2*i+1;j++) { if(j<=i) { printf("%d",j+1); } else { printf("%d",2*i-j+1); } } printf("\n") ; } } 用代码编译数

如何提升代码编译的速度 iOS

前阵子有遇到代码编译速度慢的问题,特别是在swift和object-c混编的过程中问题很突显. 网上找到一篇蛮好的文章里面又一些解决方法 推荐一下 http://www.open-open.com/lib/view/open1475993635756.html 当然除了这篇推荐外,自己还做了一些理解. 代码编译速度慢.首先我们应该想到的是 编译速度慢是跟你的编译器有关系的. 一下列出几个方向供参考 1.swift 是类型安全的,所以我们在经常定义变量的时候由于使用方便会直接 var x = a这

记事本写c#代码编译并理解编译执行原理

1.在记事本里编写c#代码,将文件保存为ProgramTest.cs: namespace huangxiangTestDemo { class ProgramTest { static void Main() { System.Console.WriteLine("hello world"); System.Console.ReadKey(); } } } 2.在控制台编译,使用csc命令编译: 注意完整写法:csc.exe /out:ProgramTest.exe /t:exe /

JVM学习笔记(二)------Java代码编译和执行的整个过程【转】

转自:http://blog.csdn.net/cutesource/article/details/5904542 版权声明:本文为博主原创文章,未经博主允许不得转载. Java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码编译机制 类加载机制 类执行机制 Java源码编译机制 Java 源码编译由以下三个过程组成: 分析和输入到符号表 注解处理 语