5.PHP自定义函数、作用域

1.函数

函数是一个固定的代码块,或者称为一个子程序,一个函数可以多次调用。函数实现了计算机模块化编程。

a.函数的定义
function 函数名(参数,参数){
    //执行代码
}
复制代码
  • 函数的命名规则:函数以字母、下划线开头,后面跟的是数字、字母、下划线
  • 函数名不区分大小写
  • 函数可以多次调用
b.可变函数
function fun($args){
	echo $args;
}
$str = 'fun';
$str('呵呵');
复制代码
c.匿名函数

PHP从5.3开始支持匿名函数,匿名函数就是没有名字的函数,匿名函数保存在变量中

$fun = function ($args){
	echo $args;
};
var_dump($fun);
$fun('呵呵');
复制代码
d.函数的预加载

代码的执行过程,词法分析——语法分析——编译——加载编译的代码——执行,在执行代码之前,函数已经加载到内存中了

e.与函数有关的魔术常量

__FUNCTION__用来获取当前的函数名。

function funname(){
    echo __FUNCTION__; //获取当前函数名
}
复制代码
2.create_function()
  • create_function(参数字符串,函数体字符串)
  • create_function()用来创建函数,通过此函数只需要定义需要的函数即可
$leng = 'eng';
if($leng == 'ch'){
	$fn = create_function('$name','echo \'你好\'.$name;');
}elseif($leng == 'eng'){
	$fn = create_function('$name','echo \'hello\'.$name;');
}
$fn('李白');
复制代码
3.function_exists()

判断函数是否存在

function FunctionName(){
	echo 'FunctionName';
}
if(function_exists('FunctionName')){
	FunctionName(); // 如果存在函数就调用
}else{
	echo 'FunctionName函数不存在';
}
复制代码
4.函数参数
  • 实参
  • 形参
a.函数的传值与传址

默认情况下,函数的值都是值传递,在定义函数的时候前面的参数上加上取地址,表示传递的是变量的地址

function fun($args){
	$args = 'this is a string';
}
$stu = array('tom','berry');
fun($stu);
var_dump($stu); 
//array(2) { [0]=> string(3) "tom" [1]=> string(5) "berry" }
复制代码
function fun(&$args){
	$args = 'this is a string';
}
$stu = array('tom','berry');
fun($stu);
var_dump($stu); 
//string(16) "this is a string"
复制代码

++如果在传递地址,在调用函数的时候不能直接写值,只能写变量++

b.参数的默认值

形式参数在定义的时候可以给参数赋一个默认值。

function fun($name='哈哈'){
	echo "你好!{$name}<br>";
}
fun();//你好!哈哈
fun('呵呵');//你好!呵呵
复制代码

默认值必须是一个存在的值,不能通过变量来代替

function fun($name=$value){
	echo "你好!{$name}<br>";
}
fun();'报错'
复制代码

默认值可以是常量

define('VALUE','呵呵');
function fun($name=VALUE){
	echo "你好!{$name}<br>";
}
fun();//你好!呵呵
复制代码

函数有多个参数的时候,没有默认值的参数要放在前面,有默认值的参数放在后面

function fun($name,$sex='男',$age='未知',$add='地址不详') {
	echo "你好:{$name}<br>";
	echo "性别:{$sex}<br>";
	echo "年龄:{$age}<br>";
	echo "地址:{$add}<hr>";
}
fun('李白'); //你好:李白 性别:男 年龄:未知 地址:地址不详
fun('杜甫','女'); //你好:杜甫 性别:女 年龄:未知 地址:地址不详
fun('白居易','男',22); //你好:白居易 性别:男 年龄:22 地址:地址不详
fun('李清照','女',23,'北京'); //你好:李清照 性别:女 年龄:23 地址:北京
复制代码

形参和实参个数不一样

function fun($name1,$name2) {
	var_dump($name1,$name2);
	echo '<hr>';
}
fun(10); // 实参少于形参,报一个错误,继续执行
fun(10,20,30); // 实参多于形参(正常执行,取前面对应的值)
复制代码

传递不确定个数的参数

  • func_num_args():获取参数的个数
  • func_get_args():获取传递的所有参数并转成数组
function fun() {
	$n = func_num_args();
	$g = func_get_args();
	echo $n,'<br>'; //3
	var_dump($g); //array(3) { [0]=> int(10) [1]=> int(20) [2]=> int(30) }
}
fun(10,20,30);
复制代码
5.函数的返回(return语句)

