Php 为什么对象的实例不是来自我的扩展类,而是来自Laravel4.2中的原始类?

Php 为什么对象的实例不是来自我的扩展类,而是来自Laravel4.2中的原始类?,php,laravel,Php,Laravel,在Laravel4.2项目中,我正在使用MathiasVerraes的Money()库。我将其包含在composer.json文件的“require”部分,如下所示: "require": { "laravel/framework": "4.2", "mathiasverraes/money": "1.2.1", 一切正常,现在我想重写Money类中的1个函数(名为“stringToUnits”)。我所做的: 1) 我创建了一个app/lib/Proje

在Laravel4.2项目中,我正在使用MathiasVerraes的Money()库。我将其包含在composer.json文件的“require”部分,如下所示:

    "require": {
        "laravel/framework": "4.2",
        "mathiasverraes/money": "1.2.1",
一切正常,现在我想重写Money类中的1个函数(名为“stringToUnits”)。我所做的:

1) 我创建了一个app/lib/Projectname/Extensions/Money.php文件来保存该函数

<?php namespace Projectname\Extensions;

use Money\Money as OriginalMoney;

class Money extends OriginalMoney {

    public static function stringToUnits($string)
    {
        ...my version...            
    }

}
所以我很困惑:为什么我创建的Money对象是原始\Money\Money的实例,而不是来自我的扩展类\Projectname\Extensions\Money?
我想我是在告诉拉威尔“用项目名称\扩展\金钱作为金钱;”?

问题是:

$amount_paid = Money::EUR(Money::stringToUnits($payment_data['amount_due_in_document_currency']));
从外观上看,原始父类方法将返回其自身的新实例。扩展类没有
EUR
方法,因此它会冒泡到父类,父类返回一个
Money\Money
实例

$difference = $amount_paid->subtract($amount_to_pay);
此时,
$difference
不再作用于扩展类。它作用于
EUR
调用返回的原始
Money\Money
实例。您可以通过转储
$amount\u paid
变量的结果,或者使用IDE的内置调试器并查看特定断点处的内容来确认这一点

可以通过删除第三个参数上的typehint来删除错误。如果您希望保留它,则需要使用以下内容覆盖父级的
callStatic
方法:

<?php namespace Projectname\Services\Payment;

use Projectname\Extensions\Money as Money;

class EloquentPaymentService implements PaymentServiceInterface {

    private function compareAmountsInAccountsPayable($accountsPayable, array $payment_data) {   

        $amount_to_pay = Money::EUR(Money::stringToUnits($accountsPayable->amount_due_in_document_currency));
        $amount_paid   = Money::EUR(Money::stringToUnits($payment_data['amount_due_in_document_currency']));

        $difference = $amount_paid->subtract($amount_to_pay);

        if( $difference->isNegative() ) {

            return $this->clearAccountsPayableWithNegativeDifference($accountsPayable, $payment_data, $difference);         
        }

    }


    private function clearAccountsPayableWithNegativeDifference($accountsPayable, array $payment_data, Money $difference) {
        ...
    }

}
namespace Projectname\Extensions;

use Money\Money as OriginalMoney;
use Money\Currency;

class Money extends OriginalMoney {

    public static function stringToUnits($string)
    {
        ...my version...            
    }
    public static function __callStatic($method, $arguments)
    {
        return new Money($arguments[0], new Currency($method));
    }
}

该代码未经测试,因此我不能保证它会立即运行。但这至少应该为您指明了正确的方向。

谢谢maiorano84,我认为您走在了正确的道路上。我可以通过转储来确认$amount\u paid变量作用于原始Money\Money对象。是的,我可以通过消除Money类型提示来确认错误已被删除。不过:我还是想保留这笔钱。所以我尝试了你的建议来覆盖callStatic方法。现在$amount_支付的金额作用于扩展类(是的!),但$difference不起作用。所以也许我也应该将“subtract”方法复制到扩展类中,我会尝试一下,并让您知道。正确,应该可以。你可以看到,一个新的例子的钱也被退回那里,这是我错过了。在扩展类中重写它应该可以纠正这个特定用例的问题。我在扩展类中添加了原始Money类中subtract方法的副本(“public function subtract(Money$subtrahand)”,Laravel给了我一个错误:Projectname\Extensions\Money::subtract()的声明应与Money\Money::subtract(Money\Money$subtrahand)兼容。请注意,错误消息没有拾取扩展类版本中的参数定义。有什么建议吗?嗯……在扩展类中,尝试键入使用
OriginalMoney
处理它的减法方法。结果是:调用私有方法Money\Money::assertSameCurrency()从上下文“Projectname\Extensions\Money”。因此,沿着这条路走下去,我将复制此用例所需的所有方法,并根据需要进行调整。也许有更好的解决方案,但同时您确实回答了我最初的问题,谢谢!
namespace Projectname\Extensions;

use Money\Money as OriginalMoney;
use Money\Currency;

class Money extends OriginalMoney {

    public static function stringToUnits($string)
    {
        ...my version...            
    }
    public static function __callStatic($method, $arguments)
    {
        return new Money($arguments[0], new Currency($method));
    }
}