2017-02-23 82 views
0

我有一个将被许多数据库使用的应用程序。要选择具有应用程序数据的数据库,我有一个包含连接参数(主机,用户名,密码,数据库等)的数据库。动态数据源和CakePHP 3中的全局?

问题是,此动态创建的数据源不适用于其他应用程序。

控制器代码

$data  = $this->request->data; 
$connection = ConnectionManager::get("default"); 
$query  = "SELECT * FROM clients WHERE client_id = ".$data['codigo']; 
$result  = $connection->execute($query)->fetchAll('assoc'); 

ConnectionManager::drop('default');    

$config = ConnectionManager::config('connection', [ 
     'className' => 'Cake\Database\Connection', 
     'driver' => 'Cake\Database\Driver\Mysql', 
     'persistent' => false, 
     'host' => $result[0]['host'], 
     'username' => $result[0]['username'], 
     'password' => $result[0]['password'], 
     'database' => $result[0]['database'], 
     'encoding' => 'utf8', 
     'timezone' => 'UTC', 
     'flags' => [], 
     'cacheMetadata' => true, 
     'log' => false, 
     'quoteIdentifiers' => false, 
     'url' => env('DATABASE_URL', null), 
    ]); 

$connection = ConnectionManager::get('connection'); 
ConnectionManager::alias('connection', 'default'); 

return $this->redirect(['controller' => 'Mains', 'action' => 'index']); 

此重定向后,显然其他控制器没有这个数据源。

+0

Ouch,那是一个SQL注入漏洞!永远不要直接将用户数据插入查询! – ndm

回答

0

根据请求数据中的内容交换数据库肯定有点不寻常 - 但通常数据库连接只需要在Cake的初始设置中完成,因为每个Controller的连接资源已经设置为default

如果你只是交换一次,你可以在(其中Cake通常设置它的ConnectionManager)中进行管理。

您将无法访问$this->request,但可能只是从$ _REQUEST抓住它代替,例如:

在,改变这些行:

Cache::config(Configure::consume('Cache')); 
ConnectionManager::config(Configure::consume('Datasources')); 
Email::configTransport(Configure::consume('EmailTransport')); 

要这样:

Cache::config(Configure::consume('Cache')); 

ConnectionManager::config(Configure::consume('Datasources')); 
$connection = ConnectionManager::get("default"); 
$client = TableRegistry::get('Clients')->find() 
    ->where(['client_id'=> $_REQUEST['client_id']])->firstOrFail(); 

ConnectionManager::drop('default'); 

$config = ConnectionManager::config('connection', [ 
    'className' => 'Cake\Database\Connection', 
    'driver' => 'Cake\Database\Driver\Mysql', 
    'persistent' => false, 
    'host' => $client->host, 
    'username' => $client->username, 
    'password' => $client->password, 
    'database' => $client->database, 
    'encoding' => 'utf8', 
    'timezone' => 'UTC', 
    'flags' => [], 
    'cacheMetadata' => true, 
    'log' => false, 
    'quoteIdentifiers' => false, 
    'url' => env('DATABASE_URL', null), 
]); 

ConnectionManager::get('connection'); 

Email::configTransport(Configure::consume('EmailTransport')); 

被修改:从原始SQL切换到Table :: find()

+2

您已经继承了OPs SQL注入漏洞! – ndm

+0

我改变了代码,出现这个错误:**注意(8):未定义索引:codigo [ROOT \ config \ bootstrap.php,第156行] **。在进行配置之前,我需要通过表单获取这些数据。 cakephp在我的表单之前阅读bootstrap.php。 –

+0

啊 - 当它首次渲染那个表单时,它应该连接到哪个数据库?默认?如果是这样的话,只需在'ConnectionManager :: config(Configure :: consume('Datasources'));'在一个大if语句('if(!empty($ _ REQUEST ['codigo']){')直到那个电子邮件行 – ahoffner