我可以在 Laravel 中集成自定义 PDO 包装器吗
Can I integrate a custom PDO wrapper in Laravel
我和我的同事正在尝试使用 Laravel 和 Vertica 数据库开发 Web 应用程序。唯一的问题是,一旦您对这个特定的数据库使用 bindValue 或 bindParam,PHP 就会因分段错误而崩溃。所以我写了一个 PDO 包装器 class 将调用重定向到 PHP_ODBC 模块并且它确实有效。我现在想知道如何将它集成到 Laravel 中,如果这样的事情是可能的话。
好吧,经过大量的尝试和错误,我和我的同事设法解决了问题 运行。最耗时的部分原来是构建包装器。假设你有,下面是将它集成到 Laravel 中所需要做的事情(顺便说一下,这些步骤是针对 Laravel 5.1 的)。另外,我的包装器名为 PDOVertica,所以无论何时您看到这个术语,都必须用它替换您自己的包装器的名称。
1) 将包装文件复制到以下文件夹:
vendor/laravel/framework/src/Illuminate/Database/Connectors
2) 接下来,您需要修改几个文件:
vendor\laravel\framework\src\Illuminate\Database\Connection.php
namespace Illuminate\Database;
use PDO;
use PDOVertica; //Add this line
use Closure;
use DateTime;
...
//Change the type of the first parameter to PDOVertica as follow
public function __construct(PDOVertica $pdo, $database = '', $tablePrefix = '', array $config = [])
vendor\laravel\framework\src\Illuminate\Database\Connectors\Connector.php
namespace Illuminate\Database\Connectors;
include 'clsPDOVertica.php'; //Add this line
use PDO;
use PDOVertica; //Add this line
...
public function createConnection($dsn, array $config, array $options)
{
$username = array_get($config, 'username');
$password = array_get($config, 'password');
//Modify the return value to return your wrapper
return new PDOVertica($dsn, $username, $password, $options);
}
vendor\laravel\framework\src\Illuminate\Database\Connectors\PostgresConnector.php
protected function getDsn(array $config)
{
extract($config);
$host = isset($host) ? "Server={$host};" : '';
// Modify this line so that it creates the Vertica DSN.
// It should look something like this.
$dsn = "Driver=/opt/vertica/lib64/libverticaodbc.so;{$host}Database={$database}";
if (isset($config['port'])) {
$dsn .= ";port={$port}";
}
if (isset($config['sslmode'])) {
$dsn .= ";sslmode={$sslmode}";
}
return $dsn;
}
vendor\laravel\framework\src\Illuminate\Database\Connectors\ConnectionFactory.php
namespace Illuminate\Database\Connectors;
use PDO;
use PDOVertica; //Add this line
use InvalidArgumentException;
...
// Modify the header of this function so that the $connection parameter
// is of type PDOVertica
protected function createConnection($driver, PDOVertica $connection, $database, $prefix = '', array $config = [])
{
if ($this->container->bound($key = "db.connection.{$driver}")) {
return $this->container->make($key, [$connection, $database, $prefix, $config]);
}
switch ($driver) {
case 'mysql':
return new MySqlConnection($connection, $database, $prefix, $config);
case 'pgsql':
return new PostgresConnection($connection, $database, $prefix, $config);
case 'sqlite':
return new SQLiteConnection($connection, $database, $prefix, $config);
case 'sqlsrv':
return new SqlServerConnection($connection, $database, $prefix, $config);
}
throw new InvalidArgumentException("Unsupported driver [$driver]");
}
3) 正确修改文件后,您所要做的就是通过修改以下文件正确配置 Laravel 以使用您的自定义连接:
config/database.php
/* |--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => 'vertica',
...
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => storage_path('database.sqlite'),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', ''),
'database' => env('DB_DATABASE', ''),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'port' => '5433h',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
//This is our custom connection
'vertica' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '192.168.1.1'),
'database' => env('DB_DATABASE', 'mydb'),
'username' => env('DB_USERNAME', 'myuser'),
'password' => env('DB_PASSWORD', 'mypassword'),
'port' => '5433',
'charset' => 'utf8',
'schema' => 'myschema',
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'port' => '5433',
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'prefix' => '',
],
],
据我所知,这就是 Laravel 连接到 Vertica 数据库而不会崩溃所需的所有步骤。希望对您有所帮助。
您可以使用我编写的 Laravel-ready PDO 连接器:
composer require mixartemev/dbal-vertica-driver
我和我的同事正在尝试使用 Laravel 和 Vertica 数据库开发 Web 应用程序。唯一的问题是,一旦您对这个特定的数据库使用 bindValue 或 bindParam,PHP 就会因分段错误而崩溃。所以我写了一个 PDO 包装器 class 将调用重定向到 PHP_ODBC 模块并且它确实有效。我现在想知道如何将它集成到 Laravel 中,如果这样的事情是可能的话。
好吧,经过大量的尝试和错误,我和我的同事设法解决了问题 运行。最耗时的部分原来是构建包装器。假设你有,下面是将它集成到 Laravel 中所需要做的事情(顺便说一下,这些步骤是针对 Laravel 5.1 的)。另外,我的包装器名为 PDOVertica,所以无论何时您看到这个术语,都必须用它替换您自己的包装器的名称。
1) 将包装文件复制到以下文件夹:
vendor/laravel/framework/src/Illuminate/Database/Connectors
2) 接下来,您需要修改几个文件:
vendor\laravel\framework\src\Illuminate\Database\Connection.php
namespace Illuminate\Database;
use PDO;
use PDOVertica; //Add this line
use Closure;
use DateTime;
...
//Change the type of the first parameter to PDOVertica as follow
public function __construct(PDOVertica $pdo, $database = '', $tablePrefix = '', array $config = [])
vendor\laravel\framework\src\Illuminate\Database\Connectors\Connector.php
namespace Illuminate\Database\Connectors;
include 'clsPDOVertica.php'; //Add this line
use PDO;
use PDOVertica; //Add this line
...
public function createConnection($dsn, array $config, array $options)
{
$username = array_get($config, 'username');
$password = array_get($config, 'password');
//Modify the return value to return your wrapper
return new PDOVertica($dsn, $username, $password, $options);
}
vendor\laravel\framework\src\Illuminate\Database\Connectors\PostgresConnector.php
protected function getDsn(array $config)
{
extract($config);
$host = isset($host) ? "Server={$host};" : '';
// Modify this line so that it creates the Vertica DSN.
// It should look something like this.
$dsn = "Driver=/opt/vertica/lib64/libverticaodbc.so;{$host}Database={$database}";
if (isset($config['port'])) {
$dsn .= ";port={$port}";
}
if (isset($config['sslmode'])) {
$dsn .= ";sslmode={$sslmode}";
}
return $dsn;
}
vendor\laravel\framework\src\Illuminate\Database\Connectors\ConnectionFactory.php
namespace Illuminate\Database\Connectors;
use PDO;
use PDOVertica; //Add this line
use InvalidArgumentException;
...
// Modify the header of this function so that the $connection parameter
// is of type PDOVertica
protected function createConnection($driver, PDOVertica $connection, $database, $prefix = '', array $config = [])
{
if ($this->container->bound($key = "db.connection.{$driver}")) {
return $this->container->make($key, [$connection, $database, $prefix, $config]);
}
switch ($driver) {
case 'mysql':
return new MySqlConnection($connection, $database, $prefix, $config);
case 'pgsql':
return new PostgresConnection($connection, $database, $prefix, $config);
case 'sqlite':
return new SQLiteConnection($connection, $database, $prefix, $config);
case 'sqlsrv':
return new SqlServerConnection($connection, $database, $prefix, $config);
}
throw new InvalidArgumentException("Unsupported driver [$driver]");
}
3) 正确修改文件后,您所要做的就是通过修改以下文件正确配置 Laravel 以使用您的自定义连接:
config/database.php
/* |--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => 'vertica',
...
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => storage_path('database.sqlite'),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', ''),
'database' => env('DB_DATABASE', ''),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'port' => '5433h',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
//This is our custom connection
'vertica' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '192.168.1.1'),
'database' => env('DB_DATABASE', 'mydb'),
'username' => env('DB_USERNAME', 'myuser'),
'password' => env('DB_PASSWORD', 'mypassword'),
'port' => '5433',
'charset' => 'utf8',
'schema' => 'myschema',
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'port' => '5433',
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'prefix' => '',
],
],
据我所知,这就是 Laravel 连接到 Vertica 数据库而不会崩溃所需的所有步骤。希望对您有所帮助。
您可以使用我编写的 Laravel-ready PDO 连接器:
composer require mixartemev/dbal-vertica-driver