邢栋博客

邢栋博客,Action博客,记录工作和生活中的点点滴滴

php安装vld扩展查看编译opcode

php安装vld扩展查看编译opcode

wget http://pecl.php.net/get/vld-0.14.0.tgz

tar -zxvf vld-0.14.0.tgz 

/usr/local/php/bin/phpize 

./configure --with-php-config=/usr/local/php/bin/php-config --enable-vld

make && make install 

vim /usr/local/php/etc/php.ini ,在文件最后面加入 extension=vld.so

service php-fpm restart //重启php-fpm


例子 

vim array.php
<?php
        $tmp = array('a'=>'a','b'=>'b','c'=>'c');
        $a = $tmp['a'];
        $b = $tmp[b];
        $c = $tmp["c"];


然后执行 
php -dvld.active=1 ./array.php    //如果加入 -dvld.execute=0(默认是1),则文件只输出opcode而不执行

返回结果如下
Finding entry points
Branch analysis from position: 0
Jump found. (Code = 62) Position 1 = -2
filename:       /data/www/study/array.php
function name:  (null)
number of ops:  9
compiled vars:  !0 = $tmp, !1 = $a, !2 = $b, !3 = $c
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   ASSIGN                                                   !0, <array>
   3     1        FETCH_DIM_R                                      $5      !0, 'a'
         2        ASSIGN                                                   !1, $5
   4     3        FETCH_CONSTANT                                   ~7      'b'
         4        FETCH_DIM_R                                      $8      !0, ~7
         5        ASSIGN                                                   !2, $8
   5     6        FETCH_DIM_R                                      $10     !0, 'c'
         7        ASSIGN                                                   !3, $10
   6     8      > RETURN                                                   1

branch: #  0; line:     2-    6; sop:     0; eop:     8; out1:  -2
path #1: 0, 
PHP Notice:  Use of undefined constant b - assumed 'b' in /data/www/study/array.php on line 4	

可以看到$tmp[b] 在编译成opcode的时候就比其他两个多一步



php正则相关知识点笔记

正则 环视(零宽断言)

环视不匹配任何字符,只匹配文本中的特定位置。类似于\b,^,$那样。环视不会占用字符。

环视分为顺序和逆序两种。

顺序
(?=exp)位置的后面能匹配exp。例如(?=\d)当前位置右边是数字
(?!exp)位置的后面不能匹配exp。例如(?!\d)当前位置右边不是数字

逆序
(?<=exp)位置的前面能匹配exp。例如(?<=\d)当前位置左边是数字
(?<!exp)位置的前面不能匹配exp。例如(?<!\d)当前位置左边不是数字


(?=jeffrey)jeff 等价于  jeff(?rey)

例子
<?php
$string = '5345678986';
$pattern = '/(?!=\d)(?=(\d{3})+$)/';
$replacement  = ',';
echo  preg_replace($pattern, $replacement, $string);//5,345,678,986


贪婪与懒惰
贪婪 通常的行为是匹配尽可能多的字符
a.*b -- aabab -- 会匹配 aabab
懒惰 只要在后面加上一个问号?。这样.*? 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
a.*?b --- aabab  --  会匹配 aab和 ab


正则的引擎
是否支持忽略优先量词和分组捕获
支持的话是 NFA
不支持的话是 DFA

DFA文本主导   //  awk,egrep,flex,lex,msyql,procmail
NFA表达式主导 //  gnu,emacs,java,ergp,less,more,.net,perl,php,python,ruby,sed,vi



php pcre的主要函数

preg_grep    --------------  返回匹配模式的数组条目
preg_match --------------   执行一个正则表达式匹配
preg_match_all -------------- 执行一个全局正则表达式匹配
preg_filter --------------  执行一个正则表达式搜索和替换
preg_replace --------------   执行一个正则表达式的搜索和替换
preg_replace_callback --------------执行搜索并且使用一个回调进行替换
preg_split-------------- 通过一个正则表达式分隔字符串
preg_quote -------------- 转义正则表达式字符
preg_last_error-------------- 返回最后一个pcre正则执行产生的错误代码


