我在 Laravel 5.2 中工作,我正试图让它与 Vertica 一起工作。几个月前,我和我的同事提出了这个解决方案,但我们现在正试图让事情变得不那么笨拙,并使用服务提供商来使事情工作,这样我们实际上可以更轻松地升级 Laravel。所以到目前为止我们所做的是:
1) 创建两个新类来扩展它们的对应类:
新的 BaseConnector:
namespace App\Vertica;
include 'clsPDOVertica.php';
use Illuminate\Support\Arr;
use \Illuminate\Database\Connectors\Connector as BaseConnector;
class Connector extends BaseConnector
{
/**
* Create a new PDO connection.
*
* @param string $dsn
* @param array $config
* @param array $options
* @return \PDO
*/
public function createConnection($dsn, array $config, array $options)
{
$username = Arr::get($config, 'username');
$password = Arr::get($config, 'password');
return new PDOVertica($dsn, $username, $password, $options);
}
}
Run Code Online (Sandbox Code Playgroud)
新的 PostgresConnector:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我们试图定义一个服务提供者来告诉 Laravel 使用我们的类而不是默认的类……但到目前为止还没有成功。这是提供程序的代码:
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();
});
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我们的 VerticaServiceProvider 的 register 方法被调用了,但很明显,内部的绑定是错误的,因为我们的类没有被调用。任何人都知道我们做错了什么?
Laravel 不会解析Connector容器中的类,因此尝试通过类名覆盖连接器是行不通的。
您可以查看Illuminate/Database/Connectors/ConnectionFactory::createConnector连接器是如何解析的。Laravel 只是做了一个return new PostgresConnector(或适合驱动程序的任何一个),所以它不会在容器中查找类名。
但是,在它“新建”之前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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1810 次 |
| 最近记录: |