Slim Model数据库实例


Slim Model db instance

对不起我的英语。

堆栈:Slim 3框架+Eloquent ORM。Eloquent与Slim合作如愿以偿。

我想使用一种MVC模式,其中瘦控制器胖模型(所有数据库查询和其他重逻辑)。

我所发现的只是如何从这样的路线使用它:

$app->get('/loans', function () use ($app) {
    $data = DB::table('loan_instalment')->get(); // works
    $data = $this->db->table('loan_instalment')->get(); // works
    ...
}

我想要的是从选择的模型中调用公共方法的能力,比如这样:

use 'src'models'Instalment;
$app->get('/loans', function () use ($app) {
    $data = $this->model('Instalment')->getSomething(12);
    ...
}

型号类别为:

namespace src'models;
use Illuminate'Database'Eloquent'Model as Model;
use Illuminate'Database'Capsule'Manager as DB;
class Instalment extends Model
{
    protected $table = 'loan_instalment';  
    public function getSomething($id)
    {
        return $this->table->find($id);
    }
    // bunch of other methods
}

我的应用程序看起来像基本的苗条骨架,Eloquent设置:

$capsule = new 'Illuminate'Database'Capsule'Manager;
$capsule->addConnection($container['settings']['db']);
$capsule->setAsGlobal();
$capsule->bootEloquent();

$container['db'] = function ($container) use ($capsule){
    return $capsule;
};

有可能吗?

如果你想使用MVC模式,你需要制作基本控制器。

<?php
namespace App'Controller;
use Slim'Container;
class BaseController
{
    protected $container;
    public function __construct(Container $container)
    {
        $this->container = $container;
    }
    public function getContainer()
    {
        return $this->container;
    }
    public function __get($name)
    {
        return $this->container->{$name};
    }
    public function __set($name, $value)
    {
        $this->container->{$name} = $value;
    }
}

容器:

// Base Controller
$container[App'Controller'BaseController::class] = function ($c) {
    return new App'Controller'BaseController($c);
};
$capsule = new 'Illuminate'Database'Capsule'Manager;
$capsule->addConnection($container['settings']['db']);
$capsule->setAsGlobal();
$capsule->bootEloquent();
$container['db'] = function ($container) use ($capsule){
    return $capsule;
};

强烈建议在型号上使用静态功能

<?php
namespace App'models;
use Illuminate'Database'Eloquent'Model as Model;
use Illuminate'Database'Capsule'Manager as DB;
class Instalment extends Model
{
    protected $table = 'loan_instalment';  
    public static function getSomething($id)
    {
        return Instalment::find($id);
    }
}

现在你的代码变成:

<?php
use App'models'Instalment;
$app->get('/loans', function ($request, $response, $args) {
    $data = Instalment::getSomething(12);
    ...
}

控制器:

<?php
namespace App'Controller;
use Psr'Http'Message'ServerRequestInterface as Request;
use Psr'Http'Message'ResponseInterface as Response;
use App'models'Instalment;
class HomeController extends BaseController
{
    public function __invoke(Request $request, Response $response, Array $args)
    {
        $data = Instalment::getSomething(12);
        // load the template
        return $response;
    }
}

以及控制器的路线

<?php
$app->get('/', App'Controller'HomeController::class);

它看起来更干净,不是吗?

更多教程:

  1. 我的博客
  2. Rob Allen的博客

您可以使用Slim的abbility来使用控制器。

制作一个基本控制器:

// BasicController.php
<?php    
namespace src'Controllers;
class BasicController
{
    public function model(string $model)
    {
        return new $model();
    }
}

然后在你的控制器中扩展这个类并将其添加到瘦容器中

//SomeController.php
<?php
namespace src'Controllers;
use 'Psr'Http'Message'ServerRequestInterface as Request;
use 'Psr'Http'Message'ResponseInterface as Response;
use 'src'models'Instalment as Instalment;
class SomeController extends BasicController
{
    public function index(Request $request, Response $response, $args)
    {
        $this->model(Instalment::class)->getSomethingOutOfDB;
        //do something else
    }
}

...
//container.php
use 'Slim'Container as Container;
$container['src'Controllers'HomeController::class] = function(Container $container) {
    return new 'src'Controllers'Homecontroller();
}
...

...
//routes.php
$app->get('/someroute', 'src'Controllers'HomeController::class . ':index');
...

另一种可能性是通过以下方式扩展您的'' Slim''应用程序:

//newApp.php
namespace scr'App
class newApp extends 'Slim'App
{
    public function model(string $model)
        {
            return new $model();
        }
}

实际上,我建议不要使用这两种方法,不要以这种方式加载模型,因为这被认为是一种糟糕的做法。

最好只使用:

//routes.php
...
use src'Models'Instalment;
...
...
$app->get('/someroute', function() {
    $instalment = new Instalment();
    // do something with it...
});