PHP基础之一揽子方案

来源:互联网 发布:php aes cbc解密乱码 编辑:程序博客网 时间:2024/05/18 21:10

P4-PHP基础4(类型转换,运算符,分支结构)
一、PHP类型转换,必须是同类型才能运算
    变量类型转换分:自动转换和强制转换。//使用时注意了:()包括在int上,如(int)4.5;     //结果4
1、强制转换    注意:结果不是对原来变量自身进行重新赋值,所以要将其赋值给一个变量。
   1.1 setType($a,"bool");//方法1:强制转为布尔型     echo getType($a);获取类型。
   1.2 (int) $a ,强制转成整型;(string)$a ,强制转成字符串;(object) $a ,强制转成对象;
    (bool) $a ,强制转成布尔值;(float) $a ,强制转成浮点型;(array) $a ,强制转成数组型
    例:1.$a="100px";2.$z=(int)$a;    3.echo $a."<br>",$z;//结果100px    100---强制转换未改变原变量自身
    不能将一个变量转换为特殊类型如(null)$a;或(resource)$a会报错
2、其他类型转换为布尔型:0,'','0',null,array(),空对象转换为布尔型结果都是false,其他都是true
3、其他类型转换为整型:    int()相当于JS中的parseInt(),例int(100abc);//结果100    int(abc100);//结果0
4、其他类型转换为浮点型:相当于JS中的parseFloat(),$a=(float)'1.23.45';//结果1.23,第二个.及其之后数值会舍去
5、其他类型转换为字符串型:3个特殊:$a=(string)true;//结果1,$a=(string)false;//结果"",$a=(string)NULL;//结果""

二、进制介绍---计算机底层的数据运算和存储的都是二进制数据
           一个8进制数,可以用3个二进制数,来表示。如:(567)8 《=》 (101 110 111)2        可互转,不足位取零
 一个16进制数,可以用4位二进制数,来表示。如:(A23)16 《=》 (1010 0010 0011)2
    二进制bin,八进制oct,十进制dec,十六进制hex。
    十进制转换为二进制、八进制、十六进制---decbin、decoct、dechex,其他进制与十进制相互转换也类似:两两组合
    echo decbin(10);//结果1010    echo hexdec('1A');//结果是十进制数26    echo dechex(6789);//1a85
注意:二进制无法直接转换为八进制。以上函数只能是十进制和其他进制之间的转换,其他进制相互之间没有函数进行转换。
    所以要先将其转换为十进制数,然后再进行转换。例:echo decoct(bindec(100111011));//结果473
三、ASCII编码:就是将字符转换为二进制进行存储的一种国际编码表。
    1、至今为止一共定义了128个字符编码。
    2、ASCII编码表都是按照顺序进行存储的
    3、小写字母比大写字母大,相同字母大32。A对应的十进制是65,a是97。
    ASCII字符集:0-9、标点符号、A-Z、a-z。
四、运算符
1、算术运算符:二元运算符 (+、-、*、/、%)、一元运算符(++、--)
    算术运算符的运算结果,一定是数值型。
    类型转换:如果两边的操作数不是数值型,要先转成数值型,再进行算术运算。
    取余%结果跟被除数有关,不是整数要转成整数。var_dump(9.8%3);//int(0),echo 10%-3;//结果1,echo -10%-3;//结果-1
    “++”有两种用法:作前缀(++$a)、作后缀($a++)。
    (1)如果单独使用,则$a++和++$a结果一样(2)如果和其它表达式混在一起,则$a++和++$a结果不一样。
例:$a=6;     $b=$a++ + $a++ + $a++;//6+7+8=21    ---先赋值后运算,
再如$a=10;$b=$a+++10;//$a:11,$b=20(先计算第3个+,$a+10,然后$a++,特殊:这里++在表达式里优先级较+低)
                        $c=++$a + ++$a + ++$a;//10+11+12=33---先运算后赋值
2、赋值运算符:=、+=、-=、*=、/=、%=
    “=”赋值运算符:将右边运算结果,装到左边变量中;
    $a++和$a+=1是否一样?     不一样,对于数值型都是$a自身+1;但是对于字符串,$a++相当于在原有ASCII编码的基础上+1;如$a="z";$a++结果为az。
3、字符串运算符(. 和 .=)“.”字符串连接运算符:$a = $b."abc";     “.=”字符串连接:先连接后赋值。
4、比较运算符:>、<、>=、<=、==、!=、===、!== 
    重点:比较运算符的运算结果,一定是布尔值。比较运算符优先级:布尔》数字》字符
    “=”赋值号,左边只能是变量名,不能是运算表达式,$a+10=200;是错误的!
    “==”,等于(模糊比较)。判断值是否相等,不管类型。“===”,全等于(严格比较)。同时比较类型和值是否相等。
    “!=” ,判断值是否相等,不管类型。“!==” ,既判断值是否相等,还管类型是否一致。
    字符串比较:两个ASCII字符串相比,按每个字符的ASCII值,进行大小比较。如比较”Bao”和”ao”的大小a的97大于B的66。
