Bagaimana untuk menggunakan semula model dalam Laravel
伊谢尔伦
伊谢尔伦 2017-05-16 16:53:44
0
5
762

Syarikat kami pada masa ini menggunakan Laravel开发项目,同时还增加了Biz层和Repositories层,来实现业务逻辑封装,反而model里面什么代码都没有。
Controller里写代码的时候,尝尝困扰我的问题是如果复用Biz对象,Repositories对象和Model对象。
以前用Yii开发项目的时候,有一个工厂模式,所以调用Model的时候,基本都不new, yang dipanggil bait menggunakan XXX::model() Cukuplah untuk sesuatu objek menjadi baharu sekali, yang boleh menjimatkan memori dengan berkesan.
Kod pengawal:

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

Sederhana kan?

Dalam Laravel, Model nampaknya tidak mempunyai kilang Untuk memanggilnya, instance diperlukan Jika Repositori merangkumi 5 kaedah, setiap satu menggunakan Model, kemudian saya memanggil lima kaedah ini dalam Controller dan Model ialah lima kali baharu. Laravel里,Model好像没有工厂,要调用,都需要实例,假如Repositories里面封装了5个方法,每个都使用了Model,那么我在Controller里调用了这5个方法,Model就被new了5次。
目前在网上看到一种办法,就是在RepositoriesSaya pada masa ini melihat cara di Internet, iaitu menyuntik objek Model ke dalam pembina Repositories dan meletakkannya dalam pembolehubah ahli persendirian Repositori Dengan cara ini, semua lima kaedah boleh memanggil pembolehubah persendirian kelas semasa. Tetapi ia menyusahkan untuk digunakan Semasa menulis kod dalam Pengawal, anda perlu menulis seperti ini:

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

Anda perlu menulis ini dalam Repositori:

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

Terdapat objek Biz的时候,还必须传入Repositories dalam bentuk baharu, dan ruang nama saya pada asasnya mengeja rentetan Kecekapan menulis kod adalah sangat rendah.

Saya ingin bertanya bagaimana anda menyelesaikan masalah penggunaan semula kelas lapisan logik seperti Model semasa membangunkan projek dengan Laravel?

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

membalas semua(5)
漂亮男人

0x0 Prakata

Persoalan yang menarik, Yii juga diiktiraf dalam industri sebagai rangka kerja dengan prestasi yang lebih tinggi daripada Laravel. Jadi saya ingin melihat pelaksanaan khusus dua rangka kerja utama hanya dari struktur ActiveRecord.

0x1 rangka kerja fasih untuk Laravel

Mudah untuk menggunakan pertanyaan hubungan dalam Laravel:

    $user = User::find(1);

Saya tidak menemui kaedah cari dalam kelas Pengguna, WTF, apa yang berlaku! ?

Kelas asas Pengguna ialah Model, yang menggunakan panggilan statik, jadi kaedah ajaib __callStatic Model akan dipanggil:

    public static function __callStatic($method, $parameters)
    {
        // $method = 'find';
        // $parameters = [1];
        
        // 实例化当前类,即 User 模块
        $instance = new static;
        // 调用当前实例的 find 方法
        return call_user_func_array([$instance, $method], $parameters);
    }

Malah, ia adalah untuk memanggil kaedah sihir __panggilan semula:

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

        $query = $this->newQuery();

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

Menjejak kembali ke sumber, kami mendapati bahawa kaedah cari sebenarnya berasal daripada IlluminateDatabaseEloquentBuilder, dan kelas ini secara dalaman menggunakan pelaksanaan IlluminateDatabaseQueryBuilder.

Tunggu sebentar, apakah perbezaan antara IlluminateDatabaseEloquentBuilder dan IlluminateDatabaseQueryBuilder?

Malah, EloquentBuilder ialah enkapsulasi lanjut QueryBuilder untuk melaksanakan pertanyaan objek hubungan dengan lebih baik.

Jadi, proses sebenar ialah:

Dalam erti kata lain, setiap kali anda memanggil secara statik kaedah Model, Model akan disegerakan dan prosesnya akan selesai.

0x2 CActiveRecord dalam Yii 1.1

Memandangkan penyoal menggunakan kaedah model, ia mestilah versi 1.1. Modul mewarisi daripada CActiveRecord (dalam Yii2, ia mewarisi daripada YiidbActiveRecord).

