PHP的字符串

与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字符串操作,应该会更加节省内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值