imooc慕课 PHP函数篇 笔记

一、为什么要使用函数
封装的代码块,简化重复的书写和调用,便于管理维护。

二、函数结构

三、函数命名规则
有效的函数名以字母或下划线开头,后面跟字母,数字或下划线

四、函数返回值
定义 : 值通过使用可选的返回语句返回 (ps:如果省略return 则返回的是null)
可以返回包括数组和对象的任意类型
返回语句会立即中止函数的运行,并且将控制权交回调用该函数的代码行

五、函数参数篇

1.形参,实参

function show_args($a,$b)  //$a $b为形参
{
    echo  "$a---$b";
}

show_args(1,2);  //1,2 为实参
$a=2;
$b=3;
show_args($a+$b,2+2);//$a+$b,2+2 为实参

实参数目大于形参时,会截取掉多余的,实参可以是常量,变量,表达式

2.参数默认值

function foo($arg1,$arg2,$arg3){}
function foo1($arg1,$arg2,$arg3 = "value"){} //$arg3有默认值

没有传值,则会使用默认值,需要写默认值的形参放后面

3.强类型参数
定义 为参数列表中的参数指定类型,如果传入的数据类型不匹配,将会抛出TypeError异常

function sum(array $a,array $b)
{
    return $a[0]+$b[0];
}
var_dump(sum([1],[2]));  //int(3)  必须要传入数组类型

4.可变参数列表
实现方式1:
func_num_args() 返回传递给函数的参数数。
func_get_arg() 返回参数列表的某一项 配合func_num_args使用
func_get_args() 返回一个包含函数参数列表的数组
(ps:在5.5及更早里面使用)

实现方法2:

function _sum(...$nums){
    var_dump($nums);
}
_sum(1,2,3,4);  //array(4) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) }

(ps:php5.6以后)

function _sum(...$nums){
    $sum = 0;
    if($nums){
        foreach ($nums as $num){
            $sum += $num;
        }
    }
    return $sum;
}
echo _sum(1,2,3,4);  //10

5.值传递&引用传递
传递类型:数值 对象 字符串 数组等

//值传递
function sum($a,$b)
{
    return $a+$b;
}

(ps:实参传递给形参,形参改变,实参并不会改变)

function swap(&$a, &$b)
{
    $tmp = $a;
    $a = $b;
    $b = $tmp;
}
$a = 1;
$b = 2;

swap($a,$b);
echo '$a='.$a.'--$b='.$b;  //$a=2--$b=1

(ps:没有返回值,但是$a和$b的值改变了)

6.变量的作用域
变量范围与生命周期:
局部变量
1) 当前页面中声明的普通变量,不能在函数或者类中起作用
2)当前页面中声明的普通变量,不能被传递到其他页面
3)在函数中声明的普通变量,在函数内部有效
4)在类中声明的属性,在类的内部有效

全局变量(global)
对于php而言,可以这么说,在页面综合那个生成的变量都是全局变量,在整个页面都是有效。但是不能被函数或者类中的方法访问
如果想被函数或者类中方法访问,我们就有了超全局变量
php自定义超全局变量:$_GET $_POST $_COOKIE $_SERVER $_FILES $_ENV $_REQUEST $_SESSION

$g_name = 'zhangxingju';
function show_name()
{
    global $g_name;
    echo $g_name;
    //echo $GLOBALS['g_name'];  
}
show_name();  //zhangxingju

global 和 $GLOBAL区别

$v1 = 1;
$v2 = 2;
function test_global()
{
    global $v1,$v2;
    $v2 = &$v1;
}
test_global();
echo '$v1='.$v1.'--$v2='.$v2;  //$v1=1--$v2=2  其中$v2并没有改变
$v1 = 1;
$v2 = 2;
function test_global()
{
    $GLOBALS['v2'] = &$GLOBALS['v1'];
}
test_global();
echo '$v1='.$v1.'--$v2='.$v2;   //$v1=1--$v2=1  其中$v2改变了 $GLOBALS其实引用了外部真实的$v1 $v2

静态变量(static)

function test_static()
{
    static $a = 0;   //这里所赋的值不能是函数表达式 比如static $a = sqrt(3);
    echo $a++;
}

test_static();  //0
test_static();  //1 上一次$a的值被保存下来了

六.可变函数
变量名后有圆括号,php将寻找与变量的值同名的函数,并且尝试执行它

function get_apple()
{
    return 'In get_apple()';
}

function get_orange()
{
    return 'In get_orange()';
}

$f1 = 'get_apple';
echo $f1();         //In get_apple()
$f1 = 'get_orange';
echo $f1();         //In get_orange()

七、嵌套函数
php嵌套函数有一些特别之处,最特别的是,当外部函数被调用时,内部函数就会自动进入全局域中,成为新的定义函数。

function out()
{
    if(!function_exists('in'))
    {
        function in()
        {
            echo '如果外部函数out()没有被调用的话,我是不存在的';
        }
    }
}

out();
in();  //如果外部函数out()没有被调用的话,我是不存在的

用法&注意 单层&多层嵌套

function f_out()
{
    echo "out \n";
    function f_mid()
    {
        echo "mid \n";
        function f_in()
        {
            echo "in \n";
        }
    }
}

f_out();
f_mid();
f_in();
//需要依次调用

传参的情况

function out($str_msg)
{
    if (!function_exists('in')) {
        function in($msg)
        {
            echo 'funciton in():' . $msg . "
"; } } echo 'funciton out():' . $str_msg . "
"; in($str_msg); } out('zhangxingju'); in('wtsxia'); //funciton out():zhangxingju //funciton in():zhangxingju //funciton in():wtsxia

八、递归函数
函数在它的函数体内调用它自身
分解问题,调用自身

function recursive($i)
{
    $sum = 1;
    if(1 == $i){
        return 1;
    }else{
        $sum = $i * recursive($i-1);
// 或者 $func=__FUNCTION__;  $sum = $i * $func($i-1);
    }
    return $sum;
}
echo recursive(3);  //6

(ps:201170722更新 内部可以使用魔术常量 来代替函数名 __FUNCTION__ 当前的函数名)

九、匿名函数(闭包)
定义 匿名函数(Anonymous functions) 也叫闭包函数(closures),允许临时创建一个没有指明名称的函数。最经常用作回调函数(callback)参数的值

使用 闭包函数可以作为变量的值来使用

$message = "hello";
$example = function ($name) use (&$message)  //引用传值 这样后面重新声明的$message才可以传值进来
{
    echo $message,",",$name;
};  //一定要有分号
$message = "Hi";
$example("zhangxingju");  //Hi,zhangxingju
//回调
function test_closure($name, Closure $clo)
{
    echo "hello,{$name}.";
    $clo();
}

test_closure("zhangxingju",function (){
   echo "this is callback";
});

十、代码复用
单独引用
include 与 require
include_once 与 require_once
include 遇到警告报错,继续执行 require遇到错误直接停止运行

路径引用
set_include_path 设置 include_path 配置选项
get_include_path 获取当前的 include_path 配置选项