PHP:我可以将函数存储在类对象中,并将值传递给它以供函数解释吗。Python可以做到这一点,但PHP可以吗?

PHP:我可以将函数存储在类对象中,并将值传递给它以供函数解释吗。Python可以做到这一点,但PHP可以吗?,python,php,class,Python,Php,Class,我很难弄清楚如何实现类似于以下Python代码的代码: class _Mapper(object): # Holds the name of the function to call when we want to predict a value. # There may be dozens of these _Mapper objects stored in an array which are # created by calling _create_couplet(

我很难弄清楚如何实现类似于以下Python代码的代码:

class _Mapper(object):
    # Holds the name of the function to call when we want to predict a value.
    # There may be dozens of these _Mapper objects stored in an array which are
    # created by calling _create_couplet() in a nested loop
    def __init__(self, estimator):
        self.estimator = estimator

def _create_couplet(pairings, A, B):
    # Gets the data for the pairing from the pairings class and returns a Mapper
    # object containing the function (either function 1 or function2 - defined in
    # pairing class) that we'll use to to predict the value
    if A < B:
        return (_Mapper(pairings.function1))
    else:
        return (_Mapper(pairings.function2))

# Use the function (either function1 or function2) stored in _Mapper.estimator
# (created by _create_couplet) to estimate the new value based on the old value
newValue = _Mapper.estimator(oldValue)
它获取_Mapper.estimator中保存的函数,然后将oldValue传递给,就好像它是newValue=function1(oldValue)或newValue=function2(oldValue)

我试图在PHP中实现类似的东西,但在CLI中运行时,我似乎得到了某种无限循环。函数名似乎未存储在

class Pairings {
    // Define the two functions (these are just placeholders)
    public function function1($value = null) {
        return $value * 2;
    }

    public function function2($value = null) {
        return $value * 4;
    }
}

class _Mapper {
    function __construct($estimator) {
        // This should store the function that we are going to
        // use based on the value of A & B in _create_couplet()
        $this->estimator = $estimator;
    }

    function estimator($value) {
        // This should pass the value specified to either function1()
        // or function function2() and should return the result.  It
        // doesn't !
        return $this->estimator($value);
    }
}

function _create_couplet($pairing, $A, $B) {
    // Based on the value of A or B store the appropriate function
    if ($A < $B) {
        return (new _Mapper($pairing->function1()));
    } else {
        return (new _Mapper($pairing->function2()));
    }
}

// Set up some values
$oldValue = 10;
$A = 10;
$B = 5;

// Define the pairing
$pairing = new Pairings;

// Create the _Mapper object
$couplet = _create_couplet($pairing, $A, $B);

