免费资源网,https://freexyz.cn/

前言

在所有的编程语言中,方法或者函数,都可以传递一些参数进来进行业务逻辑的处理或者计算。这没什么可说的,但是在PHP中,方法的参数还有许多非常有意思的能力,下面我们就来说说这方面的内容。

引用参数

涉及到值传递和引用传递的问题。在正常情况下,我们使用值传递的时候,变量是进行了拷贝,方法内外的变量不会共享内存。也就是说,在方法体中修改了变量的值,方法外部的变量不会产生变化。而引用传递则是传递的变量的内存地值。方法内外的变量可以看做是同一个变量,比如:

$a = 1;

function test(&$arg){

$arg++;

}

test($a);

echo $a; // 2

为参数加上&标识,就表明这个参数是引用传递的参数。如果没有加这个标识,则所有的基本类型参数都会以值的方式进行传递。为什么要强调基本类型呢?下面我们用类当参数来测试一下:

class A

{

public $a = 1;

}

function testA($obj)

{

$obj->a++;

}

$o = new A();

testA($o);

echo $o->a; // 2

在这个例子中,我们并没有使用&标识来表明参数$obj是引用类型的,但如果传递的参数是对象的话,那么它默认就是进行的引用传递。如果想让对象也是值传递呢?抱歉,在方法参数中是没办法实现的,只能在方法体中使用clone方式对对象参数进行克隆。

class A

{

public $a = 1;

}

function testA($obj)

{

$o = clone $obj;

$o->a++;

}

$o = new A();

testA($o);

echo $o->a; // 1

关于值和引用的问题,可以参考设计模式中原型模式的讲解:PHP设计模式之原型模式

默认参数

参数是可以有默认值的,这个我想大家都应该很清楚了。但是在使用的时候也需要注意,那就是默认参数不要放在前面,否则很容易出错,比如:

function testArgsA($a = 1, $b){

echo $a+$b;

}

testArgs(); // error

function testArgsB($a = 1, $b = 2){

echo $a+$b;

}

testArgsB(); // 3

function testArgsC($a, $b = 2){

echo $a+$b;

}

testArgsC(1); // 3

在复杂的函数或者紧急的业务开发中,很有可能一个不小心就会漏写参数,这时候testArgsA就会返回错误了。当然,这种粗心类的错误是我们应该尽量避免的。

当指定默认值的时候,我们应该根据参数的类型进行指定,比如字符串就指定为'',数字就指定为数字类型。当不确定参数是什么类型时,建议使用NULL做为默认参数。

function testArgsD($a = NULL)

{

if ($a) {

echo $a;

}

}

testArgsD(1);

testArgsD('a');

类型声明

类型声明是在PHP5之后添加的功能,就像java一样,参数前面加上参数的类型,比如:

function testAssignA(int $a = 0)

{

echo $a;

}

testAssignA(1);

testAssignA("a"); // error

如果参数的类型不对,直接就会报错。在PHP7以前,只支持类、数组和匿名方法的类型声明。在PHP7之后,支持所有的普通类型,但是这里要注意的是,只支持普通类型的固定写法。Class/interface name self array callable bool float int string

固定写法是什么意思呢?

function testAssignB(integer $a = 0) // error

{

echo $a;

}

也就是说,int只能写int,不能使用integer,bool也不能使用boolean。只能是上面列出的类型关键字。

类型声明的好处是什么呢?其实就是Java这种静态语言和PHP这种动态语言之间的差别。动态类型语言的好处就是变量灵活,不用指定类型,方便快速开发迭代。但问题也在于灵活,为了灵活,动态语言往往会在比较或者计算时对变量进行自动类型转换。如果你对变量类型转换的理解不清晰的话,很容易就会出现各种类型的BUG。同时,静态类型的语言一般都会有编译打包,而动态类型则是在执行时确定变量类型,所以很少会进行编译打包,相对来说运行效率也就不如Java之类的编译后语言了。

关于PHP的类型转换问题,可以参考此前的文章:PHP中的强制类型转换

Tips一个小技巧,如果声明了参数类型,是不能传递NULL值的,比如:

function testAssignC(string $a = '')

