在PHP的生命周期中,分为 词法分析-》语法分析-》编译PHP脚本为opcode-》Zend Engine
在上述执行过程中,经常被人提起的解释型语言性能问题也就是因为每次执行脚本,上述过程都会重复执行。因此,也就出现了APC, xcache, eAccelerator等缓存,不过现在官方主推的是opcache
一、安装VLD扩展
1、下载
地址:http://pecl.php.net/package/vld
wget http://pecl.php.net/get/vld-0.13.0.tgz
2、编译安装
cd /usr/local/src/ wget http://pecl.php.net/get/vld-0.13.0.tgz tar -zxf vld-0.13.0.tgz cd vld-0.13.0 phpize && ./configure --with-php-config=php-config --enable-vld make && make install echo extension=vld.so >> /etc/php.d/vld.ini service php-fpm reload php-config、phpize要加入环境变量
3、opcode的结构
vim Zend/zend_compile.h
typedef struct _zend_op_array zend_op_array; typedef struct _zend_op zend_op;
struct _zend_op { opcode_handler_t handler; znode_op op1; znode_op op2; znode_op result; ulong extended_value; uint lineno; zend_uchar opcode; zend_uchar op1_type; zend_uchar op2_type; zend_uchar result_type; };
struct _zend_op_array { /* Common elements */ zend_uchar type; const char *function_name; zend_class_entry *scope; zend_uint fn_flags; union _zend_function *prototype; zend_uint num_args; zend_uint required_num_args; zend_arg_info *arg_info; /* END of common elements */ zend_uint *refcount; zend_op *opcodes; zend_uint last; zend_compiled_variable *vars; int last_var; zend_uint T; zend_brk_cont_element *brk_cont_array; int last_brk_cont; zend_try_catch_element *try_catch_array; int last_try_catch; /* static variables support */ HashTable *static_variables; zend_uint this_var; const char *filename; zend_uint line_start; zend_uint line_end; const char *doc_comment; zend_uint doc_comment_len; zend_uint early_binding; /* the linked list of delayed declarations */ zend_literal *literals; int last_literal; void **run_time_cache; int last_cache_slot; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; };
4、opcode的使用
STD_PHP_INI_ENTRY("vld.active", "0", PHP_INI_SYSTEM, OnUpdateBool, active, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.skip_prepend", "0", PHP_INI_SYSTEM, OnUpdateBool, skip_prepend, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.skip_append", "0", PHP_INI_SYSTEM, OnUpdateBool, skip_append, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.execute", "1", PHP_INI_SYSTEM, OnUpdateBool, execute, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.verbosity", "1", PHP_INI_SYSTEM, OnUpdateBool, verbosity, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.format", "0", PHP_INI_SYSTEM, OnUpdateBool, format, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.col_sep", "\t", PHP_INI_SYSTEM, OnUpdateString, col_sep, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.save_dir", "/tmp", PHP_INI_SYSTEM, OnUpdateString, save_dir, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.save_paths", "0", PHP_INI_SYSTEM, OnUpdateBool, save_paths, zend_vld_globals, vld_globals) STD_PHP_INI_ENTRY("vld.dump_paths", "1", PHP_INI_SYSTEM, OnUpdateBool, dump_paths, zend_vld_globals, vld_globals)
这些是vld的系统配置
默认值
static void vld_init_globals(zend_vld_globals *vld_globals) { vld_globals->active = 0; vld_globals->skip_prepend = 0; vld_globals->skip_append = 0; vld_globals->execute = 1; vld_globals->format = 0; vld_globals->col_sep = "\t"; vld_globals->path_dump_file = NULL; vld_globals->dump_paths = 1; vld_globals->save_paths = 0; vld_globals->verbosity = 1; }
[root@localhost code]# php -dvld.active test.php Finding entry points Branch analysis from position: 0 Jump found. Position 1 = -2 filename: /data/code/test.php function name: (null) number of ops: 5 compiled vars: none line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 2 0 E > SEND_VAL 'dbname' 1 DO_FCALL 1 $0 'config' 2 SEND_VAR_NO_REF 6 $0 3 DO_FCALL 1 'var_dump' 3 4 > RETURN 1 branch: # 0; line: 2- 3; sop: 0; eop: 4; out1: -2 path #1: 0,
更多指令参见:http://php.net/manual/en/internals2.opcodes.list.php,同时列出了每条指令的案例