国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

So verwenden Sie Modelle in Laravel wieder
伊謝爾倫
伊謝爾倫 2017-05-16 16:53:44
0
5
857

Unser Unternehmen verwendet derzeit Laravel開發(fā)項目,同時還增加了Biz層和Repositories層,來實現(xiàn)業(yè)務(wù)邏輯封裝,反而model里面什么代碼都沒有。
Controller里寫代碼的時候,嘗嘗困擾我的問題是如果復(fù)用Biz對象,Repositories對象和Model對象。
以前用Yii開發(fā)項目的時候,有一個工廠模式,所以調(diào)用Model的時候,基本都不new, das als Bytes mit XXX::model() bezeichnet wird. Es reicht aus, wenn ein Objekt einmal neu ist, was effektiv Speicher sparen kann. Controller-Code:

$productModel = Product::model()->getList('xxxxxxxxx');

Wie einfach, oder?

In Laravel scheint Model keine Factory zu haben. Um es aufzurufen, ist eine Instanz erforderlich. Wenn Repositories 5 Methoden kapselt, ist jede davon vorhanden habe Model verwendet, dann habe ich diese 5 Methoden in Controller aufgerufen und Model war fünfmal neu.

Ich sehe derzeit im Internet eine M?glichkeit, das Modellobjekt in den Konstruktor von Repositories einzufügen und in die privaten Mitgliedsvariablen von Repositories einzufügen. Auf diese Weise k?nnen alle fünf Methoden aufrufen private Variablen der aktuellen Klasse. Die Verwendung ist jedoch umst?ndlich. Wenn Sie Code in Controller schreiben, müssen Sie so schreiben: Laravel里,Model好像沒有工廠,要調(diào)用,都需要實例,假如Repositories里面封裝了5個方法,每個都使用了Model,那么我在Controller里調(diào)用了這5個方法,Model就被new了5次。
目前在網(wǎng)上看到一種辦法,就是在Repositories

$xxxBiz = new XXXBiz(\xxx\xxx\Repositories);

Sie müssen dies in Repositories schreiben:

$xxxRepositories = new XXXRepositories(\xxx\xx\xxxModel);

Es gibt ein

-Objekt in new, und der Namespace ist im Grunde immer noch lang, und die Effizienz beim Schreiben von Code ist extrem gering. Au?erdem muss ich die Datei ?ffnen, um den Namen zu buchstabieren. Biz的時候,還必須傳入Repositories

Ich würde gerne fragen, wie Sie das Problem der Wiederverwendung logischer Schichtklassen wie Model bei der Entwicklung von Projekten mit Laravel l?sen?

伊謝爾倫
伊謝爾倫

小伙看你根骨奇佳,潛力無限,來學(xué)PHP伐。

Antworte allen(5)
漂亮男人

0x0 前言

有趣的問題,Yii 在業(yè)界也是被公認為性能比 Laravel 高的一個框架。于是我想單從 ActiveRecord 的構(gòu)造,看看兩大框架的具體實現(xiàn)。

0x1 Laravel 的 Eloquent 框架

在 Laravel 中可以很輕松地使用關(guān)系查詢:

    $user = User::find(1);

我在 User 類里并沒有找到 find 方法,WTF,發(fā)生了什么???

User 的基類是 Model,使用靜態(tài)調(diào)用,所以會調(diào)用 Model 的 __callStatic 魔術(shù)方法:

    public static function __callStatic($method, $parameters)
    {
        // $method = 'find';
        // $parameters = [1];
        
        // 實例化當(dāng)前類,即 User 模塊
        $instance = new static;
        // 調(diào)用當(dāng)前實例的 find 方法
        return call_user_func_array([$instance, $method], $parameters);
    }

其實就是再調(diào)用 __call 魔術(shù)方法:

    public function __call($method, $parameters)
    {
        //...

        $query = $this->newQuery();

        return call_user_func_array([$query, $method], $parameters);
    }

追根溯源,我們發(fā)現(xiàn)其實 find 方法來自 Illuminate\Database\Eloquent\Builder,而該類內(nèi)部使用 Illuminate\Database\Query\Builder 的實現(xiàn)。

等等,Illuminate\Database\Eloquent\BuilderIlluminate\Database\Query\Builder 的區(qū)別是啥?

其實 Eloquent\Builder 是對 Query\Builder 的進一步封裝,以便更好的實現(xiàn)關(guān)系對象查詢。

那么,其實過程為:

也就是說,你每次 靜態(tài)調(diào)用 Model 的方法,都會實例化一次 Model,走一次過程。

0x2 Yii 1.1 中的 CActiveRecord

題主既然用到 model 方法,那應(yīng)該是 1.1 的版本,模塊繼承自 CActiveRecord(Yii2 中則繼承自 Yii\db\ActiveRecord)。

好了,伙計們,現(xiàn)在使用 Yii 實現(xiàn)關(guān)系查詢,先定義:

    class User extends CActiveRecord
    {
        public static function model($className=__CLASS__)
        {
            return parent::model($className);
        }
    }

查詢:

    $user = User::model()->findAllByPk(1);

