【问题标题】:PHP/Laravel - Can't initiate extend of abstract classPHP/Laravel - 无法启动抽象类的扩展
【发布时间】:2013-12-07 03:58:30
【问题描述】:

我对在 PHP 中使用抽象类和接口非常陌生。

我正在尝试启动抽象类的扩展,但它不起作用。这可能是我遇到的 Laravel 特定问题。

是这样的:

  • 我有一个界面
  • 我有一个实现接口的抽象类
  • 我有扩展抽象类的“常规”类
  • 我尝试实现类

这是界面:

<?php namespace Collection\Services\Validation;

interface SomeInterface {


    public function with(array $input);

    public function passes();

    public function errors();

}

这是抽象类:

<?php namespace Collection\Services\Validation;

use Illuminate\Validation\Factory;

abstract class SomeClass implements SomeInterface {


    protected $validator;
    protected $data = array();
    protected $errors = array();
    protected $rules = array();


    public function __construct(Factory $validator)
    {
        $this->validator = $validator;
    }

    public function with(array $data)
    {
        $this->data = $data;

        return $this;
    }

    public function passes()
    {
        $validator = $this->validator->make($this->data, $this->rules);

        if( $validator->fails() )
        {
            $this->errors = $validator->messages();
            return false;
        }

        return true;
    }

    public function errors()
    {
        return $this->errors;
    }


}

这是“常规”类:

<?php namespace Collection\Services\Validation;


class SomeClassExtender extends SomeClass {


    public function sayBye()
    {
        return 'bye';
    }


}

这是实现:

<?php

use Collection\Services\Validation\PageFormValidator;
use Collection\Services\Validation\SomeClassExtender;


class PagesController extends BaseController {


    protected $someClass;


    public function __construct(SomeClassExtender $class)
    {
        $this->someClass = $class;
    }

然后我得到这个错误:

Illuminate \ Container \ BindingResolutionException
Target [Symfony\Component\Translation\TranslatorInterface] is not instantiable.

如果我删除工厂类的启动,错误就消失了。 Factory 类也只是一个普通类。

我在这里做错了什么?

【问题讨论】:

  • 该错误与您显示的代码无关
  • 错误与哪里有关?去“工厂”班?
  • Target [Symfony\Component\Translation\TranslatorInterface] is not instantiable.
  • 现在通过使用 \Validator::make();在 SomeClass 中,而不是注入 Factory。
  • 我认为该错误确实与 Factory 类有关,因为 Factory 试图在其公共 __construct 中实例化 Symfony\Component\Translation\TranslatorInterface

标签: php oop interface laravel-4 abstract-class


【解决方案1】:

我认为这是最好的解决方案,发现了同样的问题。解决了它, 在 Validator 外观中注入已经绑定的“validator”对象。

<?php namespace Illuminate\Support\Facades;

/**
 * @see \Illuminate\Validation\Factory
 */
class Validator extends Facade {

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'validator'; }

}

使用App::make('validator') 实例化工厂类

在实例化您的 SomeClassExtender 类时这样做。

$someClassExtender = new SomeClassExtender( App::make('validator') );

这篇文章由@PhilipBrown 撰写,Laravel 4 的高级验证即服务 - http://culttt.com/2014/01/13/advanced-validation-service-laravel-4/

【讨论】:

    【解决方案2】:

    我看到您正在关注 Chris Fidao 的书。遇到和你一样的错误。

    这是我的解决方案,把它放在 global.php 中

    App::bind('Symfony\Component\Translation\TranslatorInterface', function($app) {
       return $app['translator']; 
    });
    

    编辑:

    我认为 Factory 的问题在于您需要将翻译器接口绑定到 $app['translator']。这是我发现的...

    如果您查看 Factory 类,它需要翻译器接口——快速查看其 API 中的公共 __construct:

    public function __construct(TranslatorInterface $translator, Container $container = null)
    {
        $this->container = $container;
        $this->translator = $translator;
    }
    

    那么如果你查看ValidationServiceProvider中的公共函数register(),你会发现Laravel将TranslatorInterface绑定到$app['translator']:

    $validator = new Factory($app['translator'], $app);
    

    那么好像需要一个服务提供者来绑定$app['translator'],或者我们可以直接在global.php中绑定。

    【讨论】:

    猜你喜欢
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多