Baiklah, kawan-kawan, sekarang gunakan Yii untuk melaksanakan pertanyaan hubungan, mula-mula takrifkan:

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

Pertanyaan:

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

Jelas sekali objek pertanyaan datang daripada model, mari lihat bagaimana kelas induk melaksanakan fungsi ini:

    public static function model($className=__CLASS__)
    {
        // 如果已经实例化了则直接返回该实例
        if(isset(self::$_models[$className]))
            return self::$_models[$className];
        else
        {
            // 初始化,并将保存当前实例
            $model=self::$_models[$className]=new $className(null);
            $model->attachBehaviors($model->behaviors());
            return $model;
        }
    }

kaedah findAllByPk terkandung terus di dalam CActiveRecord:

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

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

Jadi prosesnya ialah:

Suntikan Ketergantungan 0x3 menggunakan Laravel

Dalam keadaan biasa (pembina tanpa parameter atau parameter yang disuntik telah dikonfigurasikan), Laravel akan membuat seketika secara automatik untuk anda:

<?php namespace App\Repositories;

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

Jadi anda boleh menggunakan semula objek yang sama dengan mudah:

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();
    }
}

Selepas melaksanakan gudang, adakah anda perlu membuat instantiat secara manual:

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

Tidak, ini tidak selaras dengan falsafah Laravel, anda boleh melakukannya semudah:

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

Ya, betul, anda tidak perlu membina secara manual, memasukkan contoh Pengguna, dll., semuanya hanyalah suntikan automatik yang mudah. Dan penyoal menyedari bahawa ruang nama digunakan di sini, jadi anda hanya perlu menggunakannya sekali. (Sudah tentu, jika anda tidak mahu mengeja ruang nama yang begitu panjang, maka sudah tiba masanya untuk anda menukar kepada IDE. Anda boleh menggunakan Alt + Enter untuk mengimport dengan cepat dalam PhpStorm

0x4 Akhirnya

Untuk isu overhed statik dan bukan statik, terdapat perbincangan mengenai StackOverflow: http://stackoverflow.com/questions/14727...

Jadi dalam analisis akhir, ia masih bergantung kepada keperluan perniagaan 23333

阿神

Melalui suntikan pergantungan
Ia boleh disuntik terus ke dalam Pengawal
Anda boleh membaca artikel ini
http://slides.com/howtomakeaturn/model#/

小葫芦

Saya andaikan anda masih belum tahu banyak tentang Laravel.

Pertama, Model Laravel ialah model, yang tidak memerlukan instantiasi yang jelas Kaedah panggilan adalah seperti berikut (diekstrak daripada dokumentasi rasmi):

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

Kedua, penerangan anda salah. Apa yang anda cari bukanlah corak kilang, tetapi corak tunggal Objek hanya perlu dibuat seketika semasa kitaran hayat permintaan. Dalam Laravel, anda perlu menggunakan bekas IOC (penyongsangan kawalan) atau bekas perkhidmatan. Seperti ini:

// 先绑定需要实例化的对象或者服务
$this->app->singleton('FooBar', function ($app) {
    return new FooBar($app['SomethingElse']);
});
// 调用对象或服务有多种方式,比如以下两种:
// 第一种
$fooBar = $this->app->make('FooBar'); // 显式解析
$fooBar = $this->app['FooBar']; // 像访问数组一样调用之前被显式解析(实例化)过的对象或服务
// 第二种
// 通过类型声明(type hinting)来自动解析,无需显式解析(实例化),直接调用,请参考最后附上的文档
// 除了单例模式外,当然还支持工厂模式,即每次调用,返回一个新的实例,像下面这样:
$this->app->bind('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app['HttpClient']);
});

Di atas hanyalah petikan ringkas Untuk penggunaan khusus, sila rujuk dokumentasi rasmi Laravel yang sangat baik.

洪涛

Syarikat kami mewarisi BaseRepository, yang ditakrifkan dalam 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);
}

Serupa dalam Biz, warisi BaseBiz, dan kemudian tulis kaedah seperti ini

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

Pengawal

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

Pengawal --->

淡淡烟草味

Ini yang saya lakukan, buat fungsi ini dalam model asas
Ubah suai bootstrap/app.php dan AppServiceProvider.php
Untuk butiran, sila rujuk Pembekal Perkhidmatan

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

Panggil Foo::load() sahaja dalam pengawal

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan