未在模型中设置Laravel 5.8动态数据库连接

时间:2019-05-13 19:13:56

标签: php laravel-5 eloquent database-connection

我正在尝试为每个模型创建动态数据库连接,以便可以使用$model->setConnection('connection_name)

传递连接名称。

我尝试了很多类似问题的答案,但是没有用

我创建了一个类,该类创建一个新的数据库连接并将其添加到数据库配置中

<?php

namespace App;

use Illuminate\Support\Facades\Config;

class Clientdb
{
    public $connection;

    public function __construct($dbUser, $dbPassword, $dbName)
    {
        Config::set('database.connections.' . $dbUser, array(
            'driver'    => 'mysql',
            'host'      => '55.55.55.55',
            'port'      => '3306',
            'database'  => $dbName,
            'username'  => $dbUser,
            'password'  => $dbPassword,
            'unix_socket' => '',
            'charset'   => 'utf8',
            'collation' => 'utf8_general_ci',
            'prefix'    => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                \PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ));

        $this->connection = $dbUser;
    }

    public function connection() {
        return $this->connection;
    }
}

在我的控制器中,创建新类的新实例以添加到数据库配置中,然后创建模型的新实例,并将连接名称传递给模型setConnection()函数。

$this->clientdb = new Clientdb($dbUser, $dbPassword, $dbName);

$model = new \App\MyModel();
// dd($this->clientdb->connection);
$model->setConnection($this->clientdb->connection);
// dd($model);

$result = $model::where('id', $id)->first();

问题在于它仍然尝试使用模型中设置的连接,并且该连接未更新。如果我在模型中对新的连接名称进行了硬编码,则可以使用,但是我需要使连接动态化,因为我不想继续手动添加到数据库配置中。

我缺少什么来更新模型中的连接。

这是我的模特的一个例子

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class MyModel extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_table';

    /**
     * Indicates if the model should be timestamped.
     *
     * @var bool
     */
    public $timestamps = false;

    /**
     * The connection name for the model.
     *
     * @var string
     */
    protected $connection = 'mysql';
}

sdfsf

2 个答案:

答案 0 :(得分:0)

它不起作用,因为$model::where()等效于(new MyModel)->where()

以非静态方法调用where()

$result = $model->where('id', $id)->first();
                ^^

您也可以使用Model::on()

$result = MyModel::on($this->clientdb->connection)->where('id', $id)->first();

答案 1 :(得分:0)

对于动态数据库连接,您必须考虑两件事

  1. 您的数据库是静态的吗?

  2. 您要如何建立连接?

在我的项目中,我的数据库名称不是静态的。在登录期间,客户端会更改数据库名称。这样我就在使用中间件,并且有一些复杂的代码。

但是,如果您使用的是静态数据库,则意味着一个将是ENV,另一个将是运行时。那么您只需几个步骤即可轻松完成此操作。

  1. Database.php配置上的提及数据库名称

    制作一个新的连接数组,就像这样:

    如果您要转至其他主机,可以更改

    HOST。否则,您可以获得表格ENV

    'bio_db' => [
        'driver' => 'mysql',
        'host' => 'YOURHOST',
        'port' => env('DB_PORT', '3306'),
        'database' => 'YourDatabaseName',
        'username' => 'DBUSERNAME',
        'password' => 'DBPASSWORD',
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'prefix_indexes' => true,
        'strict' => false,
        'engine' => "InnoDB",
    ],
    
  2. 使模型如下:

    class BioDevices extends Model
    {
        protected $connection="bio_db";
    
        protected $table="devices";
    
        protected $guarded = [];
    
        public $timestamps = false;
    
        protected $primaryKey="DeviceId";
    }
    
  3. 从控制器调用该表:

    public function test()
    {
        $data =BioDevices::get();
    
        return $data;
    }
    

如果已执行所有步骤,则将获得所需的输出,如下所示:

 [
   {
    DeviceId: 1,
    DeviceFName: "BABU ------ COLLEGE",
    DeviceSName: "1912003",
    DeviceDirection: "altinout",
    SerialNumber: "BKU719XXX5",
    ConnectionType: "TCP/IP",
    IpAddress: "",
    BaudRate: null,
    CommKey: "0",
          .......
     },
    .......
 ]