linux下安装node+npm+vue
cd /opt
wget https://npm.taobao.org/mirrors/node/latest-v10.x/node-v10.2.1-linux-x64.tar.gz
tar -zxvf node-v10.2.1-linux-x64.tar.gz

vim /etc/profile
加入
export PATH=$PATH:/opt/node-v10.2.1-linux-x64/bin
然后
source /etc/profile


换用淘宝npm源
npm install -g cnpm --registry=https://registry.npm.taobao.org



安装vue
cnpm install -g vue-cli
vue init webpack first-vue
cd first-vue
cnpm install
npm run dev

然后就可以通过 localhost:8080在浏览器里访问了
php7下安装event扩展
1.先安装libevent

wget https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz

tar -zxvf libevent-2.1.8-stable.tar.gz

cd  libevent-2.1.8-stable

./configure --prefix=/usr/local/libevent-2.1.8

make 

make install


2.再安装event扩展

wget http://pecl.php.net/get/event-2.3.0.tgz

tar -zxvf  event-2.3.0.tgz

cd event-2.3.0

/usr/local/php7/bin/phpize

./configure --with-php-config=/usr/local/php7/bin/php-config --with-event-libevent-dir=/usr/local/libevent-2.1.8/

make 

make install

然后在php.ini中加入 extension=event.so

重启php-fpm即可

php7内核读书笔记-第五章 php的编译与执行
php7内核读书笔记-第五章 php的编译与执行
opline指令-操作数类型
IS_CONST 常量,也称作字面量,比如$a=123,$a="hello",其中123,hello就是字面量
IS_CV 变量,比如$a=123,$b=3+$c,$a,$b,$c就是CV变量
IS_VAR PHP变量,比如$a=time(),time()的返回值就是IS_VAR类型
IS_TMP_VAR 临时变量,或者中间变量 $a="hello_".time(),  "hello".time()就是临时变量
IS_UNUSED 表示操作数没有使用
EXT_TYPE_UNUSED 表示返回值但是没有使用
php7内核读书笔记-第四章 内存管理
php7内核读书笔记-第四章 内存管理
引用计数
会使用引用计数机制的类型
type refcounted
simple types
string Y
interned string N(内部字符串,request完成后统一销毁释放 $a="hi")
array Y
imutable array N(不可变数组)
object Y
resource Y
reference Y

垃圾回收
ps:如果一个变量value的refcount减少到了0,那么此value可以被释放掉,不属于垃圾;如果一个变量value的refcount减少之后大于0,那么此value还不能被释放,此value可能成为一个垃圾(例子 $a=array(1);$a[]=$a;unset($a);)。
回收算法
php7内核读书笔记-第二章 SAPI
php-fpm的worker进程和master进程
worker进程-处理请求
每个worker进程会竞争地Accept请求,接收成功后解析fastcgi,然后执行相应的脚本,处理完成后关闭请求,继续等待新的连接,这个就是一个worker进程的生命周期。
1.等待请求
2.解析请求 
fastcgi请求到达后被worker接收,然后开始接收并解析请求数据,知道request数据完全到达
3.请求初始化
4.执行php脚本
5.关闭请求
master进程-管理进程
三种不同的进程管理模式
1.静态模式static
2.动态模式dynamic  默认
3.按需模式ondemand
信号
1.SIGINT/SIGTERM/SIGQUIT 
退出fpm在master收到退出信号后将向所有的worker进程发布退出信号,通知worker退出,然后master退出
2.SIGUSR1
重新加载日志文件
3.SIGUSR2
重启fpm,首先master也是回向所有的worker进行发出退出信号,等全部worker成功退出后,master会调用execvp()重新启动一个新的fpm,最后旧的master退出
4.SIGCHLD
php7的生命周期

php生命周期.png

1.模块初始化阶段(module startup)

