Middleware (MiddleWare)



Bagaimana untuk menjana middleware dengan cepat?

Melalui baris arahan: Hasilkan perisian tengah Semak di bawah direktori apl/perisian tengah

php think make:middleware Check

Kod kemasukan middleware

pertengahan mesti: executionrrre kaedah kemasukan middleware: executionrrre Ia ialah kaedah pemegang, dan parameter pertama ialah objek Permintaan, dan parameter kedua ialah penutupan.

Nilai pulangan kaedah pengendalian middleware mestilah objek Respons.

Dalam perisian tengah ini, kami melakukan pemprosesan ubah hala apabila kami menilai bahawa parameter nama permintaan semasa adalah sama dengan fikir. Jika tidak, permintaan akan diteruskan lagi kepada permohonan itu. Untuk terus menghantar permintaan kepada aplikasi, hanya panggil fungsi panggil balik $next dengan $request sebagai parameter.

Di bawah keperluan tertentu, anda boleh menggunakan parameter ketiga untuk memasukkan parameter tambahan.

<?php

namespace app\middleware;

class Check
{
    public function handle($request, \Closure $next)
    {
        if ($request->param('name') == 'think') {
            return redirect('index/think');
        }

        return $next($request);
    }
}

Tamatkan penjadualan

Middleware menyokong penentuan mekanisme panggil balik sebelum permintaan tamat Anda hanya perlu menambah kaedah tamat dalam kelas middleware.

<?php

namespace app\middleware;

class Check
{
    public function handle($request, \Closure $next, $name)
    {
        if ($name == 'think') {
            return redirect('index/think');
        }

        return $next($request);
    }
}

Perhatikan bahawa tidak boleh ada sebarang output tindak balas dalam kaedah akhir. Kerana output respons permintaan telah selesai apabila panggilan balik dikeluarkan.


Pra/post middleware

Sama ada middleware dilaksanakan sebelum atau selepas operasi khusus diminta bergantung sepenuhnya pada takrifan middleware itu sendiri.

Berikut ialah perisian tengah untuk pra-kelakuan

    public function end(\think\Response $response)
    {
        // 回调行为
    }

Berikut ialah perisian tengah untuk pasca-kelakuan

<?php

namespace app\middleware;

class Before
{
    public function handle($request, \Closure $next)
    {
        // 添加中间件执行代码

        return $next($request);
    }
}

Kaedah perisian tengah juga boleh menyokong suntikan kebergantungan.

Mari kita ambil contoh yang lebih praktikal Kita perlu menentukan sama ada persekitaran penyemak imbas semasa ialah WeChat atau Alipay

<?php

namespace app\middleware;

class After
{
    public function handle($request, \Closure $next)
    {
		$response = $next($request);

        // 添加中间件执行代码

        return $response;
    }
}

Kemudian tambahkan fail middleware.php pada versi mudah alih aplikasi anda

Sebagai contoh: /path/app/mobile/. middleware .php

namespace app\middleware;

/**
 * 访问环境检查,是否是微信或支付宝等
 */
class InAppCheck
{
    public function handle($request, \Closure $next)
    {
        if (preg_match('~micromessenger~i', $request->header('user-agent'))) {
            $request->InApp = 'WeChat';
        } else if (preg_match('~alipay~i', $request->header('user-agent'))) {
            $request->InApp = 'Alipay';
        }
        return $next($request);
    }
}

Kemudian dalam pengawal anda, anda boleh mendapatkan nilai yang berkaitan melalui $this->request->InApp

Tentukan alias middleware

Anda boleh terus menyediakannya di middleware.php dalam direktori konfigurasi aplikasi Tentukan perisian tengah (sebenarnya menambah pengecam alias), contohnya:

return [
    app\middleware\InAppCheck::class,
];

boleh menyokong penggunaan alias untuk mentakrifkan set perisian tengah, contohnya:


return [
    'alias' => [
        'auth'  => app\middleware\Auth::class,
        'check' => app\middleware\Check::class,
    ],
];

Daftar perisian tengah

ialah versi baharu middleware dibahagikan kepada perisian tengah global, Terdapat empat kumpulan: perisian tengah aplikasi (sah dalam mod berbilang aplikasi), perisian tengah penghalaan dan perisian tengah pengawal.

Arahan pelaksanaan ialah: global middleware -> application middleware -> routing middleware -> controller middleware

global middleware

global middleware berada dalam fail middleware.php di bawah direktori app Definisi, gunakan kaedah berikut:

return [
    'alias' => [
        'check' => [
            app\middleware\Auth::class,
            app\middleware\Check::class,
        ],
    ],
];

Pendaftaran middleware harus menggunakan nama kelas yang lengkap Jika alias middleware (atau kumpulan) telah ditakrifkan, ia boleh digunakan secara langsung.

Arahan pelaksanaan perisian tengah global ialah susunan definisi. Parameter perisian tengah boleh dihantar apabila mentakrifkan perisian tengah global, dan dua kaedah disokong.

<?php

return [
	\app\middleware\Auth::class,
    'check',
    'Hello',
];

Takrifan di atas bermaksud bahawa parameter pentadbir dihantar ke perisian tengah Auth dan parameter thinkphp dihantar ke perisian tengah Hello.

Perisian tengah aplikasi

