【问题标题】:Object of class Closure could not be converted to string in: filename.类 Closure 的对象无法在文件名中转换为字符串。
【发布时间】:2013-02-28 15:57:55
【问题描述】:
function convert($currencyType)
{
    $that = $this;
    return $result = function () use ($that) 
    {
        if (!in_array($currencyType, $this->ratio))
                return false;

        return ($this->ratio[$currencyType] * $this->money); //a float number
    };
}

$currency = new Currency();
echo $currency->convert('EURO');

怎么了?

我收到错误消息:

Catchable fatal error: Object of class Closure could not be converted to string

【问题讨论】:

  • 您的convert() 函数返回一个函数。然后你试图通过echo()ing 将它强制转换成一个字符串。
  • 但是闭包返回一个float/false给$result?
  • 而你在闭包中的$this 引用应该是$that。他们可能在 5.4 的思想中改变了这一点;不确定。
  • 您实际上必须调用生成的闭包来获取浮动。你为什么在这里使用闭包?
  • 啊。让我给你一个正式的答案……

标签: php


【解决方案1】:

几个问题:

  1. 因为要返回一个闭包,所以必须先将闭包赋给一个变量,然后调用函数
  2. 您的 $this 引用在闭包内不起作用(这就是为什么您改为 useing $that
  3. 您还需要使用$currencyType 在闭包的范围内访问它

function convert($currencyType)
{
    $that =& $this; // Assign by reference here!
    return $result = function () use ($that, $currencyType) // Don't forget to actually use $that
    {
        if (!in_array($currencyType, $that->ratio))
                return false;

        return ($that->ratio[$currencyType] * $that->money); //a float number
    };
}

$currency = new Currency();
$convert = $currency->convert('EURO');
echo $convert(); // You're not actually calling the closure until here!

【讨论】:

  • 一个问题,不过。为什么 if (!in_array($currencyType, $that->ratio)) 返回 false;总是返回假? $currencyType = 'EURO' 和 print_r($that->ratio) 正确输出数组。
【解决方案2】:

你必须在括号之间创建函数,并在关闭函数时添加括号。

function convert($currencyType)
{
    $that = $this;
    return $result = (function () use ($that) 
    {
        if (!in_array($currencyType, $this->ratio))
                return false;

        return ($this->ratio[$currencyType] * $this->money); //a float number
    })();
}

$currency = new Currency();
echo $currency->convert('EURO');

【讨论】:

    【解决方案3】:

    只需删除那里的return 并执行以下操作:

    $result = function () use ($that) 
    {
        if (!in_array($currencyType, $this->ratio))
                return false;
    
        return ($this->ratio[$currencyType] * $this->money); //a float number
    };
    return $result();
    

    另外,您是否意识到您没有在函数中使用$that

    顺便问一下,你为什么需要一个匿名函数呢?做吧:

    function convert($currencyType)
    {
        if (!in_array($currencyType, $this->ratio))
            return false;
    
        return ($this->ratio[$currencyType] * $this->money); //a float number
    }
    

    【讨论】:

    • 我正在尝试使用闭包来实现。我知道这没有必要,因为我自己可以在没有闭包的情况下做到这一点。我只是想将闭包用于学习目的。
    • @LisaMiskovsky,闭包可以存储在变量中。因此$var = function() {...} 将该函数存储在一个变量中。这不是使用匿名函数的地方。不要从一开始就学坏东西。当您需要关闭时,您会知道如何使用它们。
    • 你能给我举个例子,它是一个使用闭包的好地方吗?
    • @LisaMiskovsky Just take a look at here.
    • 我希望能够使用类似于 Ruby 中的块的闭包,例如而不是说 if($that=='foo') $this='bar'; elseif($that=='dee') $this='dum'; 写成:$this = function() { if($that=='foo') return 'bar'; elseif($that=='dee') return 'dum'; } 除了它远不如 Ruby 简洁:ruby this = { if that='foo' then 'bar' elsif that='dee' then 'dum' }
    【解决方案4】:
    class Currency {
        function convert($currencyType)
        {
            if (!in_array($currencyType, $this->ratio))
                 return false;
            return ($this->ratio[$currencyType] * $this->money); //a float number
        }
    }
    
    $currency = new Currency();
    echo $currency->convert('EURO');
    

    您正在定义一个 lambda 函数。你不需要它。此外,如果要获得任何准确性,您应该使用bcmul(); PHP 中的浮点数会给你带来时髦的结果。

    【讨论】:

      猜你喜欢
      • 2013-08-22
      • 2018-03-12
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 2015-07-27
      • 2012-04-29
      相关资源
      最近更新 更多