这个阶段主要进行php框架、zend引擎的初始化操作。该阶段的入口函数为php_module_startup(),这个阶段一般是在SAPI启动时执行一次,对于FPM而言,就是在fpm的master进行启动时执行的。
该阶段的几个主要处理如下所诉:
1.激活SAPI:sapi_activate(),初始化请求信息SG(request_info)、设置读取POST请求的handel等,在module_startup阶段处理完成后将调用sapi_activate()
2.启动php输出 php_output_startup
3.初始化垃圾回收期:gc_globals_ctor(),分配zend_gc_globals内存
4.启动Zedn引擎 zend_startup,主要操作包括:
a.启动内存池 start_memory_manager()
b.设置一些util函数句柄(如zend_error_cb.zend_printf.zend_write)
c.设置Zend虚拟机编译、执行器的函数句柄zend_compile_file,zend_execute_ex,以及垃圾回收的函数句柄gc_collect_cycles
d.分配函数符号表(CG(function_table))、类符号表(CG(class_table))、常量符号表(EG(zend_constants))等,如果是多线程的话,还会分配编译器、执行器的全局变量
e.注册zend核心扩展:zend_startup_builtin_functions(),这个扩展是内核提供的,该过程将注册zend核心扩展提供的函数,比如strlen.define.func_get_args.class_exists等
f.注册zend定义的标准常量:zend_register_standard_constants(),比如E_ERROR.E_WARNING.E_ALL.TRUE.FALSE等
g.注册$GLOBALS超全局变量的获取handler
h.分配php.ini配置的存储符号表 EG(ini_directives)
5.注册php定义的常量,PHP_VERSION.PHP_ZTS.PHP_SAPI等
6.解析php.ini,解析完成后所有的php.ini配置保存在configuration_hash哈希表中。
7.映射php、zend核心的php.ini配置:根据解析出的php.ini,获取对应的配置值,将最终的配置插入EG(ini_directives) 哈希表
8.注册用户获取$_GET.$_POST.$_COOKIE.$_SERVER.$_ENV.$_REQUEST.$_FILES变量的handler
9.注册静态编译的扩展:php_register_internal_extensions_func()
10.注册动态加载的扩展:php_ini_register_extensions(),将php.ini中配置的扩展加载到php中
11.回调各扩展定义的module startup钩子函数,即通过PHP_MINT_FUNCTION()定义的函数
12.注册php.ini中禁用的函数、类,disable_functions.disbale_classes.

2.请求初始化阶段(request startup)
该阶段是在请求处理前每一个请求都会经历的一个阶段,对于fpm而言,是在worker进程accept一个请求并读取、解析完请求数据后的一个阶段。该阶段的处理函数为php_request_startup()
主要的处理有以下几个:
1.激活输出:php_output_activate()
2.激活zend引擎 zend_activate,主要操作如下所述
a.重置垃圾回收器 gc_reset()
b.初始化编译器:init_compiler()
c.初始化执行器:init_executor,将EG(function_table)、EG(clas_table)分配指向CG(function_table)、CG(class_table),所以在php的编译、执行同期,EG(function_table)与CG(function_table)、EG(clas_table)与CG(class_table)是同一个值;另外还会初始化全局变量符号表EG(symbol_table)、include过的文件符号表EG(included_files);
d.初始化词法扫描器:startup_scanner()
f.激活SAPI:sapi_activate()
g.回调各扩展定义的request startup钩子函数 zend_activate_modules()

3.执行脚本阶段(execute script)
该极端包括php代码的编译、执行两个核心阶段,这也是zend引擎最重要的功能。在编译阶段,php脚本将经历从php源代码抽象语法树再到opline指令的转化过程,最终生成的opline指令就是zend引擎可识别的执行指令,这些指令接着被执行器执行,这就是php代码解释执行的过程。这个接口的入口函数为php_execute_script()

4.请求关闭阶段(request shutdown)
在php脚本执行解释器执行完成后将进入请求关闭阶段,这个阶段将flush输出内容、发送http应答header头、清理全局变量、关闭编译器、关闭执行器等。另外,在该阶段将回调各扩展的request shutdown钩子函数。该阶段是请求初始化阶段的相反操作,与请求初始化时的处理一一对应

5.模块关闭阶段(module shutdown)

该阶段在SAPI关闭时执行,与模块初始化阶段对应,这个阶段主要是进行资源的清理、php各模块的关闭操作,同时,将回调各扩展的module shutdown钩子函数。具体的处理函数为 php_module_shutdown()



优惠券
最新微语