5、逻辑运算符:&&、||、!
    一定要小心逻辑短路的情况!!!
    当&&运算符左边为假,或者||运算符左边为真,那么结果就已经确定,php为提高代码运行效率,右边代码被短路不执行。
          
6、条件(三元)运算符 例:$a=10;$b=20;    ①$max=$a>$b?$a:$b;//20   
         ②$max=$a>$b?$a:$b?$b:$a;//20 三元套三元,从左到右    ③$a>$b?echo $a:echo $b;//error三元运算符里不能放输出语句,否则报错
7、运算符优先级
               
8、错误控制运算符(@),主要用来屏蔽表达式的系统错误。
    可以用来屏蔽常量、变量、函数调用、include语句。 一般在项目开发阶段不用而在项目上线阶段使用错误运算符。
    $link=@mysql_connect("localhost","root","123456");//@符号,常用在屏蔽连接数据库的错误
五-1、分支结构(if)
    1、只判断TRUE,不管FALSE         if(){}
    2、既判断TRUE,也判断FALSE      if(){}else{}
    3、多条件判断(多选一)              if(){}elseif(){}elseif(){}……else{}---在PHP中elseif中间最好不加空 格
五-2、分支结构(switch)           
switch(变量){
case 值1:执行代码1;     break;
case 值2:执行代码2;     break;
case 值3:执行代码3;     break;    
          default:默认执行代码;}    
六、date()函数:格式化一个本地时间/日期,语法:string date ( string $format [, int $timestamp ] )例date('Y-m-d H:i:s',$time);
    参数:$format,要格式化的字符串;$timestamp可选。代表要传递的时间戳。默认为当前时间戳。
    $week=date("N");//1~7,取出系统时钟的星期值    echo date("U");// 1483616748返回Unix纪元1970-1-1 08:00:00到当前秒数。=time()
     echo date('c');// 2017-01-05T19:45:48+08:00   echo date("Y-m-d H:i:s");// 2017-01-05 19:45:48
     $today=getdate();//函数返回一个数组,echo $today['year'];//结果2017
