我正在尝试在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;
使用Closure;
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完成。这将在中间件中分配。 保存并加载它的数据库凭据,由于某种原因,它没有使用模型中的第二个连接“tenant”来检索数据。 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
答案 0 :(得分:0)
您的配置集语句看起来有错误:
\Config::set('database.connections.tenant.host', env('DB_HOST', $tenant ->host));
这个:env('DB_HOST', $tenant ->host)
如果在.env中定义,则返回DB_HOST
,如果您的.env中未定义$tenant->host
,则只返回DB_HOST