Rumah > Soal Jawab > teks badan
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次。
目前在网上看到一种办法,就是在Repositories
Saya 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?
漂亮男人2017-05-16 16:55:44
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.
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.
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);
}
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
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
阿神2017-05-16 16:55:44
Melalui suntikan pergantungan
Ia boleh disuntik terus ke dalam Pengawal
Anda boleh membaca artikel ini
http://slides.com/howtomakeaturn/model#/
高洛峰2017-05-16 16:55:44
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.
PHP中文网2017-05-16 16:55:44
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 --->
淡淡烟草味2017-05-16 16:55:44
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