Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP是否可以编写其他PHP函数,如Lisp宏?_Php_Macros - Fatal编程技术网

PHP是否可以编写其他PHP函数,如Lisp宏?

PHP是否可以编写其他PHP函数,如Lisp宏?,php,macros,Php,Macros,我正在编写一个单元测试平台,我希望能够基于我正在测试的web服务中的每个函数动态生成一个函数。动态函数将使用web服务中每个参数的默认(正确)值生成,并允许使用错误值轻松地进行错误测试 $arrayOfDefVals = array(123, 'foo'); testFunctionGenerator('function1', $arrayOfDefVals); //resulting php code: function1Test($expectedOutput, $arg1=123, $

我正在编写一个单元测试平台,我希望能够基于我正在测试的web服务中的每个函数动态生成一个函数。动态函数将使用web服务中每个参数的默认(正确)值生成,并允许使用错误值轻松地进行错误测试

$arrayOfDefVals = array(123, 'foo');

testFunctionGenerator('function1', $arrayOfDefVals);

//resulting php code:
function1Test($expectedOutput, $arg1=123, $arg2='foo')
{
    try
    {
        $out = function1($arg1, $arg2);
        if($expectedOutput === $out)
            return true;
        else
            return $out;
    } 
    catch ($e) 
    {
        return $e;
    } 
}
这将允许我一次快速、干净地传递一个错误参数或任意数量的错误参数,以测试web服务中的所有错误捕获

我的主要问题是: 这甚至可以用php实现吗? 如果不可能,还有其他选择吗


编辑:我不是在寻找单元测试,我只是在实践中学习。我不是在寻找关于这个代码示例的建议,它只是我想做的一个快速示例。我只是想知道这是否可行。

首先,您可以在函数中设置默认参数:

function function1Test($expectedOutput, $testArg1=123, $testArg2='foo') {
   ...
}
除此之外,我真的不确定你想用这个“函数生成器”实现什么…

阅读和

本手册中的示例应使您走上正确的道路:

<?php
call_user_func(function($arg) { print "[$arg]\n"; }, 'test'); /* As of PHP 5.3.0 */
?>

我不会先尝试,因为PHP没有内置宏支持。但可能是朝着这个方向:

function function1($param1, $param2)
{
    return  sprintf("param1: %d, param2: '%s'\n", $param1, $param2);
}

/* Macro: basically a port of your macro as a function */

$testFunctionGenerator = function($callback, array $defVals = array())
{
    $defVals = array_values($defVals); // list, not hash
    return function() use ($callback, $defVals)
    {
        $callArgs = func_get_args();
        $expectedOutput = array_shift($callArgs);

        $callArgs += $defVals;

        return $expectedOutput == call_user_func_array($callback, $callArgs);
    };
};

/* Use */

$arrayOfDefVals = array(123, 'foo');

$function1Test = $testFunctionGenerator('function1', $arrayOfDefVals);

var_dump($function1Test("param1: 456, param2: 'foo'\n", 456)); # bool(true)

这可能会有所帮助,请参见和。

如果您可以访问该函数(即,它不是PHP标准库的一部分,并且您有权读取该文件),则可以执行以下操作:

假设我们在某个文件中有这样一个函数。必须包含该文件(即,函数必须位于PHP的内部符号表中):

使用ReflectionFunction类获取有关该函数及其定义位置的详细信息:

$reflection=新的ReflectionFunction(“my_original_function”)

接下来,您可以使用反射实例获取该文件的路径、函数的第一行/最后一行编号以及函数的参数:

$file_path = $reflection->getFileName();
$start_line = $reflection->getStartLine();
$end_line = $reflection->getEndLine();
$params = $reflection->getParameters();
使用这些,您可以:

  • 将函数从文件中读入字符串
  • 重写第一行以更改函数名,使用已知函数名作为引用
  • 重写第一行以更改参数默认值,使用$params作为引用
  • 将修改后的函数字符串写入文件
  • 包括该文件
  • 瞧!您现在有了新的可用功能

  • 根据实际要完成的任务,您还可以使用ReflectionFunction::getClosure()获取函数的闭包副本,将其分配给所需的任何变量,并在其中定义参数。请参阅:。或者,您可以实例化多个ReflectionFunction,并使用所需的参数集调用ReflectionFunction::invoke()/invokeArgs()。请参阅:或

    如果函数退出或输出某种错误,而不是返回错误输入的结果,该怎么办?出于好奇,为什么您要编写一个单元测试平台,而不是使用一个已经存在的平台?…也就是说,这只是一个简单的示例,我还想让它做很多其他事情。问题是这是否可能。您可以使用
    create_函数
    ,它基本上是一个穿着羊皮的
    eval
    。我试图避免单独编写每个测试函数。有了宏,我就可以从web服务中给它一个函数列表,然后再给它一个测试函数列表。我知道这不在我的问题中,但作为将来的参考:因为我使用的是SoapClient(),所以我不能使用call\u user\u func\u数组,我不得不改用$client->\u soapCall($callback,$arrayOfArgs)这基本上是一样的,只是它实际上与web服务一起工作。
    $file_path = $reflection->getFileName();
    $start_line = $reflection->getStartLine();
    $end_line = $reflection->getEndLine();
    $params = $reflection->getParameters();