(这个问题不是关于数据库。我知道数据库通常被认为是多租户。但这不是我的问题。)
我创建了一个将由不同客户使用的应用程序。他们可以看到并做大部分相同的事情。但是,有些客户在这里和那里有一些额外的按钮,一些功能被禁用或其他不同的东西。
我想避免使用大量的if / else或switch语句。所以我想我可以为每个客户提供一个通用模块和特殊模块,根据需要覆盖或覆盖不同的东西。查看以下理论结构(所有文件都是正常的Yii文件):
app
general
controllers
OrderController
InvoiceController
ShippingController
views
order
index, view, update, create, _form
invoice
index, view, update, create, _form
shipping
index, view, update, create, _form
layout
main
models
Order
Invoice
Shipping
customerA
controllers
OrderController // some action is different
customerB
views
invoice
view // some buttons should be overridden
layout
main.php // other page structure
customerC
views
order
index // table gets some additional columns
model
Order // has some more properties
customerD
// this customer exists but has nothing that must be changed
// it uses all what is in general
...
web
common
console
...
我认为这是一个健全的文件结构。至少它是清楚易懂的。现在我想以某种方式实现:如果客户请求任何内容,应用程序将首先查看是否存在特定客户的文件并使用它们,或者使用通用模块中的文件(后备)。我的问题是:我该怎么做?
如果有可能,怎么样?或者只是部分可能,例如只有控制器和视图?我想视图/控制器/模型文件可能需要不同的方法。我想可以调整类自动加载。我会考虑使用路由(虽然客户必须经过身份验证,因此它只能使用他或她自己的客户):
http://example.com/customerA/invoice/view?id=1234
这一切都可以通过配置或依赖注入来完成吗?我是否需要模块或文件组织是否足够?
(思考:覆盖控制器可能很简单。但我认为只有在控制器被覆盖以设置另一个视图路径时才能覆盖视图文件。)
有没有人有想法解决这个问题?如果这适用于控制器和视图,我会很高兴。但模型也不错。或者有没有其他建议或替代方法?即使您只知道部分解决方案,也请告诉我。
我认为一个令人满意的答案可能随着时间的推移而演变。但是找到一个好的解决方案对其他人有帮助。那么让我们来研究一下;-) ......或者是另一个更适合这项任务的框架? : - (
答案 0 :(得分:0)
您可以按照以下代码使用单独的主题:
read this for theming instructions
read this for dependency injection instructions(或如何替换其他模型)
此示例显示如何将“@app/views
”替换为“@app/themes/mytheme
”。
common \ components \ Theme.php (自定义主题组件)
namespace common\components;
use Yii;
class Theme extends \yii\base\Theme
{
public function init() {
// todo: your logic goes here
$this->pathMap = [
'@app/views' => [
'@app/themes/mytheme',
]
];
return parent::init();
}
}
common \ extensions \ Bootstrap.php (DI的自定义引导程序)
namespace common\extensions;
use Yii;
use yii\base\Application;
use yii\base\BootstrapInterface;
use yii\helpers\Url;
class Bootstrap implements BootstrapInterface
{
public function bootstrap($app)
{
Yii::$container->set(\yii\base\Theme::className(), \common\components\Theme::className());
}
}
common \ config \ main.php (注册自定义引导程序)
'bootstrap' => [
'common\extensions\Bootstrap',
],
frontend \ config \ main.php (注册虚拟主题配置)
'components' => [
'view' => [
'theme' => [
'basePath' => '@app/views',
],
],
],