Laravel扩展供应商类

7

我尝试扩展一个Illuminate Class Translator

我创建了一个类并扩展到翻译器 然后我在我的RepositoryServiceProvider中添加了这行代码

$this->app->bind(\Illuminate\Translation\Translator::class, \App\Repositories\Translation\TranslationTranslator::class);

但它没有起作用

我做错了什么?

类如下

<?php

namespace App\Repositories\Translation;

use Countable;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Support\NamespacedItemResolver;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\TranslatorInterface;


class TranslationTranslator extends \Illuminate\Translation\Translator
{
    /**
     * Parse a key into namespace, group, and item.
     *
     * @param  string  $key
     * @return array
     */
    public function parseKey($key)
    {
        \Log::info('got in');
        die;
        $segments = parent::parseKey($key);

        if (is_null($segments[0])) {
            $segments[0] = @explode('.', $segments[2])[0];
        }
        if ($segments[1] == 'translatable') {
            $segments[1] = @explode('.', $segments[2])[0] . '_' . @explode('.', $segments[2])[1];
        }
        return $segments;
    }
}

更新

显然,翻译器类有一个构造函数。

 public function __construct(LoaderInterface $loader, $locale)
    {
        $this->loader = $loader;
        $this->locale = $locale;
    }

所以我的绑定必须通过接口传递..而接口是无法实例化的。
 public function boot()
{
    $app = $this->app;
    $this->app->bind(\Illuminate\Translation\Translator::class, function() use ($app){
        return $app->make(\App\Repositories\Translation\TranslationTranslator::class);
    });        
}

并且出现了以下错误

Illuminate\Contracts\Container\BindingResolutionException 错误信息为 '在构建 [App\Repositories\Translation\TranslationTranslator] 时,目标 [Illuminate\Translation\LoaderInterface] 无法实例化。'


你能提供一下你想要覆盖的类所在的包吗?这样我就可以检查并帮助你解决问题了。 - Lakhwinder Singh
Illuminate\Translation\Translator;public function parseKey() - Garine Pondikian
请分享Composer包的URL或名称,以便我进行检查。不是类命名空间 :) - Lakhwinder Singh
https://laravel.com/api/5.3/Illuminate/Translation/Translator.htmlhttps://github.com/laravel/framework/blob/5.2/src/Illuminate/Translation/Translator.php - Garine Pondikian
4个回答

4

你可以使用闭包来解决类的问题

$this->app->bind(\Illuminate\Translation\Translator::class, function(){

    return new \App\Repositories\Translation\TranslationTranslator;
});

其次,翻译器与Laravel绑定在一起使用translator别名。

您也可以覆盖它。

$this->app->bind('translator', function(){
        return new \App\Repositories\Translation\TranslationTranslator; 
    })

2
这对我有用
$app = $this->app;
$loader = $app['translation.loader'];
$locale = $app['config']['app.locale'];

$this->app->bind('translator', function() use ($loader, $locale){
    return new \App\Repositories\Translation\TranslationTranslator($loader, $locale);
});

希望这能帮到你


0

尝试将它改为这样:

$this->app->instance(\Illuminate\Translation\Translator::class, \App\Repositories\Translation\TranslationTranslator::class);

这样应该会改变接口的实例。

更新

如果你只是想添加一个新方法,Translator类是可扩展的。所以你可以这样做:

Translator::macro('parseKey', function ($key) {
    \Log::info('got in');
    die;
    $segments = parent::parseKey($key);

    if (is_null($segments[0])) {
        $segments[0] = @explode('.', $segments[2])[0];
    }
    if ($segments[1] == 'translatable') {
        $segments[1] = @explode('.', $segments[2])[0] . '_' . @explode('.', $segments[2])[1];
    }
    return $segments;
});

然后您就可以像平常一样调用您的方法。例如:

app(Translator::class)->parseKey($key);

这个好像没起作用.. 我需要清除缓存或者做些什么吗? - Garine Pondikian
你的服务提供者是否已在 app.php 文件中注册,并且你是否将此调用放置在 boot 方法中? - George Hanson

0

请查看下面的示例

namespace App\Repositories\Translation;

use Illuminate\Translation\Translator;
class TranslationTranslator extends Translator
{

    public function get()
    {
        ....
    }
}

无需做任何事情。您只需要添加新功能或覆盖基类函数。然后,您就可以像使用其他简单类一样使用此类。


你能解释一下需要做什么吗?Laravel应该如何知道那个被覆盖的类? - Nico Haase
@NicoHaase Laravel自动加载app目录下的所有类。因此,您无需加载此文件。关于覆盖。我们通过使用Vendor包类来扩展它。通过这种方式,我们可以在新文件中覆盖或添加新函数。 - Lakhwinder Singh
@GarinePondikian,你能分享一下TranslationTranslator类的代码吗?我认为你做错了什么,因为parseKey()函数需要一个参数。 - Lakhwinder Singh
@GarinePondikian 还有一件事,为了最佳实践,namespace 应该在文件顶部 use 语句的上面。 - Lakhwinder Singh
1
@LuckySaini 我认为另一个绑定正在运行时覆盖我的绑定...我已经尝试了以上所有方法,但都没有起作用。 - Garine Pondikian
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接