PHP基础之一揽子方案

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."
",$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) ."
";//一周后日期时间为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 '
';
    for($i=0;$i<10;$i++):    echo $i;
    endfor;//结果789---分隔线---0123456789
    推荐在书写html和php的混编语言中使用替代语法。例:
   
       
            *
       
   
二、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"."
");//先执行将结果存内存
    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中,若其中有,也会执行
           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 不能解析它们。
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 "
";
      // 重新索引函数:array_values( $arr ) 返回arr数组中所有的值并给其建立数字索引
      $array = array_values($array);
      $array[] = 7;
      print_r($array);     //Array ( [0] => 6 [1] => 7 )
     echo "
";
     例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文件,加载远端文件的位置叫加载文件。

    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),'
';//数组当前下标为0……
            echo '数组当前值为',current($arr),'
';//数组当前值为哈士奇……
        }
二、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,'
';     }//金毛 金毛 金毛
         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
以下代码功能也完全相同:
$arr = array("one", "two", "three");
reset($arr);
while (list($key, $value) = each($arr)) {
    echo "Key: $key; Value: $value\n";
}

foreach ($arr as $key => $value) {
    echo "Key: $key; Value: $value\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'],'
'
                                                             echo '元素的值为:',$arr2[1],'
'}    //结果循环遍历数组中元素
         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,'
';
                                                                               echo '元素的值为: ',$value,'
';} //结果循环遍历数组中元素
               再例: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(),'
';//225152
        $arr=array_fill(1,100000,1);             //(第一个元素的下标 ,元素个数100000,value给所有元素赋值 1
        echo memory_get_usage(),'
';//9272416
        $arr2=$arr;
        echo memory_get_usage(),'
';//9272128 ---空间没有明显变化
        $arr[]=2;
        echo memory_get_usage(),'
';//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 '
'.$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
";
    }
    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











你可能感兴趣的:(php)