$nextWeek=time()+(7*24*60*60);     //当前时间戳:1483618853
echo "一周后日期时间为".date('Y-m-d H:i:s',$nextWeek)."<br>";//一周后日期时间为2017-01-12 20:20:53时间戳转日期
echo "2038-1-19 11:14:07的时间戳".mktime(11,14,8,1,19,2038);//2038-1-19 11:14:07的时间戳2147483647
P5-PHP基础5(数组、替代语法、循环、中断/止、延迟、包含、路径)
一、替代语法endif endfor就是将结构体内开始的{变成:,结束的大括号替换成endXXX,XXX就是结构体的名称。
   $b=0;
    if($b>0):        //这里是冒号
        echo 123;
        elseif($b<0):  echo 456;//if语句到最后才结束endif,其他的直接省略。
        else:    echo 789;
    endif;    //如果书写else if,相当于在else的基础上重新又嵌套了一个if语句,所以用elseif。
    echo '<hr>';
    for($i=0;$i<10;$i++):    echo $i;
    endfor;//结果789---分隔线---0123456789
    推荐在书写html和php的混编语言中使用替代语法。例:
<?php if(): ?>
    <div>
        <?php for($i=0;$i<=10;$i++): ?>
            <span>*</span>
        <?php endfor; ?>
    </div>
<?php endif; ?>
二、1.循环结构(while)---先判断再执行
    $a=1;            (1)变量初始化
    while($a<10){        (2)条件判断:条件为TRUE继续循环,FALSE退出循环
        echo "$a ";
        $a++;        (3)变量更新,如果省略,就是死循环
    }//结果:1 2 3 4 5 6 7 8 9
    可以改成while($a++<10)    echo "$a ";//条件变量必须变化    结果2 3 4 5 6 7 8 9 10
    2.循环结构(do while)        //do while至少会循环一次,条件变量更新代码不能少
    do{
        //循环体代码+变量更新
    }while(条件判断);--- ---先执行再判断
    3.循环结构(for)
    for(变量初始化;条件判断;变量更新){//注:3表达式都可省略,但两分号不能省;3语句执行次数1;n+1;n次
        //循环体代码,如果上面条件判断语句省略,需要给循环体代码加break;否则死循环。
    }
        for($i=1,$j=9;$j>5,$i<=10;$i++,$j--){//每一个表达式可以是多条语句,之间用,隔开。
            ……;}//多条条件判断语句只以后面的条件判断为准,所以尽量加上逻辑运算符:&&、||进行关联。
三、1.break语句:中断各种循环(for、while、do while、foreach)和switch语句。
              语法:break [n];//n可选参数,默认为1。n为从1开始的正整数。用于决定跳出第几层循环。
              说明:一般情况下,要在break之前添加一个条件判断。条件满足则退出循环。
    $a=0;while(++$a){    //第一层循环体
        while(10){    //第二层循环体
            while(true){    //第三层循环体
                break 3;}//执行此语句则跳出全部循环
        }//上句也可以写成 同效果    if(true){ break 3; }
    }
        2、continue语句:继续    //结束本次循环,而开始下一次循环
              语法:continue [n]    //n可选,默认值为1。从1开始的正整数。用于结束第几层循环。
              说明:一般来说,在continue之前加一个条件判断。
              for($i=1;$i<10;$i++){    if($i%2!=0){continue;}    echo "$i";}//2 4 6 8
四、中止脚本运行:die()和exit():作用一模一样,输出一个消息并且退出当前脚本。
             提示:1、连接数据库时使用,2、常用在检查程序错误时缩小bug范围。
              语法:void exit ([ string $status ] )//参数:$status可选,是一个中断脚本执行前的提示信息。
              exit();        //只中断当前脚本,后面不再执行,不会输出任何内容。
          @mysql_connect('127.0.0.1','root','123456')||exit("PHP连接数据库失败!");//先输出信息,再中断。//||逻辑短路
五、延缓脚本执行:sleep(n):延缓执行---相当于JS中的延时器setTimeout()
    语法:int sleep ( int $seconds )//参数:$seconds是延缓的秒数(注意单位是秒数)。
    echo date("Y-m-d H:i:s"."<br>");//先执行将结果存内存
    sleep(10);    //延迟10秒,?能作用到上上句?---作用到整个php文件,全部执行完,apache才发回
    echo date("Y-m-d H:i:s");//效果,延迟10秒后以上两句同时显示出来。
    错误级别:notice提示性错误 warning警告性错误 fatal error致命性错误(终止运行)
六、PHP服务器端包含(4种include、require、include_once、require_once)
    描述:include、require都是语法结构,不是真正的函数,因此后面的括号可带可不带。
    用法:include “1.php”  或  include(“1.php”)
    注意:当.php文件中包含.html文件,则整个复制到php中,若其中有<?php ……?>,也会执行
          1、include和require的区别:两个都是包含文件,但在处理错误时方式不一样。
    ①include:将另一文件的代码包到当前文件中执行,若包含文件不存在,报一警告错误(E_WARNING),脚本会继续向下执行。
    ②require:将另一文件的代码包到当前文件中执行。若包含文件不存在,报一致命错误(E_ERROR),脚本会终止执行。
    ③include_once:将另一个文件的代码包到当前文件中执行。对包含的文件会进行判断,如果该文件曾经被包含过,则该文件就不会再包含了。
    ④require_once:将另一个文件的代码包到当前文件中执行。对包含的文件会进行判断,如果该文件曾经被包含过,则该文件就不会再包含了。
    include_once和include区别:include同一个有函数文件两次,会报fatal error错误,因为在一个脚本文件中,不能定义两个同名的函数(函数重载)和对象。
    使用include_once可以避免函数重载,第二句include_once语句不执行不报错。
2、包含文件中的return语句:可以向include返回一个值。然后,再把该值存储一个变量。
    作用1:终止当前文件后面的所有内容---在函数中,结束当前文件后函数。脚本中结束当前文件后脚本。
                    
               作用2:return最本质的作用是起到一个返回值的作用,一般将经常使用的数据放在一个数组中,然后将数组返回。
                  例:return array(    'cocalhost=>''127.0.0.1',    'user'=>'root','password'=>'root',);
七、数组:一个数组元素由两个部分构成:(1)下标(2)数组的值
         下标的类型,只能是整型和字符串型;(下标又称之为键,所以一个元素又称为键值对)
         数组元素的值,可以是任何类型(整型、浮点型、字符串型、布尔值、NULL、数组、对象、资源)。       
    1、数组的分类
         枚举数组:下标和值不存在逻辑关系,下标为从0开始的正整数,又称为”索引数组”。如:$arr = array(10,20,30)
         关联数组:下标和值存在逻辑关系,就是”关联数组”。如:$arr = array(‘name’=>'张三', 'sex'=>'男');
         混合数组:下标既有字符串的,也有整型的,两种下标都有。$arr = array(10,20,’name’=>’Mary’);
         多维数组:数组元素还是数组。$arr = array(array(10,20));
    2、数组的创建
        (1)使用[]来创建数组:语法一:$arr[]=$value;    语法二:$arr[$key]=$value;
        如果数组不存在,则创建一个新数组,然后再添加第一个元素。该元素的下标为0。
        如果数组已存在,则添加一个新元素,新元素下标为最大整数下标加1。//注意这里是“整数”
        也可以手动指定下标的名称,下标可以是字符串,也可以是整型。
        (2)使用array()函数来创建数组。语法一$arr=array($value1,$value2,$value3,……);
             语法二$arr=array([$key1=>]$value1[,$key2=>]$value2,……);//其中,”=>”称为重载下标,重新指定下标。
注意:
如果在数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了。
对于任意 integer,float,string,boolean 和 resource 类型,如果将一个值转换为数组,将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值。
如果一个 object 类型转换为 array,则结果为一个数组,其单元为该对象的属性。键名将为成员变量名,不过有几点例外:整数属性不可访问;私有变量前会加上类名作前缀;保护变量前会加上一个 '*' 做前缀。这些前缀的前后都各有一个 NULL 字符(\0)。
并不总是给键名加上引号。用不着给键名为常量或变量的加上引号,否则会使 PHP 不能解析它们。
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// Simple array:
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
    echo "\nChecking $i: \n";
    echo "Bad: " . $array['$i'] . "\n";//Undefined index:  $i in /path/to/script.html on line 9
    echo "Good: " . $array[$i] . "\n";//1或者2,下面同上
    echo "Bad: {$array['$i']}\n";
    echo "Good: {$array[$i]}\n";
}
?>
例1$array[5] = 6;
      print_r($array);     //Array ( [5] => 6 )
