使用Laravel服务提供程序覆盖连接器类

时间:2017-03-03 15:59:19

标签: php laravel

我在Laravel 5.2工作,我正在尝试使用Vertica。几个月前,我的同事和我提出了this解决方案,但我们现在正试图让事情变得不那么苛刻,并且使用服务提供商来使事情变得有效,这样我们就可以更轻松地升级Laravel。所以到目前为止我们所做的是:

1)创建两个扩展其对应项的新类:

New BaseConnector:

namespace App\Vertica;

use \Illuminate\Database\Connectors\PostgresConnector as BasePostgresConnector;

class PostgresConnector extends BasePostgresConnector
{

    /**
     * Create a DSN string from a configuration.
     *
     * @param  array   $config
     * @return string
     */
    protected function getDsn(array $config)
    {
        // First we will create the basic DSN setup as well as the port if it is in
        // in the configuration options. This will give us the basic DSN we will
        // need to establish the PDO connections and return them back for use.
        extract($config, EXTR_SKIP);

        $host = isset($host) ? "host={$host};" : '';

        $dsn = "Driver={$driverpath};{$host}Database={$database}";

        // If a port was specified, we will add it to this Postgres DSN connections
        // format. Once we have done that we are ready to return this connection
        // string back out for usage, as this has been fully constructed here.
        if (isset($config['port'])) {
            $dsn .= ";port={$port}";
        }

        if (isset($config['sslmode'])) {
            $dsn .= ";sslmode={$sslmode}";
        }

        return $dsn;
    }
}

New PostgresConnector:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class VerticaServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        // dd(new \Illuminate\Database\Connectors\PostgresConnector);
        $this->app->singleton('\Illuminate\Database\Connectors\Connector', function()
        {
            return new \App\Vertica\Connector();
        });

        $this->app->singleton('\Illuminate\Database\Connectors\PostgresConnector', function()
        {
            return new \App\Vertica\PostgresConnector();
        });
    }
}

现在,我们正在尝试定义一个服务提供者,实质上告诉Laravel使用我们的类而不是默认类......但到目前为止还没有成功。这是提供者的代码:

=AGGREGATE(14,6,$B$2:$D$4/(COUNTIF($E$2:E2,$B$2:$D$4)=0),1)

到目前为止,VerticaServiceProvider的register方法被调用,但很明显,内部绑定是错误的,因为我们的类没有被调用。任何人都知道我们做错了什么?

2 个答案:

答案 0 :(得分:4)

Laravel无法解析容器中的Connector类,因此尝试按类名覆盖连接器将不起作用。

您可以在Illuminate/Database/Connectors/ConnectionFactory::createConnector中看到如何解析连接器。 Laravel只执行return new PostgresConnector(或适用于驱动程序的任何一个),因此它不会在容器中查找类名。

然而,在它" new" s Connector之前,它会检查容器以查看是否有使用字符串'db.connector.[driver]'绑定到驱动程序的连接器,其中[driver]是数据库驱动程序名称。

因此,您需要绑定字符串'db.connector.your-driver-name',而不是尝试绑定容器中的类名。因此,如果您创建了自己的自定义驱动程序(例如vertica),则会将连接器绑定到'db.connector.vertica'。或者,如果要覆盖内置的postgres连接器,则可以将连接器绑定到'db.connector.pgsql'

根据您尝试覆盖postgres连接器的假设,您的服务提供商注册方法如下所示:

public function register()
{
    $this->app->bind('db.connector.pgsql', \App\Vertica\PostgresConnector::class);
}

答案 1 :(得分:0)

我无法通过PostgresConnector连接器将Illumitane查询生成器与Vertica完全值配合使用。 这就是为什么我要制作支持laravel的VerticaConnector,并通过1条命令进行安装的原因:

composer require mixartemev/dbal-vertica-driver