与C语言不同, php中有二种字符串,单引号的与双引号的。。。
在php内部,使用单引号和使用双引号,有什么区别呢?
把变量放到双引号字符串中,与使用.进行字符串连接,哪种方式更省内存呢?
Vulcan Logic Disassembler介绍与安装
Vulcan Logic Disassembler ,简称VLD。D也是Dumper的意思。
它是一个php的扩展(extension), 通过它可以看到PHP编译之后的Opcode。
下载地址:
http://pecl.php.net/package/vld
作者的主页: http://derickrethans.nl/projects.html#vld
xdebug也是此人所写。
环境说明
php5.2.13安装在了/home/modify/test/ 目录中。
/home/modify/test/php-5.2.13/ 是PHP的源码目录。
php位于 /home/modify/test/bin/php
phpize位于 /home/modify/test/bin/phpize
php-config位于 /home/modify/test/bin/php-config
php.ini位于 /home/modify/test/lib/php.ini
php.ini中设置的extension_dir: extension_dir = “/home/modify/test/ext/”
下载vld
[ root@ masalife.com] # cd /home/modify/test/php-5.2.13/ext
[ root@ masalife.com] # svn co svn://svn.xdebug.org/svn/php/vld/trunk vld
编译与安装
[ root@ masalife.com] # cd /home/modify/test/php-5.2.13/ext/vld
[ root@ masalife.com] # /home/modify/test/bin/phpize
[ root@ masalife.com] # ./configure --enable-vld --with-php-config=/home/modify/test/bin/php-config
[ root@ masalife.com] # make
[ root@ masalife.com] # cp modules/vld.so /home/modify/test/ext/
[ root@ masalife.com] # vi /home/modify/test/lib/php.ini
在最后面加上 extension =vld.so
这样就安装完毕了。可以看一下phpinfo,有没有加载到 vld.so。
这个extension有二个参数:
vld.active 1表示启用 0禁用
vld.execute 1运行代码 0只显示Opcode,不运行代码
没有必要把它们写到php.ini中。恩,没有必要。直接在命令行中指定就可以了。
使用vld
来看看下面的PHP代码编译成Opcode之后是什么样子的:
双引号的echo
<?PHP
echo
"huarong@masalife.com"
;
[ root@ masalife.com] # /home/modify/test/bin/php -dvld.active=1 -dvld.execute=0 /tmp/aabi432o32.php
number of ops: 3
compiled vars: none
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2
0
>
ECHO OP1[ IS_CONST ( 5959335 ) 'huarong%40masalife.com' ]
4
1
>
RETURN OP1[ IS_CONST ( 0 ) 1 ]
2
*
> ZEND_HANDLE_EXCEPTION
op总数量3。
@被转义成为 %40 。 和urlencode一样的哈。
双引号被转化成为单引号了!!
单引号的echo
<?PHP
echo
'huarong@masalife.com'
;
[ root@ masalife.com] # /home/modify/test/bin/php -dvld.active=1 -dvld.execute=0 /tmp/aabi432o32.php
number of ops: 3
compiled vars: none
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2
0
>
ECHO OP1[
IS_CONST (
11450330
)
'huarong%40masalife.com'
]
4
1
>
RETURN OP1[
IS_CONST (
0
)
1
]
2
*
>
ZEND_HANDLE_EXCEPTION
仍然是单引号。
双引号字符串中的变量
<?php
$a
=
"modify"
;
echo
"huarong@masalife.com $a
"
;
[ root@ masalife.com] # /home/modify/test/bin/php -dvld.active=1 -dvld.execute=0 /tmp/aabi432o32.php
number of ops: 7
compiled vars: !
0
= $a
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2
0
>
ASSIGN OP1[
IS_CV !
0
]
OP2[
, IS_CONST (
628503
)
'modify'
]
3
1
INIT_STRING RES[
IS_TMP_VAR ~1
]
2
ADD_STRING RES[
IS_TMP_VAR ~1
]
OP1[
IS_TMP_VAR ~1
]
OP2[
, IS_CONST (
628186
)
'huarong%40masalife.com+'
]
3
ADD_VAR RES[
IS_TMP_VAR ~1
]
OP1[
IS_TMP_VAR ~1
]
OP2[
, IS_CV !
0
]
4
ECHO OP1[
IS_TMP_VAR ~1
]
5
5
>
RETURN OP1[ IS_CONST ( 0 ) 1 ]
6
*
>
ZEND_HANDLE_EXCEPTION
0 ASSIGN 是为$a赋值
之后的echo语句竟然变成了4行opcode:
INIT_STRING, ADD_STRING, ADD_VAR, ECHO。
INIT_STRING是初始化整个string
ADD_STRING是添加 “huarong@masalife.com ”
ADD_VAR是添加$a
ECHO就输出了。
如果是 echo “huarong@masalife.com $a abc”
在ADD_VAR之后,还要再ADD_STRING “abc”。
number of ops: 8
compiled vars: !
0 = $a
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2
0
>
ASSIGN OP1[ IS_CV ! 0 ]
OP2[ , IS_CONST ( 3396580 ) 'modify' ]
3
1
INIT_STRING RES[ IS_TMP_VAR ~1 ]
2
ADD_STRING RES[ IS_TMP_VAR ~1 ]
OP1[ IS_TMP_VAR ~1 ]
OP2[ , IS_CONST ( 3396263 ) 'huarong%40masalife.com+' ]
3
ADD_VAR RES[ IS_TMP_VAR ~1 ]
OP1[ IS_TMP_VAR ~1 ]
OP2[ , IS_CV ! 0 ]
4
ADD_STRING RES[ IS_TMP_VAR ~1 ]
OP1[ IS_TMP_VAR ~1 ]
OP2[ , IS_CONST ( 3396585 )
'+abc' ]
5
ECHO OP1[ IS_TMP_VAR ~1 ]
5
6
>
RETURN OP1[ IS_CONST ( 0 )
1 ]
7
*
>
ZEND_HANDLE_EXCEPTION
如果字符串中有很多变量。。。想想就觉得郁闷。
字符串连接
<?php
$a
=
"modify"
;
echo
"huarong@masalife.com"
.
$a
;
[ root@ masalife.com] # /home/modify/test/bin/php -dvld.active=1 -dvld.execute=0 /tmp/aabi432o32.php
number of ops: 5
compiled vars: ! 0 = $a
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2
0
>
ASSIGN OP1[ IS_CV ! 0 ]
OP2[ , IS_CONST ( 7277335 ) 'modify' ]
3
1
CONCAT RES[ IS_TMP_VAR ~1 ]
OP1[ IS_CONST ( 7277018 ) 'huarong%40masalife.com' ]
OP2[ , IS_CV ! 0 ]
2
ECHO OP1[ IS_TMP_VAR ~1 ]
5
3
>
RETURN OP1[ IS_CONST ( 0 ) 1 ]
4
*
>
ZEND_HANDLE_EXCEPTION
简单了很多,字符串连接就是一个CONCAT,然后就ECHO了。
比起把变量放到字符串里面,字符串连接的速度更快啦。
关于这一点,在PHP文档中也有提及:
Parsing variables within strings uses more memory than string concatenation.
When writing a PHP script in which memory usage is a concern,
consider using the concatenation operator (.) rather than variable parsing.
如果是多个字符串进行连接,如 echo “huarong@masalife.com “.$a.” abc”;
就会CONCAT多次:
number of ops: 6
compiled vars: ! = $a
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2
0
>
ASSIGN OP1[ IS_CV ! 0 ]
OP2[ , IS_CONST ( 6217291 ) 'modify' ]
3
1
CONCAT RES[ IS_TMP_VAR ~1 ]
OP1[ IS_CONST ( 6216973 ) 'huarong%40masalife.com+' ]
OP2[ , IS_CV ! 0 ]
2
CONCAT RES[ IS_TMP_VAR ~2 ]
OP1[ IS_TMP_VAR ~1 ]
OP2[ , IS_CONST ( 6217296 ) '+abc' ]
3
ECHO OP1[ IS_TMP_VAR ~2 ]
5
4
>
RETURN OP1[ IS_CONST ( 0 ) 1 ]
5
*
>
ZEND_HANDLE_EXCEPTION
另外一种连接字符串的方式
使用逗号也可以的!
<?php
$a
=
"modify"
;
echo
"huarong@masalife.com"
,
$a
;
[ root@ masalife.com] # /home/modify/test/bin/php -dvld.active=1 -dvld.execute=0 /tmp/aabi432o32.php
number of ops: 5
compiled vars: ! 0 = $a
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2
0
>
ASSIGN OP1[ IS_CV ! 0 ]
OP2[ , IS_CONST ( 3686782 ) 'modify' ]
3
1
ECHO OP1[ IS_CONST ( 3686464 ) 'huarong%40masalife.com' ]
2
ECHO OP1[ IS_CV ! 0 ]
5
3
>
RETURN OP1[ IS_CONST ( 0 ) 1 ]
4
* >
ZEND_HANDLE_EXCEPTION
可以看到,使用逗号连接字符串就相当于echo了多次。。。
不过逗号只有在echo的时候可以用,print就不支持它了。
由于它没有用到CONCAT字符串操作,应该会更加节省内存。