{

if ($a) {

echo __FUNCTION__ . ':' . $a;

}

}

testAssignC(NULL); // TypeError

这时有两种方式可以解决,一是指定默认值=NULL,二是使用?操作符:

function testAssignD(string $a = NULL)

{

if ($a == NULL) {

echo 'null';

}

}

testAssignD(NULL); // null

function testAssignE(?string $a)

{

if ($a == NULL) {

echo 'null';

}

}

testAssignE(NULL); // null

可变数量参数

php中的方法可以接收可变数量的参数,比如:

function testMultiArgsA($a)

{

var_dump(func_get_arg(2));

var_dump(func_get_args());

var_dump(func_num_args());

echo $a;

}

testMultiArgsA(1, 2, 3, 4);

我们只定义了一个参数$a,但是传进去了四个参数,这时我们可以使用三个方法来获取所有的参数: func_get_arg(int $arg_num),获取参数列表中的某个指定位置的参数 func_get_args(),获取参数列表 func_num_args(),获取参数数量

此外,php还提供了...操作符,用于将可变长度的参数定义到一个参数变量中,如:

function testMultiArgsB($a, ...$b)

{

var_dump(func_get_arg(2));

var_dump(func_get_args());

var_dump(func_num_args());

echo $a;

var_dump($b); // 除$a以外的

}

testMultiArgsB(1, 2, 3, 4);

和参数默认值一样,有多个参数的情况下,...b也不要放在前面,这样后面的参数并不会有值,所有的参数都会在b也不要放在前面,这样后面的参数并不会有值,所有的参数都会在b中。不过PHP默认已经帮我们解决了这个问题,如果...参数后面还有参数的话,会直接报错。

利用这个操作符,我们还可以很方便的解包一些数组或可迭代的对象给方法参数,例如:

function testMultiArgsC($a, $b){

echo $a, $b;

}

testMultiArgsC(...[1, 2]);

是不是很有意思,那么我们利用这个特性来合并一个数组会是什么效果呢?

$array1 = [[1],[2],[3]];

$array2 = [4];

$array3 = [[5],[6],[7]];

$result = array_merge(...$array1); // Legal, of course: $result == [1,2,3];

print_r($result);

$result = array_merge($array2, ...$array1); // $result == [4,1,2,3]

print_r($result);

$result = array_merge(...$array1, $array2); // Fatal error: Cannot use positional argument after argument unpacking.

$result = array_merge(...$array1, ...$array3); // Legal! $result == [1,2,3,5,6,7]

print_r($result);

和方法声明参数时一样,在外部使用...操作符给方法传递参数时,也不能在...后面再有其他参数,所以array_merge(...array1, array1,array2)的操作会报错。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/201911/source/PHP%E6%96%B9%E6%B3%95%E5%8F%82%E6%95%B0%E7%9A%84%E9%82%A3%E7%82%B9%E4%BA%8B%E5%84%BF.php

参考文档: https://www.php.net/manual/zh/functions.arguments.php https://www.php.net/manual/zh/functions.arguments.php#121579免费资源网,https://freexyz.cn/

