【问题标题】:Laravel model not using assigned connection (second connection) in a multi tenant appLaravel 模型未在多租户应用程序中使用分配的连接(第二个连接)
【发布时间】:2017-08-03 09:12:06
【问题描述】:

我正在尝试在 laravel 上构建一个多租户应用程序。 它是从 url 获取子域,从子域获取租户 id,获取该租户数据库的凭据并使用另一个连接连接到该数据库。

下面是我在config文件夹中database.php中的数据库配置。

'default' => env('DB_CONNECTION', 'mysql'),

    'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'erptenants'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
        'tenant' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', ''),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', ''),
            'username' => env('DB_USERNAME', ''),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
    ],

如您所见,有两个连接。默认和另一个称为租户。 租户具有通过全局中间件分配的新凭据。

命名空间 App\Http\Middleware;

使用闭包;

class TenantIdentification
{    
    public function handle($request, Closure $next)
    {

        $tk = "HYD"; //hardcoded for time being

        $tenant = \App\Models\Tenant::where('tenantKey', $tk)->first();

        \Config::set('database.connections.tenant.host', env('DB_HOST', $tenant ->host));
        \Config::set('database.connections.tenant.username', env('DB_USERNAME', $tenant ->username));
        \Config::set('database.connections.tenant.password', env('DB_PASSWORD', $tenant ->password));
        \Config::set('database.connections.tenant.database', env('DB_DATABASE', $tenant ->database));


        return $next($request);
    }
}

我假设这个 DB 凭证分配是有效的,因为我没有从 laravel 得到任何错误。可能也是一种不好的做法。

现在我有一个定义了连接的模型。

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    protected $connection = 'tenant';
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];


}

下面是我的控制器和试图检索数据的函数。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Models\User;

class UserController extends Controller
{
    public function verify(Request $request)
        {

            $username = $request->username;
            $password = $request->password;

            $user = \App\Models\User::where('username',$username)->where('password',$password)->first();

            var_dump($user);
        }
}

我收到一个错误提示

未找到基表或视图:1146 表 'erptenants.users' 不存在 存在

必须从 erpdata 而不是 erptenants 进行检索。这将在中间件中分配。 保存并加载它的数据库凭据,由于某种原因,它没有使用模型中的第二个连接“租户”来检索数据。 Laravel 正在尝试从错误的数据库中检索信息。 我能做些什么呢? 因为第二个连接是动态加载的,硬编码是不切实际的。 我能想到的唯一方法是覆盖默认数据库而不是第二个数据库连接。但我更喜欢有一个单独的数据库连接。 非常感谢任何帮助。

附带说明...默认连接仅用于验证租户 ID 并从表中获取 mysql db 凭据。也许这应该在第二个连接上完成。但话又说回来,默认数据库凭据是从 .env 文件中获取的。不是动态的。所以我将再次遇到这个问题。

---下面是我的环境文件

APP_ENV=local
APP_DEBUG=true
APP_KEY=base64:somekeyhere=
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=erptenants
DB_USERNAME=root
DB_PASSWORD=

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

【问题讨论】:

  • 您的 .env 中是否定义了 DB_HOSTDB_USERNAME 等?请发布您的 .env 文件
  • 看起来有一些定义。 env 文件添加到问题正文中

标签: php mysql database laravel laravel-5


【解决方案1】:

您的配置集语句似乎有错误:

\Config::set('database.connections.tenant.host', env('DB_HOST', $tenant ->host));

这:env('DB_HOST', $tenant -&gt;host) 如果在您的 .env 中定义,则返回 DB_HOST,并且仅在您的 .env 中未定义 DB_HOST 时才返回 $tenant-&gt;host

【讨论】:

  • 如何解决这个问题?删除环境 thingi 并使用 \Config::set('database.connections.tenant.host',$tenant ->host); ???
  • 是的,这就是要走的路
  • 是否最好也从 config/database.php 文件中删除“DB_HOST”部分?所以 env 文件不会被引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
相关资源
最近更新 更多