return的作用:

  • 立即从函数中退出
  • Return返回值

示例:求两个数的最大值

function myMax($num1,$num2) {
	if($num1 > $num2)
		return $num1;
	return $num2;
}
echo myMax(10,20); //20
复制代码
a.返回函数的引用
  • 定义函数时,在函数名前面加上”&”表示返回函数的引用
  • 调用函数时,在函数名前面加上“&”,如果没有“&”符,保存的是返回值的值
function &fun() {
	$num = 10;
	return $num;
}
$result = &fun();
echo $result; //10
复制代码
6.变量的作用域
  • 全局变量:在函数外部的变量
  • 局部变量:在函数内部的变量
  • 超全局变量:在函数的内部和外部使用
在javascript中,局部变量只能在函数内部使用,全局变量在函数内部和函数外部使用
默认情况下在PHP中全局变量只能在函数外部使用,局部变量在函数内部使用
复制代码

通过超全局变量实现变量在函数内部和外部访问

$_GET['num'] = 10;
function fun(){
	echo $_GET['num'];
}
fun(); //10
复制代码

通过$GLOBALS[]来获取全局变量的值

$num = 10;
function fun(){
	$num1 = 20;
	echo $GLOBALS['num']+$num1; //$GLOBALS['num'] 获取全局变量num值
}
fun(); //30
复制代码

global关键字用于创建一个对全局变量的引用

$num1 = 100;
function fun(){
	$num2 = 200;
	global $num1; //保存全局$num1地址,等价于$num1=&$GLOBALS['num1'];
	echo $num1+$num2,'<br>'; //300
	unset($num1); //销毁的是全局$num1的地址,不是具体的值
	echo $num1,'<br>'; //报错
}
fun();
echo $num1; //100
复制代码

在函数内部声明全局变量 方法1:

function fun(){
	$_GET['num']=10;
}
fun();
echo $_GET['num']; //10
复制代码

方法2:推荐使用

function fun(){
	$GLOBALS['num']=10;
}
fun();
echo $num; //10
复制代码

方法3:

function fun(){
	global $num;
	$num = 10;
}
fun();
echo $num; //10
复制代码

变量有作用域的概念,常量没有作用域的概念

define('PI',3.14);
function fun(){
	echo PI;
}
fun(); //3.14
复制代码
function fun(){
	define('PI',3.14);
}
fun();
echo PI;//3.14
复制代码
7.变量的生命周期
  • 全局变量:声明的时候产生,页面执行完毕后销毁
  • 局部变量:函数执行的时候产生,函数执行完毕销毁。

可以通过unset()手动销毁变量。

8.静态变量 static
  • 静态变量放在函数内部
  • 作用域不变,还是在函数的内部访问,但是生命周期变了,页面执行完毕后才销毁。
  • 静态变量只能被初始化一次。
function fun(){
	$num = 10;
	$num++;
	echo $num,'<br>';
}
fun();//11
fun();//11
复制代码
function fun(){
	static $num = 10;
	$num++;
	echo $num,'<br>';
}
fun();//11
fun();//12
复制代码

++静态变量作用域没有变,只是生命周期发生了变化++

function &fun(){
	static $num = 10;
	$num++;
	echo $num,'<br>';
	return $num;
}
$str = &fun(); //1
$str = 5;
fun(); //6
复制代码
9.匿名函数的use()

匿名函数的作用域和普通函数是一样的,函数内部不能访问函数外部的变量, ++匿名函数中的use()可以将匿名函数外的变量引入到匿名函数内部++

$num = 10;
$fun = function() use ($num) { //use()可以将匿名函数外的变量引入到匿名函数内部
	echo $num;
};
$fun(); //10
复制代码

use()引入和匿名函数所在同一作用域的变量

$num=10;
function myfun() {
	$num=20;
	$fun=function() use($num){
		echo $num;
	};
	$fun();    //20
}
myfun();
复制代码
a.use()的传值和传址

默认情况下,use()是传值的

传值:

$num=20;
$fun = function() use ($num){
	$num++;
	echo $num,'<br>';//21
};
$fun();
echo $num;//20
复制代码

传址:

$num=20;
$fun = function() use (&$num){
	$num++;
	echo $num,'<br>';//21
};
$fun();
echo $num;//21
复制代码
b.匿名函数的作用

适合建立一个临时函数,用完以后可以销毁,如果一个函数只需要执行一次就可以声明成匿名函数

如何将函数内部的匿名函数在函数外部调用