明顯查詢對象來自 model,看看父類怎么實現(xiàn)這個函數(shù):

    public static function model($className=__CLASS__)
    {
        // 如果已經(jīng)實例化了則直接返回該實例
        if(isset(self::$_models[$className]))
            return self::$_models[$className];
        else
        {
            // 初始化,并將保存當(dāng)前實例
            $model=self::$_models[$className]=new $className(null);
            $model->attachBehaviors($model->behaviors());
            return $model;
        }
    }

findAllByPk 方法直接封裝于 CActiveRecord 內(nèi)部:

    public function findByPk($pk,$condition='',$params=array())
    {
        // ...

        $criteria = $this->getCommandBuilder()->createPkCriteria($this->getTableSchema(),
            $pk, $condition, $params, $prefix);
            
        return $this->query($criteria);
    }

所以其過程為:

0x3 使用 Laravel 的依賴注入

通常情況下(無參數(shù)的構(gòu)造函數(shù)或注入?yún)?shù)已配置),Laravel 會自動幫你實例化:

<?php namespace App\Repositories;

use App\User;    
    
class Repository {
    
    protected $user;
    
    public __construct(User $user) {
        $this->user = $user;
    }
}

所以你可以很輕松復(fù)用同一個對象:

class Repository {
    
    protected $user;
    
    public __construct(User $user) {
        $this->user = $user;
    }
    
    public function first() {
        $this->user->first();
    }
    
    public function find(Request $request, $id) {
        if (Gate::denies('view', $request->user())) {
            abort(403);
        }
        
        return $this->user->find($id);
    }
    
    public function excited() {
        return $this->user->where('name', 'bigNews')->get();
    }
}

實現(xiàn)完倉庫后,你需要手動實例化嗎:

    $repo = new App\Repositories\Repository(new App\User());

不,這不符合 Laravel 的哲♂學(xué),你可以如此簡單:

<?php
    use App\Repositories\Repository;
    
    public function index(Repository $repo) {
        return $repo->first();
    }

是的,沒錯,你無需手動構(gòu)造,傳入 User 實例等等,一切只是一個簡單的自動注入。而且題主注意到這里使用了命名空間,所以你只需 use 一次。(當(dāng)然如果你不想拼寫這么長的命名空間,那你是時候換一款 IDE 了,PhpStorm 中可以使用 Alt + Enter 快速導(dǎo)入

0x4 最后

對于靜態(tài)和非靜態(tài)開銷的問題,在 StackOverflow 上有一篇討論:http://stackoverflow.com/questions/14727...

所以說到底還是看業(yè)務(wù)需求嘛23333

阿神

通過依賴注入呀
直接可以注入到Controller中
可以看看這個文章
http://slides.com/howtomakeaturn/model#/

小葫蘆

我假定你對Laravel還不是很了解。

第一,Laravel的Model也就是模型,不需要顯式的實例化,調(diào)用方式像下面這樣(摘自官方文檔):

$flights = App\Flight::where('active', 1)
               ->orderBy('name', 'desc')
               ->take(10)
               ->get();

第二,你的描述有錯誤。你尋找的不是工廠模式(factory pattern),而是單例模式(singleton pattern),對象在一次請求生命周期之內(nèi),最多只需要實例化一次。在Laravel當(dāng)中,需要用到IOC(inversion of control)容器或者說是服務(wù)容器(service container)。像下面這樣:

// 先綁定需要實例化的對象或者服務(wù)
$this->app->singleton('FooBar', function ($app) {
    return new FooBar($app['SomethingElse']);
});
// 調(diào)用對象或服務(wù)有多種方式,比如以下兩種:
// 第一種
$fooBar = $this->app->make('FooBar'); // 顯式解析
$fooBar = $this->app['FooBar']; // 像訪問數(shù)組一樣調(diào)用之前被顯式解析(實例化)過的對象或服務(wù)
// 第二種
// 通過類型聲明(type hinting)來自動解析,無需顯式解析(實例化),直接調(diào)用,請參考最后附上的文檔
// 除了單例模式外,當(dāng)然還支持工廠模式,即每次調(diào)用,返回一個新的實例,像下面這樣:
$this->app->bind('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app['HttpClient']);
});

以上只是簡單的摘錄,具體用法,請參考Laravel官方優(yōu)秀的文檔,鏈接如下:
Service Container(IOC容器/服務(wù)容器)

洪濤

我司是繼承一個BaseRepository,BaseRepository中定義

protected function getUserCouponModel($new = false)
{
    if (is_null($this->userCouponModel) || true === $new) {
        $this->userCouponModel = new UserCouponModel();
    }
    return $this->userCouponModel;
}

CouponRepository中

public function create($couponID)
{
    $attributes = [
        'couponID' => $couponID,
    ];

    return $this->getUserCouponModel(true)->create($attributes);
}

Biz中類似,繼承一個BaseBiz,然后方法這么寫

public function create($fields)
{
    return $this->getCouponRepository()->create($fields);
}

Controller中調(diào)用

$biz = new Biz();
$biz->create($fields);

Controller ---> Biz ---> Repository

淡淡煙草味

我是這么做的,在底層 model 里建立這個函數(shù)
修改bootstrap/app.php 和 AppServiceProvider.php
具體參考 Service Provider

    static public function load(){
        return app()->make(get_called_class());
    }

在controller 里調(diào)用 Foo::load() 就可以了

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage