Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
832 views
in Technique[技术] by (71.8m points)

php - Can I integrate a custom PDO wrapper in Laravel

My fellows at work and I are trying to develop a web application using Laravel with a Vertica database. The only problem is that as soon as you use bindValue or bindParam with this specific database, PHP crashes with a segmentation fault. So I've written a PDO wrapper class that redirects calls to the PHP_ODBC module and that actually works. I was now wondering how to integrate it in Laravel if such a thing is even possible.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Okay so after a lot of trial and error, my co-workers and I managed to get things up and running. The most time-consuming part turned out to build the wrapper. Assuming you have that, here's what you need to do to integrate it in Laravel (these steps are for Laravel 5.1 by the way). Also, my wrapper's called PDOVertica so whenever you see this term, you have to substitute it for the name of your own wrapper.

1) Copy your wrapper file to the following folder:

vendor/laravel/framework/src/Illuminate/Database/Connectors

2) Next, you need to modify a couple of files:

vendorlaravelframeworksrcIlluminateDatabaseConnection.php

namespace IlluminateDatabase;

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 = [])

vendorlaravelframeworksrcIlluminateDatabaseConnectorsConnector.php

namespace IlluminateDatabaseConnectors;
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);
}

vendorlaravelframeworksrcIlluminateDatabaseConnectorsPostgresConnector.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;
}

vendorlaravelframeworksrcIlluminateDatabaseConnectorsConnectionFactory.php

namespace IlluminateDatabaseConnectors;

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) Once the files have been properly modified, all you have to do is properly configure Laravel to use your custom connection by modifying the following file:

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'   => '',
    ],

],

So far as I could tell, this was all the steps needed to get Laravel to connect to a Vertica database without crashing. I hope this helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...