金沙贵宾会官网|金沙贵宾会登录-官网

【A】金沙贵宾会官网超高的返奖率为娱乐者提供资金保障,所以金沙贵宾会登录官网更加的方便了你的娱乐,申请88元彩金,因为在当中不仅仅只有游戏。

func_num_args实现伪重载,php函数的传值与传址

日期:2019-09-29编辑作者:网络安全

偶尔在网上看到关于php的伪重载的问题,有点兴趣便研究了一下。下面作者将说说php如何利用func_get_arg,func_get_args,func_num_args实现函数的伪重载问题。

php中引用的用法:

一、函数的声明
1、语法结构

首先说说方法重载的好处:

  1. 变量的引用赋值: $a = &$b

  2. 函数调用时的引用参数传递

 代码如下

实现方法重载可以不用为了对不同的参数类型或参数个数,而写多个函数。多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。如果我们使用reflector去查看微软写的.net的基类库的话,我们可以发现他使用很多的方法重载,这样我们在调用的时候,就不需要记那么多的方法名称,而是知道了方法的功能就可以直接的给他传递不同的参数,编译器会明确的知道我们调用了哪一个方法。

    1) 早期php是在调用时通过&符号传递引用类型的变量, 比如: func(&$arg);

function 函数名 (参数列表)
{
    函数体; //可选
    返回值; //return可选
}

但是在PHP中没有函数重载这个概念,让很多时候我们无法进行一些处理,甚至有时候不得不在函数后面定义好N个参数来解决相关问题,而php提供了几个函数,比如:func_get_arg,func_get_args,func_num_args 却可以直接解决相关问题。具体举个示例代码如下:

    2) 后来, 函数的引用类型参数被规定为需要在函数声明时定义, 不如: function func(&$arg);

    参数列表用逗号隔开,勿遗漏$变量符号
    函数名不区分大小写,规则与变量一致
    函数调用才执行,可先调用后声明
    函数名不能重名,包括系统函数

 代码如下

       注: 引用声明时定义引用类型参数后, 运行时引用参数传递被废弃, 需要在php.ini中增加allow_call_time_pass_reference来开启.

2、函数调用

<?php
function  testOne($a) {
echo ('一个参数就这样 ');
}
function testTwo($a, $b) {
 echo ('两个参数的就这样 ');
}
function testThree($a, $b, $c) {
 echo ('呵呵,这是三个参数的 ');
}
function test() {
 $argNum = func_num_args();
 // 这一段其实可以用 $_arg = func_get_args() 来获得所有的参数,只是要用数组而已,不方便我下面的表达,呵呵
 for ($i = 0; $i < $argNum; $i++) {
  $_arg_{$i} = func_get_arg($i);
 }
 switch ($argNum) {
  case 1 :
   testOne($_arg_1);
  break ;
  case 2 :
   testTwo($_arg_1, $_arg_2);
  break ;
  case 3 :
   testThree($_arg_1, $_arg_2, $_arg_3);
  break ;
  default :
   echo (' 这是没有参数的情况 ');
  break ;
 }
}
/**
 * 例子的实现
 */
test();
echo ('<br>');
test(1);
echo ('<br>');
test(1, 2);
echo ('<br>');
test(1, 2, 3);
// 这些只是在函数中的运用,其实最主要的还是在类中的运用
// 如果这些用到类里面我就不需要担心构造函数是否有几个参数了,不是吗?
// 类里面的运用只举一个简单的例子
class test{
 var $a = 0;
 var $b = 0;
 function test() {
  $argNum = func_num_args();
  $_arg = func_get_args();
  switch ($argNum) {
   case 1 :
    $this->test1($_arg[0]);
   break ;
   case 2 :
    $this->test2($_arg[0], $_arg[1]);
   break;
   default :
    $this->a = 0;
    $this->b = 1;
   break;
  }
 }
 function test1($a) {
  $this->a = $a;
 }
 function test2($a, $b) {
  $this->a = $a;
  $this->b = $b ;
 }
}

  1. 函数返回引用类型, 这种应用方式需要声明函数时, 在函数名前增加&符号, 并且, 在调用时, 要用引用赋值方式, 比如:

 代码如下

友情提示

 代码如下

function sum($x,$y) //形参:在声明函数时声明的参数
{
    // $x = 1; //如果在函数内对参数赋值,则会覆盖实参。
    // $y = 2;
    $sum = 0;
    $sum = $x + $y;
    return $sum; //执行到return函数结束,后面不再执行
}

php的的func_num_args、func_get_arg和func_get_args都是返回函数实参相关的函数。

function &func() {
    return $a;
}
$a = func();  //这种调用方式得到的不是引用传值
$a =& func(); //这样调用才是引用传值

sum();
sum(2,2); //实参:在调用函数时传递给形参的数值
echo sum(2,2); //通过return返回数据可作为值使用

func_num_args:实参个数;

简而言之, 就是让函数的返回一个引用类型的值, 一个更实际的例子:

二、函数中的变量
1、变量范围

func_get_arg:返回某一个实参,必须事实参数组的索引;

 代码如下

    局部变量:函数内部声明与使用的变量
    全局变量:在函数外声明,脚本任何地方均可以使用