Jika anda menggunakan mod berbilang aplikasi, definisi perisian tengah aplikasi disokong Anda boleh menambah fail middleware.php terus di bawah direktori aplikasi Kaedah definisi adalah sama dengan definisi perisian tengah global, tetapi ia hanya akan berkuat kuasa di bawah aplikasi .

Routing middleware

Kaedah pendaftaran middleware yang paling biasa digunakan ialah mendaftar routing middleware

<?php

return [
	[\app\http\middleware\Auth::class, 'admin'],
    'Check',
    ['hello','thinkphp'],
];

Menyokong pendaftaran berbilang middleware

Route::rule('hello/:name','hello')
	->middleware(\app\middleware\Auth::class);

Anda boleh terus mentakrifkan middleware dalam direktori konfigurasi middleware.yphp menambah pengecam alias), contohnya:

Route::rule('hello/:name','hello')
	->middleware([\app\middleware\Auth::class, \app\middleware\Check::class]);

Kemudian terus gunakan alias middleware untuk mendaftar dalam laluan

return [
	'auth'	=>	app\middleware\Auth::class,
    'check'	=>	app\middleware\Check::class
];

boleh menyokong menggunakan alias untuk menentukan set middleware, contohnya:

Route::rule('hello/:name','hello')
	->middleware(['auth', 'check']);

Kemudian, daftar terus menggunakan yang berikut kaedah Middleware

return [
	'check'	=>	[
    	app\middleware\Auth::class,
   		app\middleware\Check::class
    ],
];

menyokong pendaftaran middleware untuk kumpulan penghalaan

Route::rule('hello/:name','hello')
	->middleware('check');

menyokong pendaftaran middleware untuk nama domain tertentu

Route::group('hello', function(){
	Route::rule('hello/:name','hello');
})->middleware('auth');

Jika anda perlu menghantar parameter tambahan kepada middleware, anda boleh menggunakan

Route::domain('admin', function(){
	// 注册域名下的路由规则
})->middleware('auth');

Jika anda perlu menentukan berbilang middleware, gunakan Kaedah tatasusunan

Route::rule('hello/:name','hello')
	->middleware('auth', 'admin');

boleh lulus dalam parameter tambahan yang sama

Route::rule('hello/:name','hello')
	->middleware([Auth::class, 'Check']);

atau memanggilnya beberapa kali secara berasingan, menyatakan parameter yang berbeza

Route::rule('hello/:name','hello')
	->middleware(['auth', 'check'], 'admin');

Jika anda mahu perisian tengah penghalaan dilaksanakan secara global (tidak kira sama ada laluan itu sepadan atau tidak), anda tidak perlu Ditakrifkan dalam penghalaan, ia disokong untuk ditakrifkan secara langsung dalam fail konfigurasi penghalaan Contohnya, tambah:

Route::rule('hello/:name','hello')
	->middleware('auth', 'admin')
        ->middleware('hello', 'thinkphp');

ke fail konfigurasi config/route.php Dengan cara ini, semua permintaan di bawah aplikasi akan melaksanakan perisian tengah Auth dan Semak.

Gunakan penutupan untuk menentukan perisian tengah

Anda tidak perlu menggunakan kelas perisian tengah Dalam beberapa situasi mudah, anda boleh menggunakan penutupan untuk menentukan perisian tengah, tetapi fungsi penutupan mesti mengembalikan contoh objek Respons.

'middleware'    =>    [
    app\middleware\Auth::class,
    app\middleware\Check::class,
],

Perisian tengah pengawal

menyokong penentuan perisian tengah untuk pengawal. Anda hanya perlu mentakrifkan atribut middleware dalam pengawal, contohnya:

Route::group('hello', function(){
	Route::rule('hello/:name','hello');
})->middleware(function($request,\Closure $next){
    if ($request->param('name') == 'think') {
        return redirect('index/think');
    }
    
	return $next($request);
});

Perisian tengah auth akan dipanggil apabila pengawal indeks dilaksanakan, dan penggunaan definisi ruang nama yang lengkap juga disokong.

Jika anda perlu menetapkan operasi berkesan di tengah-tengah pengawal, anda boleh mentakrifkannya seperti berikut:

<?php
namespace app\controller;

class Index
{
    protected $middleware = ['auth'];

    public function index()
    {
        return 'index';
    }

    public function hello()
    {
        return 'hello';
    }
}

Perisian tengah menghantar parameter kepada pengawal

Anda boleh menghantar parameter kepada pengawal (atau tempat lain) dengan memberikan nilai kepada objek permintaan, contohnya

<?php
namespace app\controller;


class Index
{
    protected $middleware = [ 
    	'auth' 	=> ['except' 	=> ['hello'] ],
        'check' => ['only' 		=> ['hello'] ],
    ];

    public function index()
    {
        return 'index';
    }

    public function hello()
    {
        return 'hello';
    }
}

Kemudian anda boleh menggunakannya secara langsung dalam kaedah pengawal

<?php

namespace app\middleware;

class Hello
{
    public function handle($request, \Closure $next)
    {
        $request->hello = 'ThinkPHP';
        
        return $next($request);
    }
}

Keutamaan pelaksanaan

Jika anda mempunyai keperluan yang ketat pada susunan pelaksanaan middleware, anda boleh menentukan keutamaan pelaksanaan middleware. Tambah

public function index(Request $request)
{
	return $request->hello; // ThinkPHP
}

dalam profil