echo "<br>";
      // 重新索引函数:array_values($arr)返回arr数组中所有的值并给其建立数字索引
      $array = array_values($array);
      $array[] = 7;
      print_r($array);     //Array ( [0] => 6 [1] => 7 )
     echo "<br>";
     例2 var_dump(0 == 'all');//bool(true)字符串和0比较时会先转化为int型,结果都为0
     例3  $colors = array('red', 'blue', 'green', 'yellow');
遍历方法1:foreach ($colors as $gsdf) {//这里$v是变量,也可以是其他字符串
              echo "Do you like $gsdf ?\n";
          }//Do you like red ? Do you like blue ? Do you like green ? Do you like yellow ?
遍历方法2:foreach ($colors as $k=>$v) {
        echo "Do you like $colors[$k]?\n";     //echo "Do you like $v ?\n";也同样效果
    }

                         
八、多维数组:就是数组元素的值,是一个数组。
              语法一:使用[]来创建二维数组$arr[][]='';$数组名[][]
              语法二:使用array()函数创建二维数组$arr=array( 'key'=>array('value',……) );
1、count():计算数组元素个数-例echo count($arr,1);注意:与JS不同,主要用来统计有效数据。
    语法:int count ( mixed $var [, int $mode = COUNT_NORMAL ] )//$var,要统计的数组变量名称;
    $mode可选是否统计多维数组元素个数。1为统计多维,0默认--只统计当前维数。
2、unset()释放给定的变量---也可以删除一个数组元素,也可以删除整个数组。unset($arr[3])
    unset()如果删除一个数组的元素,实际删除的是元素的值,而下标保留,用count()统计会减一(count统计有效元素)。
    再增加一个元素时,下标+1。但删除整个数组时,全不保留。再创建同名数组时是下标从0开始的全新数组。
3、is_array()判断数组中第i排是否为二维数组if( is_array($arr[$i]) ){……}
九、绝对路径、相对路径
    1、./文件名和文件名的区别
    无论是./文件名和文件名都可以代表当前文件夹。但是./文件命仅仅只代表当前文件夹,
    文件名除了表示自己本身所在的文件夹以外,还有include_path中设定的文件夹。
    输入phpinfo(),查找include_path,默认路径是c:/php/pear
    2、set_include_path
    语法 : set_include_path(‘加载路径’)
    set_include_path是替换原来的地址,所以设置了新的地址以后,原来的include_path包含的地址就不见了。
    3、get_include_path:获取include_path设置的路径。
    语法 : get_include_path()
    结合set_include_path和get_include_path就可以在原有的基础上继续增加新的路径。
    例:set_include_path(get_include_path().';c:/php/peach');
//include、require、include_once、require_once加载文件中的相对路径是相对于加载文件所在位置而言,放到include文件中后,所有相对路径都是相对于include文件所在当前位置。
include所在文件就叫include文件,加载远端文件的位置叫加载文件。

<?php
    header("content-type:text/html;charset:utf-8");
    //1.输出1-1000000以内的所有质数。
    $arr[]=2;
    $len=1;
    for($i=2;1;$i++){
        for($m=0,$n=sqrt($i);$m<$len&&$arr[$m]<=$n;$m++){
            if($i%$arr[$m]==0){ continue 2;}
        }           
        echo $i,' ';
        $arr[]=$i;
        $len=count($arr);
    }
        #1. 先将n开平方缩小范围
        #2. 再将所有质数放在数组中
        #3. 分别将要计算的数字去除以小于开平方n的数组中的每一个数字,如果都除不尽,那么这个数字也是质数