func_get_args:返回实参数组;

$a = 1;
function &func(&$a) {
  return $a;
}
$b = func($a);
$c =& func($a);
$b = 2;
echo "a: $a, b: $b, c: $c. <br />/n";
//输出a: 1, b: 2, c: 1.
//可见对$b的修改不会影响$a
$c = 3;
echo "a: $a, b: $b, c: $c. <br />/n";
//输出a: 3, b: 2, c: 3.
//可见对$c的修改会影响$a

Tips:在PHP函数中使用全局变量,要通过global关键字将这个全局变量包含到函数中才能使用

php函数传值的几个细节

 代码如下

 代码如下

$a = 1;
$b = 2;
function demo($a = '')
{
    //global 须放在前面
    //global $a,$b global 可包含多个全局变量
    //$GLOBALS['a'] //声明全局变量 方法二
    global $a;
    $a += 5;
    echo $a;
}

//一、基本数据类型的传值  
/* **************************************************** */ 
function testvar($k){
 $k = 40;
}
$c = 30;
//给一个函数参数传一个基本数据类型(整型,布尔,字符 ...), 实际上传的就是值 ;
testvar($c);
echo $c;//结果是:30
 
 
function testvar2(&$k){
 $k = 40;
}
$e = 30;
//给一个函数参数传一个基本数据类型(整型,布尔,字符 ...), 实际上传的y就是地址 ;
testvar2($e);
echo $e;//结果是:40
 
/* **************************************************** */
//二、数组(默认情况下是复制一份数据),如要传地址则&$arr.
$arr1 = array(-1,5,0);
function testArr($arr){
 for($i=0;$i<count ($arr);$i++){
  for($j=$i+1;$j<count($arr);$j++){
   if($arr[$i]>$arr[$j]){
    $temp = $arr[$i];
    $arr[$i] = $arr[$j];
    $arr[$j] = $temp;
   }
  }
 
 }
 print_r($arr);  //结果:Array ( [0] => -1 [1] => 0 [2] => 5 )
}
testArr($arr1);
print_r($arr1);  //结果:Array ( [0] => -1 [1] => 5 [2] => 0 )
 
function testArr2(&$arr){
 for($i=0;$i</count><count ($arr);$i++){
  for($j=$i+1;$j<count($arr);$j++){
   if($arr[$i]>$arr[$j]){
    $temp = $arr[$i];
    $arr[$i] = $arr[$j];
    $arr[$j] = $temp;
   }
  }
 
 }
}
testArr($arr1);
print_r($arr1);  //结果:Array ( [0] => -1 [1] => 0 [2] => 5 )
 
 
 
 
/* **************************************************** */
//三、对象数据类型传值
class person{
 public $name;
 public  $age;
}
 
$a = new person();
$a->name = '小明';
$a->age = '20';
//变量a在存的是对象的地址,把a赋给b这个变量,实际上就是赋了一个地址。
$b = $a;
$b->age = 30;
//echo $a->age.$b->age;//结果是:30 30
//给一个函数参数传一个对象, 实际上传的是这个对象的地址;
function test($k){
 $k->age =40;
}
//调用
test($b);
//echo $a->age.$b->age;//结果是:40 40
</count>

demo();

php函数的传值与传址有什么区别呢?对于这样的问题我喜欢通过程序演示来获取答案。让我们来看一个演示记录吧!

2、PHP静态变量

 代码如下

    静态变量可以在同一个函数中多次调用中共用
    静态变量只能在函数或类中声明,不能在全局声明。

<?php   
       
$i=100;   
       
function func($n){   
       
   $n=$n+100;   
          
   return $n;   
          
}   
echo '1)函数传值前变量$i的值:'.$i.'<br>';   
echo '2)传值后函数的返回值:'.func($i).'<br>';   
echo '3)函数传值后变量$i的值:'.$i.'<br>';   
echo '4)函数传址前变量$i的值:'.$i.'<br>';   
echo '5)传址后函数的返回值:'.func(&$i).'<br>';   
echo '6)函数传址后变量$i的值:'.$i.'<br>';   
//echo func($i).'<br>';   
?>

 代码如下

程序输出:

function demo($a = '')
{
    static $a = 0; //定义静态变量
    $a++;
    echo "$a <br>";
}
demo(); //输出1
demo(); //输出2

1)函数传值前变量$i的值:100
2)传值后函数的返回值:200
3)函数传值后变量$i的值:100
4)函数传址前变量$i的值:100
5)传址后函数的返回值:200
6)函数传址后变量$i的值:200
   
解释:

3、变量函数

1)直接输出一个赋值$i=100的变量
2)func函数传值返回一个算术相加的结果$=100+100
3)func函数传值,其作用区域只限于函数内部,对外面的变量$i不会有影响
4)同上
5)func函数参数前多了个"&"符,表示传址,和2)一样,返回值是函数的算术运行结果。

 代码如下

6)func(&$i),变量指针指向$i的位置,可以理解为是对变量$i的操作,$i=$i+100;这时变量$i已经相当于重新被赋值

