MENU

php中的函数

• May 14, 2018 • Read: 121 • Code

[title]变量[/title]

1、动态变量

定义在函数范围内的变量,其作用域就在函数的范围内,出了函数会被自动释放掉

2、静态变量

用static定义的变量,其作用域同动态变量,不同的是函数结束后它不会被释放掉,每次调用函数都会看是否定义过

function staticVariable(){
  static $a = 2;
  $a++;
  echo $a, "<br />";
}
staticVariable();
staticVariable();

输出结果:

3

4

3.全局变量

在函数外定义的变量,函数内部不能直接拿到,这是我们需要gobal $var,来获取函数外的变量,获取后对变量操作会改变变量的值

function printNum(){
  global $a, $b;//使用的是外面的变量
  echo $a, "<br />";
  echo $b, "<br />";
  $a++;//可以修改外部的a的值
  echo $a, "<br />";
  echo "<br />";
}

[title]值传递和引用传递[/title]

$aa = 1;
$kk = 2;
function change($c){
  $c = 5;
}
change($aa);
echo $aa;

输出结果:

1

实际上它并没有改变变量aa的值,因为在传参数的时候没有把真正的内存中的aa变量传给change函数,而是拷贝了一份传了过去

$aa = 1;
$kk = 2;
function change(&$c){
  $c = 5;
}
change($aa);
echo $aa;

而这样写是把aa的地址传给了change函数,所以结果是5;

如果变量是对象呢?

$obj = new stdClass();
$obj->a = 3;
function change($o){
  $o->b = 5;
}
change($obj);
print_r($obj);

结果是不是stdClass Object ( [a] => 3 ),但实际上是stdClass Object ( [a] => 3 [b] => 5 ),因为变量是存储在栈内存中的,它在堆内存中开辟空间,变量就是地址,所以讲$ojb传给change,就是将地址传了过去。

注:

栈内存是可以直接存取的,而堆内存不可以直接存取。对于我们的对象来数就是一种大的数据类型而且是占用空间不定长的类型,所以说对象是放在堆里面的,但对象名称是放在栈里面的,这样通过对象名称就可 以使用对象了。

[title]可变参数列表[/title]

function var_dump2(){
    if(func_num_args()<1) return;
    $params = func_get_args();
    foreach ($params as $param) {
      if (is_integer($param)) {
        echo "int(".$param.") ";
        continue;
      }
      if (is_string($param)){
        echo "string(".strlen($param).")".$param." ";
        continue;
      }
    }
}
var_dump2(1,2,"3","4444");

ps:

func_num_args() 这个函数返回的是当前函数的参数数量 返回的是数字
func_get_arg()函数返回的是指定位置的参数的值
func_get_args()这个函数返回的是包含当前函数所有参数的一个数组

[title]参数类型[/title]

函数中的参数类型,是对函数类型的限定,可以有数组、对象、callable;

如:function test(array $a){}

function test(callable $aa){
  $aa();
}
function callBack(){
  echo "callback";
}
test('callBack');

[title]可变函数[/title]

function test(){
  echo "可变函数";
}
$kebian = 'test';
$kebian();

但有的时候函数不在这个文件中,你不知道是否可以调用这里我们可以判断一下

if(is_callable($kebian)){
  $kebian();
}

第二种方式:

if(function_exists($kebian)){
  $kebian();
}

[title]嵌套调用[/title]

函数的嵌套调用还是很简单的

function bar(){
  echo "test";
}
function foo(){
  bar();
}
foo();

[title]递归[/title]

function sum($m, $n){
  if($m >= $n){
    return $m;
  }
  return sum($m, $n-1) + $n;
}
echo sum(1, 100);

斐波那契数列

function fbnq($n){
  if($n<=2){
    return 1;
  }
  return fbnq($n-1)+fbnq($n-2);
}
echo fbnq(6);

[title]匿名函数[/title]

$say = function(){
  echo "say";
};
$say();

[title]php实现冒泡[/title]

$arr = [4,9,8,6,7,3,2,1];
function bullingSort(&$arr){
  $checkPoint = 0;
  while (true) {
    $swapCount = check($arr, $checkPoint);
    $checkPoint++;
    if($swapCount <= 0){
      return $arr;
    }
  }
}
function check(&$arr, $checkPoint){
  $swapCount = 0;
  for($i = count($arr) - 1; $i > $checkPoint; $i--){
    if($arr[$i] < $arr[$i-1]){
      swap($arr, $i);
      $swapCount++;
    }
  }
  return $swapCount;
}
function swap(&$arr, $i){
  $tmp = $arr[$i];
  $arr[$i] = $arr[$i-1];
  $arr[$i-1] = $tmp;
}
bullingSort($arr);
print_r($arr);

[title]php解决汉罗塔[/title]

法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
不管这个传说的可信度有多大,如果考虑一下把64片金片,由一根针上移到另一根针上,并且始终保持上小下大的顺序。这需要多少次移动呢?这里需要递归的方法。假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1
三个盘子的汉诺塔:
汉诺塔永远只有三步:

php实现:

function hlt($n){
  if($n === 1){
    return 1;
  }
  return 2*hlt($n - 1) + 1;
}
echo hlt(64);