基于PHP编程注意事项的小结(2)


    <?php   

         $a   =   1 ;   
         $b   =&   $a ;   
         unset  ( $a );   
         echo $b; //输出:1: 


使用unset($a)与$a=null的结果是不一样的。如果该块内存只有$a一个映射,那么unset($a)与$a=null等价,该内存的引用计数变为0,被自动回收;如果该块内存有$a和$b两个映射,那么unset($a)将导致$a=null且$b不变的情况,而$a=null会导致$a=$b=null的情况。
原因:某变量赋值为null,将导致该变量对应的内存块的引用计数直接置为0,被自动回收。

2)PHP引用是采用引用计数、写时拷贝

很多人误解Php中的引用跟C当中的指针一样,事实上并非如此,而且很大差别。C语言中的指针除了在数组传递过程中不用显式申明外,其他都需要使用*进行定义,而php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“引用计数、写时拷贝”的原理,(写时复制(Copy-on-Write,也缩写为COW),顾名思义,就是在写入时才真正复制一份内存进行修改。)

就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的,比如下面的代码:
$a = array('a','c'...'n');
$b = $a;
如果程序仅执行到这里,$b和$b是相同的,但是并没有像C那样,$a和$b占用不同的内存空间,而是指向了同一块内存,这就是php和c的差别,并不需要写成$b=&$a才表示$b指向$a的内存,zend就已经帮你实现了引用,并且zend会非常智能的帮你去判断什么时候该这样处理,什么时候不该这样处理。

如果在后面继续写如下代码,增加一个函数,通过引用的方式传递参数,并打印输出数组大小。

复制代码 代码如下:


    function printArray(&$arr) //引用传递 
     { 
        print(count($arr)); 
    } 
     printArray($a); 


上面的代码中,我们通过引用把$a数组传入printArray()函数,zend引擎会认为printArray()可能会导致对$a的改变,此时就会自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储。这就是前面提到的“引用计数、写时拷贝”概念。

直观的理解:$a将使用自己原始的内存空间,而$b,则会使用新开辟的内存空间,而这个空间将使用$a的原始($a或者$b改变之前)内容空间的内容的拷贝,然后做对应的改变。

如果我们把上面的代码改成下面这样:

复制代码 代码如下:


    function printArray($arr)  //值传递 
     { 
         print(count($arr)); 
     } 
     printArray($a); 


上面的代码直接传递$a值到printArray()中,此时并不存在引用传递,所以没有出现写时拷贝。

5. 编码的问题

程序代码使用utf-8码,而strlen函数是计算字符串的字节数而不是字符数?
 $str = “您好hello”;

echo strlen($str);

结果:ANSI=9 而utf-8=11,utf-8中文字符编码是3个字节。要获取字符数,使用mb_strlen().

6. PHP获取参数的三种方法

方法一 使用$argc $argv

复制代码 代码如下:


<?php 
    if ($argc > 1){ 
        print_r($argv); 
    }


在命令行下运行 /usr/local/php/bin/php ./getopt.php -f 123 -g 456

运行结果:
     # /usr/local/php/bin/php ./getopt.php -f 123 -g 456
        Array
        (
            [0] => ./getopt.php
            [1] => -f
            [2] => 123
            [3] => -g
            [4] => 456
        )

方法二 使用getopt函数()

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/e149b6fd7700581b5cab3c74f1873957.html