?>
P6-PHP基础6(遍历数组、foreach、each()、list()、数组排序、函数调用)
一、遍历数组 :对一个数组的内容完全不知道的情况下,通过循环结构去依次获取数组里面的每一个元素
     1、数组元素指针的理解:每一个数组都有一个唯一数组指针;
          数组初始化,指针总是指向第一个元素。
          数组指针,总是指向一个数组元素。也可以指向数组末端或上端未知(非法区域),这时则返回FALSE,foreach循环结束。
     2、数组指针的函数:current()、key()、next()、prev()、reset()、end()
    1.不移动指针:current():获取当前指针处元素的2.key()获取指针处元素下标。   
    3.next():指针下移一行,返回下一个数组元素的值;4.prev():将指针上移一步,返回上一个数组元素的值。
    5.reset():将指针移到第一个合法位置元素上,返回第一个数组元素的值;6.end():指针移到数组最后一个元素,返回最后一元素的值。
    注意1.上移和下移指针是相对于当前位置为参考,但是指针一旦处于非法位置,就没有参照物了,所以指针无法上下移,返回false。
              注意2.重置指针reset()和最后位end(),不需要参考当前位置,直接可以定位。
              注意3.当指针处于非法位置,其值为false,下标为null。例:
        $arr=array('哈士奇','萨摩耶','阿拉斯加');
        for(;current($arr);next($arr)){     //用for循环结合指针函数遍历数组
            echo '数组当前下标为',key($arr),'<br/>';//数组当前下标为0……
            echo '数组当前值为',current($arr),'<br/>';//数组当前值为哈士奇……
        }
二、Foreach循环:1foreach先下标后移再操作,2写时复制后操作的是拷贝值数组,对其操作不影响原数组。
    1、语法结构:语法一:foreach($arr as $value){……};语法二:foreach($arr as $key=>$value){……}//既遍历数组下标也遍历值
    注意1.foreach一般情况指针遍历完数组后,指针处于一个非法位置。
    注意2.foreach遍历数组之前,会先对指针做一个初始化操作(reset)。
    注意3.foreach遍历数组,实际遍历和操作的是数组的拷贝值,修改原数组,拷贝后的数组不会修改。
    注意4.同理,修改$value的值,原数组也不会发生变化。
    注意5.如果想在修改$value的同时修改原数组的值,那么在foreach的小括号内,$value前加一个&取地址。
        例:foreach($arr as $key=>&$value){     $value='金毛'; echo $value,'<br/>';     }//金毛 金毛 金毛
         var_dump($arr);//结果array(3) { [0]=> string(6) "金毛" [1]=> string(6) "金毛" [2]=> &string(6) "金毛" }
    关于数组变量复制时指针的问题
    当一个变量复制另一个变量后,移动其中一个变量的指针,另一个不会发生变化。
    当一个变量复制另一个变量时,指针也跟着一起复制。
    当一个变量处于非法位置时,复制给另一个变量,先输出谁,谁就被初始化操作了,另一个还处于非法位。
    foreach遍历数组后,指针处于一个不确定的情况,建议在foreach之后还要对指针操作的话,先对指针做一个初始化操作。
$arr=array( array(10,11,12),array(20,21),array(30),    );//用foreach遍历二维数组
        $sum=0;
        foreach($arr as $arr2){//foreach遍历二维数组
                 foreach($arr2 as $value){
                                    $sum+=$value;    }
        }  echo '平均值:'.$sum;//平均值:104
以下代码功能也完全相同:
<?php
$arr = array("one", "two", "three");
reset($arr);
while (list($key, $value) = each($arr)) {
    echo "Key: $key; Value: $value<br />\n";
}

foreach ($arr as $key => $value) {
    echo "Key: $key; Value: $value<br />\n";
}
?>
三、数组操作函数
       1.each()返回数组中当前的键/值对并将数组指针向下移动一步
         语法:array each ( array &$array ),作用:相当current()+key()+next()
    既可以获取当前指针指向的元素下标和值,也可以让指针自动下移一位
              each()获取数组元素的信息,是4个元素的数组,分别是关联数组下的下标和值key=>$key value=>$value和
                             索引数组下的下标和值0=>$key 1=>$value     //0、key是键,1、value是值
         如果内部指针越过了数组的末端,则 each() 返回 FALSE。
while($arr2=each($arr)){    echo '元素下标为:',$arr2['key'],'<br>'
                                                             echo '元素的值为:',$arr2[1],'<hr>'}    //结果循环遍历数组中元素
         2、list():把数组中的值赋给一些变量
         语法:array list ( mixed $varname [, mixed $... ] )
               作用:将数组里面某些元素的值赋值给一些变量。要求数组元素的下标必须从0开始依次递增。
         如:list($a,$b)=$arr;$a就是获取$arr中下标为0的值,$b就是获取$arr中下标为1的值。依次类推
                    while(list($key,$value,)=each($arr)){     echo '元素下标为: ',$key,'<br>';
                                                                               echo '元素的值为: ',$value,'<hr>';} //结果循环遍历数组中元素
               再例:1. $arr=array(1=>'可乐','a'=>'雪碧','b'=>'芬达',0=>'七喜',2=>'健力宝',);       //注意取的下标
                        2. list($a,$b,$c)=$arr;      3. echo $a,' ',$b,' ',$c;    //结果七喜 可乐 健力宝

