【问题标题】:PHP: Can I store a function in a class object and pass values to it for the function to interpret. Python can do it, but can PHP?PHP:我可以将函数存储在类对象中并将值传递给它以供函数解释。 Python可以做到,但是PHP可以吗?
【发布时间】:2020-11-29 11:36:59
【问题描述】:

我很难弄清楚如何实现类似于以下 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 对象数组,每个对象都包含一个对稍后用于计算值的函数(函数 1 或函数 2)的引用。关键步骤似乎是:

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");

我确信我犯了一个简单的错误,但我看不出我错过了什么。如何将函数名称存储在对象中,然后将参数传递给它,以便存储的函数使用该参数并返回一个值?

【问题讨论】:

  • $pairing-&gt;function1() this 执行方法...$pairing-&gt;function1 this 指的是方法...在 PHP 中你必须有一个“Callable”...这也可以是一个字符串(用于函数)或数组(用于类方法),如下所示:[$pairing, 'function1']。编辑:您必须使用 call_user_func 或类似名称来调用它
  • 感谢您的回复。 call_user_func 会去哪里?在配对类中?
  • 不,在 Mapper 中,当访问 Pairing 时(估计方法)... Mapper 根本不需要知道 Pairing 类,有一个“Callable”就足够了。请参阅下面的评论,@Kern 解释得很好......

标签: python php class


【解决方案1】:

有两个问题:

在您的_create_couplet 方法中,您提供给new _Mapper() 的参数不是要执行的函数,而是函数结果。您正在执行$pairing-&gt;function1(),它执行null * 2,因为您允许null 值,否则它应该失败,因为您在没有参数的情况下调用function1

按照 Lars 的建议,您应该使用可调用参数:

//before
new _Mapper($pairing->function1());

//after
new _Mapper([$pairing, 'function1']);

引发无限循环的第二个问题是您尝试在 estimator 方法中调用此可调用对象,该方法正在调用 $this-&gt;estimator()。你可能认为$this-&gt;estimator() 指的是$this-&gt;estimator 中包含的可调用对象,但由于你有一个同名的方法,PHP 会认为你调用的是方法而不是属性。

修复它的最简单方法是对方法或属性进行不同的命名。

【讨论】:

  • 感谢您的回复。我已经按照您的建议进行了更改: function __construct($estimator) { $this->estimator = call_user_func($estimator); } function getEstimate($value) { return $this->estimator($value);并修改:return (new _Mapper([$pairing, 'function1'])); return (new _Mapper([$pairing, 'function2']));现在被调用:$newValue = $couplet->getEstimate($oldValue);但它在这里给出“未捕获的错误:调用未定义的方法_Mapper::estimator()”:return $this->estimator($value)
  • 是的,call_user_func() 不能在构造函数中,因为如果你写的话,你会在这里执行 callable。你想在getEstimate方法中执行它,你应该有function getEstimate() { return call_user_func($this-&gt;estimator); }__construct($estimator) { $this-&gt;estimator = $estimator; }
  • 谢谢。尽管进行了这些更改,但我仍然收到相同的错误:PHP 致命错误:未捕获的错误:在 return call_user_func($this->estimator($value)) 行中调用未定义的方法 _Mapper::estimator()。就好像 _construct() 中的 $this->estimator 没有被存储
  • call_user_func($this-&gt;estimator);,如果你写$this-&gt;estimator($value),PHP会尝试调用不存在的_Mapper对象的estimator方法!另一方面,$this-&gt;estimator 是包含您的可调用对象的属性。
  • 啊,有道理。添加 $value 作为第二个参数允许我将其传递给函数 :-) 非常感谢您的帮助和耐心!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-17
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多