// Pass oldValue into the appropriate function and get the result back
$newValue = $couplet->estimator($oldValue);
echo ("New value: $newValue");
类配对{
//定义这两个函数(它们只是占位符)
公共函数function1($value=null){
返回$value*2;
}
公共函数function2($value=null){
返回$value*4;
}
}
类映射器{
函数构造($estimator){
//这应该存储我们将要使用的函数
//基于_create_couplet()中A&B的值使用
$this->estimator=$estimator;
}
函数估计器($值){
//这应该将指定的值传递给function1()
//或函数function2(),并应返回结果
//没有!
返回$this->estimator($value);
}
}
函数_创建_对联($pairing,$A,$B){
//根据A或B的值存储适当的函数
如果($A<$B){
返回(新的映射器($pairing->function1());
}否则{
返回(新的映射器($pairing->function2());
}
}
//设置一些值
$oldValue=10;
$A=10;
$B=5;
//定义配对
$pairing=新配对;
//创建_Mapper对象
$couplet=\u创建\u对联($pairing,$A,$B);
//将oldValue传递到适当的函数中并返回结果
$newValue=$couplet->estimator($oldValue);
echo(“新价值:$newValue”);
我肯定我犯了一个简单的错误,但我看不出我错过了什么。如何在对象中存储函数名,然后向其中传递参数,以便存储的函数使用该参数并返回值?

有两个问题:

\u create\u couplet
方法中,您给
new\u Mapper()
的参数不是要执行的函数,而是函数结果。您正在执行
$pairing->function1()
,它执行
null*2
,因为您允许
null
值,否则它应该失败,因为您正在调用
function1
,没有参数

正如Lars建议的,你应该使用一个可调用的参数:

//之前
新的映射器($pairing->function1());
//之后
新的_映射器([$pairing,'function1']);
引发无限循环的第二个问题是,您试图在
estimator
方法中调用此可调用函数,该方法调用
$this->estimator()
。您可能认为
$this->estimator()
引用了
$this->estimator
中包含的可调用项,但由于您有一个同名的方法,PHP会认为您调用的是该方法,而不是属性


修复它的最简单方法是以不同的方式命名方法或属性。

$pairing->function1()这将执行方法<代码>$pairing->function1这指的是。。。在PHP中,您必须有一个“可调用的”。。。这也可以是字符串(用于函数)或数组(用于类方法),如下所示:
[$pairing,'function1']
。编辑:您必须用
call\u user\u func
或类似的方式调用它。谢谢您的回复。call_user_func会去哪里?在Pairings类中?否,在映射器中,当访问配对时(估计器方法)。。。映射器根本不需要知道结对类,只要有一个“可调用”就足够了。请看下面的评论,@Kern解释得很好……感谢您的回复。我已经做了您建议的更改:函数u构造($estimator){$this->estimator=call_user_func($estimator);}函数getEstimate($value){return$this->estimator($value);}并修改了:return(新的_映射器([$pairing,'function1']);返回(新的_映射器([$pairing,'function2']);现在调用:$newValue=$couplet->getEstimate($oldValue);但是它在这里给出了“未捕获错误:调用未定义的方法_Mapper::estimator()”:return$this->estimator($value)是的,调用_user_func()不能在构造函数中,因为如果您编写了它,您将在这里执行可调用的函数。如果要在
getEstimate
方法中执行它,您应该有
函数getEstimate(){return call\u user\u func($this->estimator);}
构造($estimator){$this->estimator=$estimator;}
谢谢。尽管做了这些更改,我仍然得到相同的错误:PHP致命错误:未捕获错误:在返回调用\u user\u func($this->estimator($value))行中调用未定义的方法_Mapper::estimator()。好像没有存储来自_construct()的$this->estimator
call\u user\u func($this->estimator)
,如果您编写
$this->estimator($value)
,PHP将尝试调用
\u Mapper
对象的方法
estimator
,该方法不存在<另一方面,code>$this->estimator是包含可调用的属性。啊,这很有意义。添加$value作为第二个参数可以将其传递到函数:-)非常感谢您的帮助和耐心!
class Pairings {
    // Define the two functions (these are just placeholders)
    public function function1($value = null) {
        return $value * 2;
    }

    public function function2($value = null) {
        return $value * 4;
    }
}

class _Mapper {
    function __construct($estimator) {
        // This should store the function that we are going to
        // use based on the value of A & B in _create_couplet()
        $this->estimator = $estimator;
    }

    function estimator($value) {
        // This should pass the value specified to either function1()
        // or function function2() and should return the result.  It
        // doesn't !
        return $this->estimator($value);
    }
}

function _create_couplet($pairing, $A, $B) {
    // Based on the value of A or B store the appropriate function
    if ($A < $B) {
        return (new _Mapper($pairing->function1()));
    } else {
        return (new _Mapper($pairing->function2()));
    }
}

// Set up some values
$oldValue = 10;
$A = 10;
$B = 5;

// Define the pairing
$pairing = new Pairings;

// Create the _Mapper object
$couplet = _create_couplet($pairing, $A, $B);

// Pass oldValue into the appropriate function and get the result back
$newValue = $couplet->estimator($oldValue);
echo ("New value: $newValue");