四、数组排序
    sort():对数组元素的值升序排列,不保留索引关系。(下标发生改变从0升序)
    rsort():对数组元素的值降序排列,不保留索引关系。
    asort():对数组元素的值升序排列,保留索引关系。
    arsort():对数组元素的值降序排列,保留索引关系。
    ksort():数组按键名(下标)升序排列,保留索引关系。
    krsort():数组按键名降序排列,保留索引关系
    natsort():sort进行包含字符串的数字排序,那么其排序的原则是按照字符串大小一个一个字符进行排序,有些场景不使用。
                       因此,natsort就是将整个字符串当成一个整体,然后进行排序。natsort保留原来数组的下标。
              usort():用户可以自定义排序,多用于二维数组
                       语法:usort(数组名,函数),有两参数,排序的原则是两两进行比较排序。如果想让哪个往后排,返回一大于0的整数。
        想让某元素前排,返回小于0的整数,元素位置保持不变的话,那么直接返回一个0。返回的结果不保留原来的下标。
        例:usort($arr,function($num1,$num2){
            if($num1['age']>$num2['age']){return 1;
            }elseif($num1['age']<$num2['age']){return -1;
            }else{return 0;}    });
    注意:所有的排序函数,都是在原来的数组基础上进行排序的,所以只要使用,原数组的排序和关联就改变。

五、函数:将一串功能性的代码封装在一个函数内,然后可以多次重复调用。优点:1方便,2适合结构化编程
         1、函数定义格式    function funcName([形参1][,形参2][,形参3]……){//函数名称funcName必须唯一
                函数的功能代码;
                [return 参数]    //将函数执行结果返回函数调用者,return语句一旦执行,其后的代码不再执行
                        一函数体可有多return,一般在条件判断有多个return,根据不同结果返回不同值。
        }
           函数分为函数声明和函数调用两部分,声明可以放在调用后,因为声明函数是在代码的解析阶段开辟空间,调用函数是在代码执行阶段。
         2、函数调用:
                   了解栈内存,堆内存,代码区,静态区
         3、函数参数
        形参(形式参数):主要用来获取调用函数者传递过来的数据。是一个临时容器。
        实参(实际数据):是真正的数据。实参可以是具体的值,也可以是变量。
   提示:形参不能是具体的值,只能是变量。形参>=实参的参数个数通常要对等。
        当形参个数大于实参个数,系统报错但仍会执行;当形参个数小于实参个数,系统照常执行不报错
        例:fn(10,20,30,40,50,60,70,80);//结果100---相当于后面4个实参没有传递
4、函数参数传递
    ①值传递---又称”拷贝传值”。
        如果在函数内修改了变量的值,函数外变量的值,不会变。
    ②引用传递---又称为”引用传地址”。
        使用”&”,可以将其它变量变成”引用传递”。默认情况下,对象和资源是引用传递。
        通常引用传递用在形参上,function showInfo(&$name,&$age){……}
    ③默认参数---PHP支持默认参数传递。可以减少出错率。
        如果实参个数少于形参时,将用默认参数来代替实参。
        1提示:默认参数的值几乎所有类型都可,但不能是函数调用、资源、对象。如$action="round(12.987)"会报错!
        function showInfo($name,$action="打太极"){ echo "{$name}正在{$action}!";}
        showInfo("老马");//老马正在打太极!    //2。注意:默认参数只能放在非默认参数的右边。
        showInfo("李四","打游戏");//李四正在打游戏!
        3.默认参数不能是一个变量,但是可以是一个常量,但要在函数调用之前定义该常量。
拓展:写时复制 COW---copy on write
当一个变量复制另一个变量的时候,其实并没有直接去开辟一个空间,只有当其中一个变量进行写操作的时候,另一个变量才会去开辟空间。
例:模拟计算机内存去演示写时复制
         memory_get_usage():获取当前代码占用的计算机内存。
         array_fill(startnum,num,value):创建一个数组元素,startnum代表开始起始下标,num代表数组中一共有多少个元素,value给所有元素统一赋值。
        echo memory_get_usage(),'<br>';//225152
        $arr=array_fill(1,100000,1);             //(第一个元素的下标 ,元素个数100000,value给所有元素赋值 1
        echo memory_get_usage(),'<br>';//9272416
        $arr2=$arr;
        echo memory_get_usage(),'<br>';//9272128 ---空间没有明显变化
        $arr[]=2;
        echo memory_get_usage(),'<br>';//18320976--空间明显变化,这时$arr才去开辟了一个空间。
//foreach举例:
    $arr=array('天','地','玄','黄');
    foreach($arr as $key=>$value){
    }
    var_dump(current($arr));//指针处于非法位置

    $arr=array('天','地','玄','黄');
    foreach($arr as $key=>$value){
       $arr[2]='王';
    }
    var_dump(current($arr));//指向地,?先拷贝一份下标下移再操作,原数组指针仍然停在拷贝前
    echo $value;//黄,拷贝值下标已经移到黄

    $arr=array('天','地','玄','黄');
    foreach($arr as $key=>$value){
       if($key==1){
           $arr[2]='王';
       }
    }
    var_dump(current($arr));//指针指向王

    $arr=array('天','地','玄','黄');
    foreach($arr as $key=>$value){
       if($key==2){
           $arr[2]='王';
       }
    }
    var_dump(current($arr));//指针指向黄,先下标后移再操作

    $arr=array('天','地','玄','黄');
    foreach($arr as $key=>$value){
       if($key==3){
           $arr[2]='王';
       }
    }
    var_dump(current($arr));//指针指向天,?谁先写操作谁初始化,另一非法区域

    $arr=array('天','地','玄','黄');
    foreach($arr as $key=>$value){
       if($key==4){
           $arr[2]='王';
       }
    }
    var_dump(current($arr));//指针指向false,非法区域