function myfun() {
	$num = 20;
	$GLOBALS['fun']=function() use ($num) {
		$num++;
		echo $num,'<br>';
	};
}
myfun();
$fun(); //21 将函数保存在全局变量中可以在外部直接调用
unset($fun);//销毁函数
复制代码
10.递归
语法:函数的内部自己调用自己
复制代码
要素:
1、递归点:递归调用的地方
2、递归出口:递归调用结束
复制代码

递归:从1加到100

function fun($num) {
	if($num==1)
		return 1;	//递归出口
	return $num+fun($num-1); //递归点
}
echo fun(100);
//分析
//fun(100)=100+fun(99);
//		=100+99+fun(98);
//		=100+99+98+fun(97);
//		=100+99+98+97++fun(1);
//		=100+99+98+97+1
//结果 5050
复制代码

递归:前10个斐波那契数列

//第n个斐波那契数
function cal($n) {
	if($n==1 || $n==2)
		return 1;
	return cal($n-1)+cal($n-2);
}
// 分析:第5个斐波那契数
// cal(5)	=cal(4)+cal(3)
// 		=2*cal(3)+cal(2)
// 		=2*[cal(2)+cal(1)]+1
// 		=2*(1+1)+1
// 		=5
复制代码

在递归调用的时候,有时候可能PHP执行的时间不够用,可以通过php.ini配置文件更改php最大执行时间

max_execution_time = 30;

11. 函数的代理调用

不直接通过函数名去调用函数,而是通过PHP的内置函数call_user_func_array()来调用函数

<?php
function concat() {
	$array=func_get_args();
	if(empty($array)){
		echo '您没有传递参数<br>';
		return;
	}
	$str='';
	for($i=0,$n=count($array); $i<$n; $i++) {
		$str.=$array[$i];
	}
	echo $str;
}
//concat(1,2,3);
if(isset($_POST['button'])) {
	$str=$_POST['str'];
	$array=explode(',',$str);
	call_user_func_array('concat',$array);  //函数的代理调用
}
?>
<form method="post" action="">
	请输入字符,用逗号分隔:<input type="text" name="str">
	<input type="submit" name="button" value="连接字符串">
</form>
复制代码

传入参数不确定时调用

11. 练习

a.打印颜色面板

<style type="text/css">
	td{
		border:#000 solid 1px;
		width:20px;
		height:20px;
	}
	table{
		border-collapse:collapse;
		float:left;
	}
</style>
<div style="width:500px; margin:auto">
	<?php
		$arr=array('0','3','6','9','C','F'); //组成颜色的字符
		$n=count($arr);	//数组的个数钱
		for($r=0;$r<$n;$r++){
			echo '<table>';
			for($b=0;$b<$n;$b++){
				echo '<tr>';
				for($g=0;$g<$n;$g++){
					echo '<td style="background-color:#'.$arr[$r].$arr[$g].$arr[$b].'"></td>';	
				}
				echo '</tr>';
			}
			echo '</table>';
		}
	?>
</div>
复制代码

b.打印菱形

<style type="text/css">
span{
	width:5px;
	margin:0px 8px;
	display:inline-block;
}
div{
	text-align:center;
}
</style>
<div>
<?php
$total=9;	//总行数
for($i=1;$i<=$total;$i++){
	$row=$i;	//$row表示变化后的行的编号
	if($i>$total/2)
		$row=$total-$i+1;
	$n=2*$row-1;	//星星的个数
	for($j=1;$j<=$n;$j++){
		echo '<span>*</span>';	
	}
	echo '<br>';
}
?>
</div>
复制代码

c.打印0

<div>
<?php
for($i=1;$i<=10;$i++){
	if($i==1 || $i==2 || $i==9 || $i==10){
		for($j=1;$j<=10;$j++){
			echo '<span>*</span>';
		}
	}else{
		for($j=1;$j<=10;$j++){
			if($j==1 || $j==2 ||$j==9 ||$j==10)
				echo '<span>*</span>';
			else
				echo '<span></span>';
		}
	}
	echo '<br>';
}
?>
</div>
复制代码

d.递归法:猴子吃桃子

一个猴子守着一堆桃子,第一天吃了一半又多吃了一个,第二天一样,到第十天就剩下一个桃子,请问原来有几个桃子。
复制代码
//f(n)/2-1=f(n+1)
//f(n)=(f(n+1)+1)*2;
function f($n){
    if($n == 10){
        return 1;
    }else{
        return 2*(f($n+1)+1);
    }
}
echo f(1);
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值