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