Laravel을 사용하여 효율성을 유지하는 7가지 팁

라라빌의 내재적인 힘은 디테일에 있다.코드의 유지보수성을 유지하기 위해서 아래의 7가지 힌트를 드리겠습니다.
  • 1. Controllers should... well, control
  • 2. Cleaner validation with Requests Forms
  • 3. Type hint your models in your controllers
  • 4. Centralized error handling
  • 5. Collections... collections everywhere
  • 6. Factorize your routes with Resources
  • 7. Lean code with mutators
  • 1. 컨트롤러는...응, 컨트롤


    이런 사내아이를 본 적이 있습니까?
    use Validator;
    use Kreait\Firebase\Factory;
    use Kreait\Firebase\ServiceAccount;
    
    class AuthenticationController extends Controller {
      public function index(Request $request) {
        if ($request->wantsJson()) {
          $validator = Validator::validate($request->all(), [
            'token' => 'required|filled|string'
          ]);
    
          if ($validator->fails()) {
            return response()->json('wrong token', 400);
          }
    
          $serviceAccount = ServiceAccount::fromArray(config('firebase'));
          $firebase = (new Factory)->withServiceAccount($serviceAccount)
            ->create()
            ->getAuth();
    
          try {
            $firebase->verifyIdToken($token);
    
            return response()->json('ok');
          } catch(Exception $exception) {
            app('sentry')->captureException($exception);
    
            return response()->json('unauthorized', 403);
          }
        } else {
          abort(403);
        }
      }
    }
    
    이거 어때요?
    use App\Firebase;
    use App\Http\Requests\AuthenticationRequest;
    
    class AuthenticationController extends Controller {
      public function index(AuthenticationRequest $request) {
        if ($request->wantsJson()) {
          if (Firebase::tokenValid($request->input('token'))) {
            return response()->json('ok');
          } else {
            return response()->json('unauthorized', 403);
          }
        } else {
          abort(403);
        }
      }
    }
    
    우리는 업무 논리를 나머지 부분에서 해방시키는 데 몇 가지 방법을 사용했다.나는 여기서 Request forms을 소개할 것이다. 이것은 내가 컨트롤러에서 검증 절차를 삭제하는 것을 도와주고 본고에서 Error handling을 소개한다.
    그러나 중요한 것은 업무 논리를 컨트롤러에 두지 않는 것이다.Controllers은 경량급을 유지하고 필요한 도구만 사용하여 재라우팅 요청을 결정해야 한다.마지막으로, 그것은 단지 요청 컨트롤러일 뿐이다.어떤 상업 결정도 Models에 있어야 한다.
    예, 테이블과 관련이 없는 클래스를 만들 수 있습니다.내 예시에서 나는 하나의 클래스를 사용하여'문제': Firebase 인증을 모델링했다.

    2. 양식을 사용하여 보다 간결한 검증 요청


    나는 라레빌과 함께 검증하는 것을 좋아한다.나는 그것들의 깨끗하고 표현력이 풍부한 사용 방식을 좋아한다.일반적으로 사용자 카트를 검증하는 예입니다.
    use App\Product;
    use App\Order;
    use App\Session;
    
    class CartController extends Controller {
      public function store(Request $request) {
        $request->validate([
          'id' => 'required|exists:product,id'
        ]);
    
        // Request passed, time to save the data
    
        $productId = $request->input('id');
        $product = Product::find($productId);
    
        Order::insert([
          'productId' => $product->id
        ]);
    
        Session::flash('success', 'Order completed!');
    
        return response()->view('product');
      }
    }
    
    이것은 매우 좋지만, 우리는 더욱 간소화할 수 있다.우선, 폼 요청을 만들어야 합니다.
    php artisan make:request CartRequest
    
    app/Http/Requests/CartRequest.php에 파일을 생성합니다.그것을 열면 이렇게 보일 것이다.
    use Illuminate\Foundation\Http\FormRequest;
    
    class CartRequest extends FormRequest {
      public function authorize() {
        return true; // Unless you have Guards, set it to true.
      }
    
      public function rules() {
        return [
          'id' => 'required|exists:product,id'
        ];
      }
    }
    
    이제 컨트롤러에서 사용할 수 있습니다.
    use App\Product;
    use App\Order;
    use App\Session;
    use App\Http\Requests\CartRequest;
    
    class CartController extends Controller {
      public function store(CartRequest $request) {
        // The request is validated using our CartRequest
    
        $productId = $request->input('id');
        $product = Product::find($productId);
    
        Order::insert([
          'productId' => $product->id
        ]);
    
        Session::flash('success', 'Order completed!');
    
        return response()->view('product');
      }
    }
    
    이것은 모호함을 제거하고 업무 알고리즘에 전념하는 좋은 방법이다.가장 좋은 상황은 유사한 검증을 공유하는 모델에 대해 폼 요청을 다시 사용할 수 있다는 것이다.
    use App\Http\Requests\ProductRequest;
    
    class Shoe extends Controller {
      public function index(ProductRequest $request) {
        // ...
      }
    }
    
    class Clothing extends Controller {
      public function index(ProductRequest $request) {
        // ...
      }
    }
    

    3. 컨트롤러에 모델 힌트를 입력합니다.


    때때로 나는 3킬로미터의 노선을 썼고, 나의 컨트롤러도 따라 갔다.
    Route::get('/customer/{customerId}/contract/{contractId}/invoice/{invoiceId}', 'CustomerContractInvoiceController@show');
    
    use App\Customer;
    use App\Contract;
    use App\Invoice;
    
    class CustomerContractInvoiceController extends Controller {
      public function show(Request $request, int $customerId, int $contractId, int $invoiceId) {
        $customer = Customer::findOrFail($customerId);
        $contractId = Contract::findOrFail($contractId);
        $invoice = Invoice::findOrFail($invoiceId);
    
        // ...
      }
    }
    
    Laravel은 Route model binding을 사용하여 모델을 처리하여 얻을 수 있습니다.저항은 헛수고...
    use App\Customer;
    use App\Contract;
    use App\Invoice;
    
    class CustomerContractInvoiceController extends Controller {
      public function show(Request $request, Customer $customer, Contract $contract, Invoice $invoice) {
        $customerName = $customer->name;
    
        // ...
      }
    }
    
    이렇게 하면 너는 웅변의 모형을 직접 사용할 수 있다.이를 위해 모델이 $primaryKey이 아닌 경우 Laravel은 모델에 id 속성을 정확하게 지정해야 합니다.
    use Illuminate\Database\Eloquent\Model;
    
    class Customer extends Model {
      protected $primaryKey = 'customerId';
    }
    
    

    4. 중앙 집중식 오류 처리


    나는 컨트롤러의 오류를 검사하는 것에 이미 싫증이 났다.
    use Validator;
    use Session;
    
    class NewsletterController extends Controller {
      public function store(Request $request) {
        $validator = new Validator($request->all(), [
          'email' => 'required|email'
        ]);
    
        if ($validator->fails) {
          return redirect()->back()->withInput()->withErrors($validator);
        }
    
        Session::flash('success', 'We publish each week so stay tuned!');
    
        return redirect()->route('newsletter.success');
      }
    }
    
    따라서 전역 Error handling을 폼 요청을 이용한 이상으로 설정합니다.이 작업을 수행하려면 app/Exceptions/Handler.php으로 이동하십시오.
    class Handler extends ExceptionHandler {
      public function report(Exception $exception) {
        // This is where you log to your error dashboard like Sentry, ...
    
        parent::report($exception);
      }
    
      public function render($request, Exception $exception) {
        // Here we manage errors globally
      }
    }
    
    그래서 우리가 맞춤형으로 만들고 싶은 방법은 render이다.보고서는 Sentry과 같은 오류 관리 응용 프로그램에 알림을 전송하기에 매우 적합하다.
    검증 오류를 전체적으로 처리합시다.
    use Illuminate\Validation\ValidationException;
    
    class Handler extends ExceptionHandler {
      public function report(Exception $exception) {
        // This is where you log to your error dashboard like Sentry, ...
    
        parent::report($exception);
      }
    
      public function render($request, Exception $exception) {
        if ($exception instanceof ValidationException) {
          return redirect()->back()->withInput()->withErrors($exception->errors());
        }
      }
    }
    
    한 번의 촬영에서 내비게이션과 AJAX 오류를 관리할 수도 있습니다.
    use Illuminate\Validation\ValidationException;
    
    class Handler extends ExceptionHandler {
      public function report(Exception $exception) {
        // This is where you log to your error dashboard like Sentry, ...
    
        parent::report($exception);
      }
    
      public function render($request, Exception $exception) {
        // The request have a "Accept: application/json"
        // This is an AJAX request
        if ($request->wantsJson()) {
          if ($exception instanceof ValidationException) {
            return response()->json($exception->errors(), 400);
          }
        }
        // This is a normal form validation 
        else {
          if ($exception instanceof ValidationException) {
            return redirect()->back()->withInput()->withErrors($exception->errors());
          }      
        }
      }
    }
    

    5. 소장...어디서나 볼 수 있는 모음집


    PHP에 대해 유감스럽게도 대상 프로그래밍이 부족합니다.Javascript의 유행은 매우 멋있다.
    const popularPosts = posts.filter(post => post.views > 5000)->map(post => post.title);
    
    Laravel에서 가장 좋은 기능 중 하나는 집합이다.웅변의 모형이 이렇게 편리해지면 우리는 많은 일을 유창하게 집행할 수 있다.
    use App\Post;
    
    $popularPosts = Post::all()->filter(function($post) { 
      return $post->views > 5000;
    })->map(function($post) {
      return $post->title;
    });
    
    너는 심지어 웅변의 용법 이외에도 그것을 사용할 수 있다.
    $menus = [
      [ 'placement' => 'left', 'text' => 'Home' ],
      [ 'placement' => 'left', 'text' => 'About us' ],
      [ 'placement' => 'right', 'text' => 'Contact' ]
    ];
    
    $rightMenus = collect($menus)->filter(function($menu) {
      return $menu['placement'] === 'right';
    });
    

    6. 자원 분해 노선 활용


    나는 이것이 너에게 일어났는지 모르겠지만, 한 번은 내가 업무 중에 웹 응용 프로그램을 구축했는데, 나의 routes/web.php은 이렇게 변했다.
    // routes/web.php
    
    Route::get('/customer', 'CustomerController@index');
    Route::get('/customer/create', 'CustomerController@create');
    Route::get('/customer/{id}', 'CustomerController@show');
    Route::get('/customer/{id}/edit', 'CustomerController@edit');
    Route::get('/customer/{id}/delete', 'CustomerController@delete');
    Route::get('/customer/{id}/phone', 'CustomerPhoneController@index');
    Route::get('/customer/{id}/phone/create', 'CustomerPhoneController@create');
    Route::get('/customer/{customerId}/phone/{phoneId}', 'CustomerPhoneController@show');
    Route::get('/customer/{customerId}/phone/{phoneId}/edit', 'CustomerPhoneController@edit');
    
    Route::post('/customer', 'CustomerController@store');
    Route::post('/customer/{id}/phone', 'CustomerPhoneController@store');
    
    Route::put('/customer/{id}', 'CustomerController@update');
    Route::put('/customer/{customerId}/phone/{phoneId}', 'CustomerPhoneController@update');
    
    Route::delete('/customer/{id}', 'CustomerController@destroy');
    Route::delete('/customer/{customerId}/phone/{phoneId}', 'CustomerPhoneController@destroy');
    
    ... 이것은 발췌문이다.나는 또한 고객 주소, 고객 이메일, 고객 회사, 고객 계약, 고객 계약 영수증을 관리한다...

    다행히도 라레빌은 Resources controllers을 지지했다.
    // routes/web.php
    
    Route::resource('customer', 'CustomerController');
    Route::resource('customer.phone', 'CustomerPhoneController');
    
    드디어 신선한 공기가 생겼어요...
    참고 자료는 첫 번째 매개 변수를 4개의 일반적인 HTTP 방법에 자동으로 연결하여 작동합니다.하면, 만약, 만약...
    php artisan route:list
    
    다음 출력을 얻을 수 있습니다.
    영역
    방법
    URI
    이름
    행동
    중간부품
    얻다
    고객
    손님지수
    응용 프로그램\Http\컨트롤러\CustomerController@index
    그물 모양
    얻다
    /고객/{customer}
    손님표시
    응용 프로그램\Http\컨트롤러\CustomerController@show
    그물 모양
    얻다
    /고객/{customer/편집
    손님편집하다
    응용 프로그램\Http\컨트롤러\CustomerController@edit
    그물 모양
    얻다
    /고객/{customer}/전화
    손님전화기지수
    응용 프로그램\Http\컨트롤러\CustomerPhoneController@index
    그물 모양
    얻다
    /고객/{customer/phone/{phone}
    손님전화기표시
    응용 프로그램\Http\컨트롤러\CustomerPhoneController@show
    그물 모양
    얻다
    /고객/{customer}/phone/{phone}/edit
    손님전화기편집하다
    응용 프로그램\Http\컨트롤러\CustomerPhoneController@edit
    그물 모양
    직책
    고객
    손님백화점
    응용 프로그램\Http\컨트롤러\CustomerController@store
    그물 모양
    직책
    /고객/{customer}/전화
    손님전화기백화점
    응용 프로그램\Http\컨트롤러\CustomerPhoneController@store
    그물 모양
    PUT, 패치
    /고객/{customer}
    손님현대화하다
    응용 프로그램\Http\컨트롤러\CustomerController@update
    그물 모양
    PUT, 패치
    /고객/{customer}/phone/{phone}
    손님전화기현대화하다
    응용 프로그램\Http\컨트롤러\CustomerPhoneController@update
    그물 모양
    삭제
    /고객/{customer}
    손님파괴하다
    응용 프로그램\Http\컨트롤러\CustomerController@destroy
    그물 모양
    삭제
    /고객/{customer}/phone/{phone}
    손님전화기파괴하다
    응용 프로그램\Http\컨트롤러\CustomerPhoneController@destroy
    그물 모양
    마찬가지로 Laravel은 지원을 제공하기 때문에 이 명령줄로 자원 컨트롤러를 만들 수 있습니다.
    php artisan make:controller CustomerController --resource
    
    이것은 자동으로 상술한 방법을 만들 것입니다!
    // app/Http/Controllers/CustomerController.php
    
    use Illuminate\Http\Request;
    
    class CustomerController extends Controller
    {
      public function index() {}
    
      public function create() {}
    
      public function store(Request $request) {}
    
      public function show($id) {}
    
      public function edit($id) {}
    
      public function update(Request $request, $id) {}
    
      public function destroy($id) {}
    }
    
    
    화목하다모델을 만들면 리소스 모드에서 관련 컨트롤러를 만들 수도 있습니다. 그러면 Laravel에서 프롬프트 컨트롤러를 입력할 수 있습니다.
    php artisan make:model Customer --resource --controller
    
    // app/Http/Controllers/CustomerController.php
    
    use App\Customer;
    use Illuminate\Http\Request;
    
    class CustomerController extends Controller
    {
      public function index() {}
    
      public function create() {}
    
      public function store(Request $request) {}
    
      public function show(Customer $customer) {}
    
      public function edit(Customer $customer) {}
    
      public function update(Request $request, Customer $customer) {}
    
      public function destroy(Customer $customer) {}
    }
    

    7. 변이체를 띤 정익 코드


    때때로 혼합 기록된 여러 필드는 의미 있는 내용을 만드는 데 도움이 된다.예를 들어, 고객 보기에서:
    <!-- resources/views/customer/show.blade.php -->
    
    @extends('layout/logged')
    @section('content')
      <h1>viewing customer {{ $customer->firstName }} {{ $customer->lastName }}</h1>
    @endsection
    
    변체는 당신의 추상적인 업무 논리를 도울 것입니다.
    // app/Customer.php
    
    use Illuminate\Database\Eloquent\Model;
    
    class Customer extends Model {
      protected $table = 'customer';
    
      public function getNameAttribute() {
        return "{$this->firstName} {$this->lastName}";
      }
    }
    
    $customer->name 속성에 접근하려면 public function get<yourattribute>Attribute() {} 형식으로 상술한 함수를 만들어야 합니다.설득력 있는 모형을 수집할 때, 라레빌은 당신에게 이 속성을 제공할 것입니다.
    <!-- resources/views/customer/show.blade.php -->
    
    @extends('layout/logged')
    @section('content')
      <h1>{{ $customer->name }}</h1>
    @endsection
    
    더 좋은 것은 데이터베이스에서 제출한 데이터를 변환할 수 있다는 것이다.
    고객 테이블에는 wantsNewsletter이라는 부울 필드가 있습니다.알고 있는 바와 같이 MySQL에는 부울 유형이 없으므로 다음 시뮬레이션에 사용됩니다.
    wantsNewsletter TINYINT(1) NOT NULL DEFAULT 0
    
    false은 0true으로 1입니다.웅변의 모형에서 라라빌에게 부울 값으로 바꾸라고 요구할 수 있습니다.
    // app/Customer.php
    
    use Illuminate\Database\Eloquent\Model;
    
    class Customer extends Model {
      protected $table = 'customer';
      protected $casts = [
        'wantsNewsletter' => 'boolean'
      ];
    
      public function getNameAttribute() {
        return "{$this->firstName} {$this->lastName}";
      }
    }
    
    이제 삼중 상등 연산자를 사용하여 검증을 수행할 수 있습니다.
    // app/Console/Commands/SendNewsletter.php
    
    use Illuminate\Console\Command;
    use App\Mail\NewsletterMail;
    use App\Customer;
    
    class SendNewsletter extends Command {
      protected $signature = 'newsletter:send';
    
      public function handle() {
        $customers = Customer::all();
    
        $customers = $customers->filter(function($customer) {
          $customer->wantsNewseletter === true;
        });
    
        foreach($customers as $customer) {
          Mail::to($customer->email)->send(new NewsletterMail($customer));
        }
      }
    }
    

    결론


    이 모든 것이 압도적일 수도 있다.이런 것들을 연속적으로 적용하지 마라.코드 라이브러리를 개선하기 위해 당신이 옳다고 생각하는 것과 무엇을 할 수 있는지 균형을 잡으세요.
    Vuex website에서 참조를 수정하려면 다음과 같이 하십시오.

    These tips are like glasses: You will know when you need it.


    나는 네가 내가 이런 기교를 배울 때처럼 놀라길 바란다.만약 당신이 새로운 것을 배웠다면, 만약 내가 열거하지 않은 다른 기교가 있다면, 혹은 내가 이 기교로 더 잘 할 수 있다면, 평론에서 나에게 알려주세요.
    유쾌한 최적화!
    사진은 nappy에서 Pexels으로 촬영되었습니다.

    좋은 웹페이지 즐겨찾기