php方法参数,关于PHP方法参数的那一些事相关推荐

  1. java unlimited_具有无限参数的Java方法(Java method with unlimited arguments)

    具有无限参数的Java方法(Java method with unlimited arguments) Spring框架使用方法,您可以根据需要传递尽可能多的参数. 我想写一个函数,也可以采取无限量的 ...

  2. tomcat7修改内存 win_详解Windows下调整Tomcat启动参数的实现方法

    Windows下调整Tomcat启动参数 Tomcat默认可以使用的内存为128MB,对于访问数比较多.比较吃内存的应用来说,这是不够的.我们可以通过调整Java虚拟机的启动参数来增加Tomcat可使 ...

  3. java 返回值判断_在Java中判断方法重载的条件除了参数外,还可以通过返回值类型判断。_学小易找答案...

    [单选题]若int x;且有下面的程序片断,则输出结果是() . for (x=3; x<6; x++) { printf((x%2) ? "##%d" : "** ...

  4. swift 方法的局部和外部参数名

    一.什么是外部参数名? 浅显地说,外部参数名就是在调用一个方法时要在方法的参数前面加上一个特定的名字,目的是便于阅读代码,提高维护效率. 二.在最新的Xcode中,外部参数名的性质与用法如下 性质: ...

  5. 新浪微博开放平台API中page参数的使用方法

    新浪微博开放平台API中page参数的使用方法 在做项目的时候,有时候要调用新浪微博开放平台的API.说实话,新浪微博的API功能很强大,但是API文档写的不是很清楚. 我在做项目的时候,调用了很多A ...

  6. android优雅私有方法注释,带有注释参数的私有方法的Android java.lang.VerifyError

    我有一个非常简单的项目可以编译,但是无法在Emulator上启动.问题在于这种方法: private void bar(@Some String a) {} // java.lang.VerifyEr ...

  7. DL之DNN优化技术:DNN中参数初始化【Lecun参数初始化、He参数初始化和Xavier参数初始化】的简介、使用方法详细攻略

    DL之DNN优化技术:DNN中参数初始化[Lecun参数初始化.He参数初始化和Xavier参数初始化]的简介.使用方法详细攻略 导读:现在有很多学者认为,随着BN层的提出,权重初始化可能已不再那么紧 ...

  8. .net mvc actionresult 返回字符串_072-SpringMVC后端控制器接收参数、处理器方法返回值类型、拦截器、文件上传下载...

    1. 注解式开发之annotation-driven解释 (1) mvc注解驱动在哪个文件中配置? 在springmvc中配置 (2) 配置mvc注解驱动使用哪个标签? 2. 注解式开发之视图解析器 ...

  9. 三个案例带你看懂LayoutInflater中inflate方法两个参数和三个参数的区别

    本文转载自[http://blog.csdn.net/u012702547/article/details/52628453] 关于inflate参数问题,我想很多人多多少少都了解一点,网上也有很多关 ...

  10. php pdo 参数绑定,PDO绑定参数的其他方法

    摘要:在<PDO中预处理语句占位符的使用​>已经介绍了参数绑定方法bindParam(),冒号':'占位符和问号'?'都可以使用这个方法绑定参数,而且还可以指定绑定参数的类型,再次确保在执 ...

最新文章

  1. 实力封装:Unity打包AssetBundle(大结局)
  2. python双下划线什么意思_python中几个双下划线用法的含义
  3. openshift_为Openshift + MongoDb应用程序编写验收测试
  4. C语言课后习题(14)
  5. 【LeetCode】剑指 Offer 57 - II. 和为s的连续正数序列
  6. php +html5 websocket 聊天室
  7. Facebook AI研究员田渊栋:2021年年终总结
  8. error: No implicit Ordering defined for Any
  9. u盘修复计算机w7,制作win7系统修复u盘的方法
  10. Android混淆规则
  11. 前端vs图片:2 图片深度、图片分类等基本信息
  12. 读《创业36条军规》(五)放下身段死缠烂打
  13. 今日恐慌与贪婪指数为10 恐慌程度稍有上升
  14. 测评Mimick模型对词向量重构效果
  15. mv 命令批量移动文件夹
  16. petgo.jp狗粮
  17. 如何让你画里的鱼,游进海里?
  18. 【ANSYS】ANSYS导入数组方法:MATLAB输出TXT文件导入ANSYS笔记
  19. opengl随机地形生成
  20. Nvidia AGX Xavier MAX9286 GMSL 载板(绿板)

热门文章

  1. VC里的project panel窗口如何实现(转载)
  2. JS数据类型 构造函数 原型链
  3. 淘宝网的软件质量属性分析
  4. python爬虫播放mp3
  5. 第二章:2线性表---单链表表示和实现
  6. 做问答系统是对题目修改的bug
  7. 进程间能否传递指针?
  8. asp.net 2.0
  9. WTL-编译出错01--CVTRES : fatal error CVT1100: 资源重复。类型: MANIFEST,名称: 1,语言: 0x0409
  10. Excel导出改造_只填写字典类型_就可以自动对应导出_字典类添加获取字典值方法---SpringCloud Alibaba_若依微服务框架改造---工作笔记013