P7-PHP基础7(可变、create_function 和匿名函数、变量作用域、生命周期、递归、迭代
一、可变参数
    可变参数,就是指实参的中数量是动态的。而形参一般不写参数。 有的情况下,不知道究竟会有多少个参数,那么形参干脆一个不写。
    如:var_dump()、unset() 也是可变参数函数,
提示:以下三个函数只能在函数内部来使用。一、func_get_args(),二、func_get_arg($index),三、func_num_args()
    function getSum(){
        #$arr=func_get_args();         //一、获取传递过来的实参,放入一数组并返回,数组元素下标从0开始递增。
        $len=count($arr); //方式2-$len=func_num_args();//三、获取实参的总个数。
        $sum=0;
        for($i=0;$i<$len;$i++){
            $sum+=$arr[$i];//方式2-$sum+=func_get_arg($i);        }
                       //二、获取第n+1个参数。//注意1.这里是arg而不是args,2.获取的实参下标从0开始算
        echo "和为:$sum";
        $de=func_get_arg(5);      echo '<br>'.$de;    //结果:45  6
    }
    getSum(1,2,3,4,5,6,7,8,9);
二、函数返回值:return语句,将函数计算完的结果返回到调用函数的位置。作用1:终止函数后面的代码,作用2:返回一个结果
return可以在函数中,也可以用在脚本中。
    如果用在函数中,相当于中止函数运行,并向调用者返回一个值。
    如果用在脚本,相当于中止网页执行。如果用在包含文件中,向include返回值。
     如果在函数运行时想返回多个值,可以将多个值放在一个数组中,然后返回数组即可。
         如果直接返回一个值,那么return的数据和接收调用函数的结果,两者之间是一个拷贝传值的关系,
         如果想让两者之间是一个引用传址的关系,需要在声明函数的函数名前家一个&
    例:function &fn(){
            $arr=array(1,2,3);
            $a=10;
            return $arr;
            #return 11;//Notice: Only variable references should be returned by reference in
        }
    $a=fn();var_dump($a);//结果array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
一般情况下,返回数组很大,普通返回方式会将数组所有内容复制一份,效率低,而使用返回函数的地址,只需要复制一份地址即可,代码效率高
三、可变函数:将函数名赋值给一个变量,然后通过变量区调用函数。
          可变函数,可以实现动态调用函数。(根据不同情况调用不同函数)
$file='ch.bmp';     //实例:根据不同的图片扩展名,调用不同的图片处理函数
$type='bmp';
$arr=array(
    'jpg'=>'imagecreatefromjpg','bmp'=>'imagecreatefrombmp','gif'=>'imagecreatefromgif',);
$arr[$type]();
四、create_function('形参列表','函数体代码');作用:创建一个函数
$fn=create_function('$name','echo "Hello $name";');    $fn("李白");//Hello 李白
默认生成的函数名是从lambda_1开始,后面的数字依次递增的一个字符串。
并且函数名字中还存在一个隐藏字符。函数名不断变化,安全性高。只有在重启apache时,才会还原。
string(10)"lambda_12"
create_function只有在执行时才会创建一个函数,如果代码没有执行,则函数没有创建,可以节约代码空间。
五、匿名函数
1、匿名函数,就是没有名字的函数。,不能单独定义,也不能单独调用。如:function(){echo "OK";}       ();//会报语法错误
2、匿名函数的两种用法
(1)匿名函数,主要用来作为数据,传给其它变量。(赋值给一个变量,通过变量去调用这个匿名函数)
(2)匿名函数,可以作为函数的实参,传递给形参
    匿名函数赋值的变量,是不是函数名?不是,其实是一个对象,存储的是函数里面的语句。
     ?怎么判断是一个什么函数?---可以使用var_dump(变量名)来查看其数据类型
               如果是普通字符串类型string(2) "fn",说明其为一个可变函数;如果是一个自增长的字符串string(9) "lambda_6",说明是create_function创建的函数,如果是一个对象object(Closure)#1(0){},说明其是一个匿名函数。

六、变量作用域:指变量的有效范围
1、JS中的变量作用域:
     - 全局变量:在函数外定义的变量称为”全局变量”。可以直接在函数内使用网页执行完毕就消失了
     - 局部变量:在函数内定义的变量称为”局部变量”。函数执行完毕就消失了
2、PHP中的变量作用域
     - 超全局变量:既可在函数内又可在函数外使用。网页执行完毕消失。如:$_GET、$_POST
     - 全局变量:在函数外定义和使用的变量称为”全局变量”。在函数内不能使用。网页执行完毕就消失了。
     - 局部变量:在函数内定义的变量称为”局部变量”。函数执行完毕就消失了。
3、在局部作用域中访问全局变量——global关键字
- 将一个全局变量引入到函数内部去使用。
- 注意:- global只能在函数内部使用;- global只能引用全局变量,而不能一边引用一边赋值。
global关键词引入的变量和全局变量是一个引用传址的关系。
$name="张三";function fn(){
                              global $name;     //$name=&$name;
                              $name="李四";
                              unset($name);
                         }
                         fn();
                         echo $name;          //结果:李四
4、$GLOBALS超全局变量数组:把一个全局变量变成一个超全局变量。
$GLOBALS一个超全局变量数组。该数组中包含$_GET、$_POST、$_COOKIE、$_FILES
$变量1和$GROBALS['变量1']两者是一体的关系,修改其中一个,另一个也变化,删除其中一个,另一个也被删除。
在函数内部输入一个超全局变量,还是需要使用$GLOBALS[变量名]
                    $name="张三";     function fn(){     echo$GLOBALS["name"];     }     fn();//结果张三
5、use:配合匿名函数去进行使用的,作用是引入一个和匿名函数同作用域的变量。
use默认情况下引入变量是一个拷贝传值的关系,所以改变匿名函数内部引入变量的值,外部的变量不会发生变化,
如果想通过改变匿名函数引入的变量来修改外部变量值的话,那么在use后面的变量名前加上一个&。    
          $name="王小伟";     $fn=function() use (&$name){
                                    $name="王大伟";        
                             }    
                             $fn();     echo $name;//结果王大伟
数学函数:1伪随机数int rand([int min,int max])     2四舍五入float round(float val[,int precision])
3舍去法取整float floor(float value)舍去value小数部分4进一法取整float ceil(float value)
例:rand(-10,10)---5     round(2.3456,3)--2.345     floor(2.45)--2     ceil(2.45)--3     
七、生命周期:
超全局变量和全局变量的生命周期是从定义的时候开始一直到程序执行完毕的时候终止
局部变量的生命周期是从定义的时候开始一直到函数执行完毕以后终止。
    静态变量:是使用static关键词定义的变量,只会被声明一次不会再次被声明。
     (只存在于函数作用域内的特殊局部变量,下次调用这函数时,该变量值仍会保留下来。)
其生命周期等同于全局变量的生命周期,其作用域等于局部变量的作用域。例:function fun(){ static $num=1;}
八、递归:分治算法的一种,将一复杂问题拆分为若干相似小问题来解决,然后将所有小问题合并起来就是大问题答案(分-拆-合)
注意:在做递归时必须考虑其return的情况,有去有回,返回时的计算问题也要考虑在内。
(即递归的return不能直接结束循环而是返回上一级递归)
          1、递归分两部分:一、递归点(函数内部调用自己本身的地方)二、递归出口              
          举例:阶乘n! = n(n-1)!。如:5! = 5*4*3*2*1。已知条件:1的阶乘是1
          
一般递归出口都会写在递归点前面,如果没有递归出口,那么函数将会一直运行到时间资源或者空间资源耗尽。
     斐波拉契数列 :第一项和第二项的值为1,从第三项开始,每一项等于前两项的和。
原理图
    function fn($n){
        if($n==1||$n==2){return 1;}
        return fn($n-1)+fn($n-2);
    }echo fn(10);    //1 1 2 3 5 8 13 21 34 55 89
2、函数递归调用
函数递归:在函数中不断的调用自己。
函数嵌套:在函数中调用别的函数。
3、递归实现的条件
一、 递归公式:由前一个值,推导出后一值的公式。
二、递归出口:递归的退出条件。
优点:1代码量简洁,2写起来方便,只需要将题目转换为php语言就可以实现。
缺点:十分占用内存空间2十分浪费时间(综上,递归能不用尽量不用)
九、迭代(递推)例如循环结构就是一个迭代思想(for,while)
缺点 :相对于递归而言,代码量略微增加
优点:节约时间,节约空间

(递归算法)有一个猴子,偷到一堆桃子,第一天,他吃了桃子数量的一半多一个,第二天,他又吃了桃子剩下的一半又多一个。。。。第十天,猴子发现还剩1个桃子了,问,这个猴子偷了多少个桃子。
function fn($n){     
    if($n==1){
        return 1;//递归出口
   }
    return (fn($n-1)+1)*2;
} echo fn(10);
静态变量
    function fun2(){
        static $mm;
        $mm++;
        echo $mm.'ns';
        unset($mm);
        $mo=6265665223;
        echo $mm."nx<br>";
    }
    fun2();
    fun2();
    fun2();
1ns
Notice: Undefined variable: mm in E:\CZwj\wdc\justTest.php on line 43
nx     //静态变量删除后单次函数内无法重新赋值
2ns    //静态变量再次调用函数时数据在原基础上加1
Notice: Undefined variable: mm in E:\CZwj\wdc\justTest.php on line 43
nx
3ns
Notice: Undefined variable: mm in E:\CZwj\wdc\justTest.php on line 43
nx











原创粉丝点击