使用命名参数调用 PHP 函数

  Python 很棒的一点是它能够使用名字将参数传递到一个函数,看起来是这样的:

  my_foo_function(param_name="value", another_param_name="another value")

  今天我想在 PHP 5.4 中做同样的事情(可轻松移植到 PHP 5.3),我写了一个 call_user_func_named 函数,类似 PHP 内置的 call_user_func_array 函数,代码如下:

<?php

$x = function($bar, $foo="9") {
  echo $foo, $bar, "\n";
};

class MissingArgumentException extends Exception {
}

function call_user_func_named_array($method, $arr){
  $ref = new ReflectionFunction($method);
  $params = [];
  foreach( $ref->getParameters() as $p ){
    if( $p->isOptional() ){
      if( isset($arr[$p->name]) ){
        $params[] = $arr[$p->name];
      }else{
        $params[] = $p->getDefaultValue();
      }
    }else if( isset($arr[$p->name]) ){
      $params[] = $arr[$p->name];
    }else{
      throw new MissingArgumentException("Missing parameter $p->name");
    }
  }
  return $ref->invokeArgs( $params );
}

call_user_func_named_array($x, ['foo' => 'hello ', 'bar' => 'world']); //Pass all parameterss
call_user_func_named_array($x, ['bar' => 'world']); //Only pass one parameter
call_user_func_named_array($x, []); //Will throw exception

 

  更新:很感谢一些热心的贡献者做的一些改进:

 

 <?php

$x = function($bar, $foo="9") {
  echo $foo, $bar, "\n";
};

class MissingArgumentException extends Exception {
}

function call_user_func_named_array($method, $arr){
  $ref = new ReflectionFunction($method);
  $params = [];
  foreach( $ref->getParameters() as $p ){
    if (!$p->isOptional() and !isset($arr[$p->name])) throw new MissingArgumentException("Missing parameter $p->name");
    if (!isset($arr[$p->name])) $params[] = $p->getDefaultValue();
    else $params[] = $arr[$p->name];
  }
  return $ref->invokeArgs( $params );
}
function make_named_array_function($func) {
  return function($arr) use ($func) {
    return call_user_func_named_array($func,$arr);
  };
}

call_user_func_named_array($x, ['foo' => 'hello ', 'bar' => 'world']); //Pass all parameterss
call_user_func_named_array($x, ['bar' => 'world']); //Only pass one parameter
call_user_func_named_array($x, []); //Will throw exception

$y = make_named_array_function($x);
$y(['foo' => 'hello ', 'bar' => 'world']); //Pass all parameterss
$y(['bar' => 'world']); //Only pass one parameter
$y([]); //Will throw exception

时间: 2024-11-03 22:22:12

使用命名参数调用 PHP 函数的相关文章

Python自定义函数的创建、调用和函数的参数详解_python

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创见函数,这被叫做用户自定义函数.一.定义一个函数你可以定义一个由自己想要功能的函数,以下是简单的规则: 1.函数代码块以def关键词开头,后接函数标识符名称和圆括号().2.任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数.3.函数的第一行语句可以选择性地使用文档字符串-用于存放函数说明.4.

关于C++函数参数调用的问题

问题描述 关于C++函数参数调用的问题 最近几天都在学习数据结构呀~学习的过程中发现一个小小的问题,虽然放置不管也没有什么关系--但是如果以后因为这些问题酿了大祸就不好了!所以借着这种未雨绸缪(伪)的精神,决定把问题po出来. 此前在下是查过书,查过百度谷歌的,但是找不到很满意的解答(大概是因为这个问题太具体了--),所以把琐碎问题在此提出来.能够回答这细枝末节的高手们,在下十分感激! 问题如下: 如上图所示,我构建了一个结构体叫BiTNode,用来构建二叉树的节点的.接下来我也是在main函数

WebService中更新函数传入值,再调用其中函数时,函数的参数还是未改变

背景: 今天写了一个webservice,又修改了一下函数的返回类型.out参数的数量(改为:public void SendData(DataSet ds, out string result,out string errMsg)),之后更新引用,再调用的使用时候发现SendData显示为public string SendData(DataSet ds, out string errMsg)形式,不管是添加webservice还是reference service都不行,解决方案也清理过,i

python 函数 argparse 使用 - 针对命令行参数调用 [备忘]

python 具有 argarse 模块, 专门针对命令行下的参数传递 参见执行例子: [root@gd02-zabbix-db-research python_api]# ./app.py usage: ./app.py --help [root@gd02-zabbix-db-research python_api]# ./app.py --help usage: app.py [-h] [-t] [-u] [-s SCHEDULER] [-p PERSISTENT] [-r REALSERV

delphi调用HttpQueryInfo函数编译报错,说参数类型不符合

问题描述 delphi调用HttpQueryInfo函数编译报错,说参数类型不符合 procedure Get(url,heads: string;res: TStream); var hInt,hUrl:HINTERNET; buffer:PChar; dwRead:cardinal; hBuf:PChar; flag:Boolean; len,index:Integer; var value: DWORD; begin GetMem(buffer, 65536); GetMem(hBuf,

shell自定义函数及参数调用解析_linux shell

一.定义函数 复制代码 代码如下: function fname(){statements;} 或 复制代码 代码如下: fname(){statements;} 二.调用函数 只需要使用函数名,即可调用某个函数:$ fname ; #执行函数 可以传递参数给函数,并由脚本进行访问:fname arg1 arg2; # 传递参数 以下是函数fname的定义.在函数fname中,包含了各种访问函数参数的方法. 复制代码 代码如下: fname(){  echo $1, $2; # 访问参数1和参数

javascript中函数作为参数调用的方法_javascript技巧

本文实例讲述了javascript中函数作为参数调用的方法.分享给大家供大家参考.具体分析如下: 先来看示例: function Map(){ var obj = {}; this.put = function(key, value){ obj[key] = value; } this.eachMap = function(fn){ for(var attr in obj){ fn(attr, obj[attr]); } } } var m = new Map(); m.put('01', 'a

深入理解JavaScript系列(4) 立即调用的函数表达式_javascript技巧

前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行. 在详细了解这个之前,我们来谈了解一下"自执行"这个叫法,本文对这个功能的叫法也不一定完全对,主要是看个人如何理解,因为有的人说立即调用,有的人说自动执行,所以你完全可以按照你自己的理解来取一个名字,不过我听很多人都叫它为"自执行",但作者后面说了很多,来说服大家称呼为"立即调用的函数表达式". 本文英文原文地址:http://benalman

Applet调用&amp;#106avascript函数

函数 在做的的applet中用到了调用javascript程序调用方法如下:1 首先引入JSObject 包 // LiveConnect... for JavaScriptimport netscape.javascript.JSObject ;2 在调用js的地方用:try { // 创创建JSObjectJSObject.getWindow (this).eval ("javascript::window.open()")}catch (Exception ex) { 错误提示}