PHP / Laravel - 无法启动抽象类的扩展

I'm quite new to using abstract classes and interfaces in PHP.

I'm trying to initiate a extend of an abstract class, but it won't work. It might be a Laravel specific issue i'm having.

This is the case:

  • I have an interface
  • I have an abstract class that implements the interface
  • I have 'regular' class that extends the abstract class
  • I try to implement the class

This is the interface:

<?php namespace Collection\Services\Validation;

interface SomeInterface {


    public function with(array $input);

    public function passes();

    public function errors();

}

This is the abstract class:

<?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;
    }


}

This is the "regular" class:

<?php namespace Collection\Services\Validation;


class SomeClassExtender extends SomeClass {


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


}

This is the implementation:

<?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;
    }

And then i get this error:

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

If i remove the initiation of the Factory class, the error is gone. The Factory class is also just a regular class.

What am i doing wrong here?

I see that you're following Chris Fidao's book. Got the same error as you are.

This is my solution, put this inside global.php

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

EDIT:

I think the problem with Factory is that you need to bind the translator interface to $app['translator']. Here's what I found...

If you look at the Factory class, it requires the translator interface -- A quick look into its public __construct in the API:

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

Then if you look at the public function register() in ValidationServiceProvider, you'll find that Laravel binds the TranslatorInterface to $app['translator']:

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

Then seems like a service provider to bind $app['translator'] is needed, or we can just bind it in global.php.

I think this is the best working solution, found the same exact problem . Solved it by, injecting the already bound "validator" object in the Validator facade.

<?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'; }

}

Instantiate the Factory class with App::make('validator')

Do it this way,when instantiating your SomeClassExtender class.

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

This article by @PhilipBrown Advanced Validation as a Service for Laravel 4 - http://culttt.com/2014/01/13/advanced-validation-service-laravel-4/