[PHP] Trait에 구조기를 만들면 호칭이 안 될 수도 있어 좋지 않아

9367 단어 PHPLaraveltrait

개시하다


PHP에는 "Trait"기능이 있습니다.
보통 클래스는 하나의 클래스만 계승할 수 있지만trait를 사용하면 여러 클래스의 변수와 함수 등을 사용할 수 있기 때문에 매우 편리하다.(대략적인 설명)
그러나 실제 인코딩을 해보니trait의 구조기에 대해서는 조금 주의를 기울이는 것이 좋다.
트레이트의 구조기는 실제 조립 방법에 의해 불리지 않을 가능성이 높기 때문이다.

확인


실제로 검증해 봤습니다.이번에는 라벨을 채택한다.

하고 싶은 일


학급, 추상류,trait에 각각 구조기를 설치하고 각양각색의 구조기를 실행한다

모드 1: 추상 클래스와trait 동시 구현


우선 추상류와trait를 만들어 보자.
ModelBase.php
<?php
namespace App;

abstract class ModelBase{
    public function __construct(){
        echo 'call ModelBase ';
    }
}
ModelTrait.php
<?php
namespace App;

trait ModelTrait{
    public function __construct(){
        echo 'call ModelTrait ';
    }
}
모든 것은 echo에 정보를 표시하기만 하면 된다.
Model 클래스에서 이러한 항목을 호출합니다.부모반과trait에 설치된 구조기를 호출하고 싶습니다.parent:construct();실행됨.
Model.php
<?php
namespace App;

class Model extends ModelBase{
    use ModelTrait;

    public function __construct(){
        echo 'call Model ';

        parent::__construct();
    }
}
그런 다음 페이지를 표시합니다.
web.php
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    new \App\Model();
    return view('welcome');
});
이 작업을 수행하면 다음과 같이 표시됩니다.

왼쪽 상단에는 "cal Model"및 "cal ModelBase"가 표시됩니다.(너무 얇아서 미안합니다.)
그러나 "call ModelTrait"는 표시되지 않습니다.
「parent::__construct();」부모로서의 모델 베이스가 실행되지만, 모델 트레이트는 실행되지 않는 것 같습니다.
이렇게 말하는 것은 당연한 것일 수도 있지만, 한번 해 보면 적당하다고 느낀다.

모드 2:trait만


이번에는 ModelBase를 계승하지 않고 ModelTrait만 실시합니다.
Model.php
<?php
namespace App;

//class Model extends ModelBase{
class Model{
    use ModelTrait;

    public function __construct(){
        echo 'call Model ';

        parent::__construct();
    }
}
이러면 어떻게 되는 거예요?결과는 다음과 같다.

슬프게도 잘못이 생겼다.
잘못된 내용은'Cannet access parent: when current class scope has no parent'이며'부모가 없다'는 오류입니다.
parent는 extends에서만 사용할 수 있고trait는 안 될 것 같습니다.서운하다

모드3:parent:construct();삭제


parent::__construct();삭제합니다.
Model.php
<?php
namespace App;

//class Model extends ModelBase{
class Model{
    use ModelTrait;

    public function __construct(){
        echo 'call Model ';

        //parent::__construct();
    }
}

왼쪽 상단에는'call Model'만 있고'call Model Trait'는 없습니다.
완전히construct 함수를 초과한 것 같습니다.그래서 트레이트 쪽 구조기라고 할 수는 없어요.

모드 4: 모델 구조자 자체 삭제


Model의 구조기 자체를 삭제해 보십시오.
Model.php
<?php
namespace App;

//class Model extends ModelBase{
class Model{
    use ModelTrait;

    //public function __construct(){
    //    echo 'call Model ';
    //
    //    parent::__construct();
    //}
}


이렇게 하면 마침내 "call ModelTrait"이 표시됩니다.
하지만 기존 모델측 구조기 쪽이 사라진 만큼 본말이 뒤바뀐 것이다.

(추가) 모드 5: 별칭


@mpyw 댓글에 쓰여있다!!정말 고맙습니다.
별명으로 해결한다고 들었습니다.
Model.php
<?php
namespace App;

class Model extends ModelBase
{
    use ModelTrait {
        ModelTrait::__construct as traitConstructor;
    }

    public function __construct()
    {
        echo 'call Model ';

        $this->traitConstructor();     
    }
}


이렇게 해서 마침내 가장 하고 싶었던'콜 모델 콜 모델 트레이트'(call Model Call Model Trait)를 보여준다.
정말 감사합니다!

이번에 배운 것


원래'어떤 포장 안의 분류를 계승하여 클래스를 실현한다'는 처리를 할 때'공통 처리와 공통 변수를 간단하게 실시할 수 없기 때문에trait를 사용해 보았다.
하지만 트위터에 올라온 댓글을 보면 트레이트는 구조기를 갖기에 적합하지 않은 것 같다. 단순히 처리·함수를 공통화해서 사용하는 것이 좋다.
'라벨 포장이라도 트라이트에 구조기를 절대 못 끼게 한다'는 평도 있다.
그래서 이번 용도에서 트레이트를 솔직하게 멈추고 원래 반에서만 지도원과 변수를 갖게 하기로 했습니다.
어떻게든 유니버설 프로세서나 변수 구조기를 사용하고 싶다면 어떤 포장 내의 반을 계승하여 추상류를 만들고 거기에 공통 변수 등을 써라.
그리고 이 추상류를 계승하여 반을 만드는 순서가 필요하다.(원래 이렇게 해야 한다.)
많이 배웠어요.감사합니다!

좋은 웹페이지 즐겨찾기