PHP的字符串

    技术2022-05-19  30

    与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@masalife.com' ] 4 1 > RETURN OP1[ IS_CONST ( 0 ) 1 ] 2 * > ZEND_HANDLE_EXCEPTION

    op总数量3。 @被转义成为 @ 。 和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@masalife.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@masalife.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@masalife.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@masalife.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@masalife.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@masalife.com' ] 2 ECHO OP1[ IS_CV ! 0 ] 5 3 > RETURN OP1[ IS_CONST 0 ) 1 ] 4 * > ZEND_HANDLE_EXCEPTION

    可以看到,使用逗号连接字符串就相当于echo了多次。。。

    不过逗号只有在echo的时候可以用,print就不支持它了。

    由于它没有用到CONCAT字符串操作,应该会更加节省内存。


    最新回复(0)