$var = 'hello'; //变量名后面右括号,就寻找与变量值同名的函数
$var(); //等价于 hello();

如果去掉上面代码的第18行注释,会得什么结果呢?

三、函数分类及声明

小结:传址为了在执行函数的同时,同时改变函数参数值,而传值不期望改变。

1、函数分类

 代码如下

//常规函数
bool copy(string source,string dest)

//带mixed,表示可以传任何类型的数据
bool chown(string filename,mixed user)

//带&参数的函数,这个参数只能是变量,变量值是动态的
//对数组进行排序,数组的索引保持和单元的关联
bool arsort ( array &$array [, int $sort_flags ] )
$fruits = array('a', 'c', 'b');
arsort($fruits);
var_dump($fruits);

//默认函数,即带[]中括号的函数,表示参数可选,若没有传值则使用默认值
//如果调用没有赋值,又没有初值则出现警告
function demo($a=1,$b=2)
{
    #code
}
demo();

//带有...参数的函数,表示可以传任意多个参数
//在数组开头插入一个或多个单元
int array_unshift ( array &$array , mixed $var [, mixed $... ] )

2、声明多个参数函数

 代码如下

function Test()
{
    echo func_num_args();
}
Test('a','b','c');  // 3

func_get_arg():返回参数列表中的第N个参数

function Test()
{
    echo func_get_arg('1');
}
Test('a','b','c'); //b

使用实例

 代码如下

function cls_mysql()
{
    $mysql = func_get_args();
    $conn = mysql_connect($mysql['0'], $mysql['1'], $mysql['2']);
}
cls_mysql('localhost:3306', 'root', '123456');

3、函数注释规范

 代码如下

/**
 * 用用演示函数 //函数功能,决定是否使用
 *
 * @static
 * @access public
 * @param string $attributeName 属性名称 //函数参数,决定怎样调用
 * @return string //函数的返回值,决定调用后怎么处理
 */
public function demo($attributeName)
{
    $attributeName = 'abc';
    return $attributeName
}

四、Callback 回调函数

我们自定义一个函数A,但是我们不直接去调函数A,而是在函数B中去调用函数A,函数B通过接收函数A的名字和参数来实现对函数A的调用,函数A称为回调函数。

 代码如下

function A($x,$y)
{
    return $x*$y;
}
function B($a,$b,$fun)
{
    return $a+$b+$fun($a,$b);
}
echo B(2,3,"A");

PHP回调函数的实现方法

php提供了两个内置函数call_user_func()和call_user_func_array()提供对回调函数的支持

 代码如下

//mixed call_user_func_array 以数组的形式接收回调函数的参数
mixed call_user_func_array ( callable $callback , array $param_arr )
call_user_func_array('f1',array('A','B'));

//call_user_func的参数个数根据回调函数的参数来确定
mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
call_user_func_array('f1','A','B');

实例:

 代码如下

//普通全局函数
function f1($arg1,$arg2)
{
    echo $arg1."<br>".$arg2."<br>";
}

echo "通过call_user_func_array调用函数f1:<br>";
call_user_func_array('f1',array('A','B'));

echo "通过call_user_func调用函数f1:<br>";
call_user_func('f1','C','D');

//类
class myClass
{
    public $name;
    function show($arg1)
    {
        echo '参数名:'.$arg1."<br>";
        echo '对象中的成员名:'.$this->name;
        echo "<br>";
    }
    function show1($arg1,$arg2)
    { 
        echo $arg1."<br>".$arg2."<br>";
    }
    public static function show2($arg1,$arg2) 
    {
        echo $arg1."<br>".$arg2."<br>";
    }
}

echo "调用类中非静态成员函数,该成员函数中有this调用了对象中的成员:<br>";
$a = new myClass;
$a->name = 'F';
call_user_func_array(array($a,'show'),array('E'));

echo "调用类中非静态成员函数,该函数没有调用对象中的成员,没有this:<br>";
call_user_func_array(array('myClass','show1'),array('G','H'));

echo "调用类中静态成员函数:<br>";
call_user_func_array(array('myClass','show2'),array('I','J'));

五、内部函数

在函数内部再声明函数,目的是在函数内部调用,用来帮助外部函数完成一些子功能

本文由金沙贵宾会官网发布于网络安全,转载请注明出处:func_num_args实现伪重载,php函数的传值与传址

关键词:

解析xml文档代码,dom读取xml文档代码

$dom = new domdocument; $dom-loadxml($xml_str); 复制代码 代码如下: books book authorjack herrington/author titlephp教程hacks/title publishero...

详细>>

php删除钦点目录下的相干文书实例,php删除目录

 代码如下 本文实例讲述了php实现删除指定目录下相关文件的方法。分享给大家供大家参考。具体实现方法如下: 例...

详细>>

的行使介绍

php教程 mysql教程_fetch_array与mysql_fetch_assoc区别 mysql_fetch_array --从结果集中取得一行作为关联数组,或数字数组,或二...

详细>>

php用户注册ID验证正则表达式,CodeIgniter使用php

1.检查客商名是或不是符合规定 两位以上的假名,数字,大概下划线   正则表明式直白以来是本身相比头痛的东西,...

详细>>