PHP에서 클래스 멤버를 초기화하는 가장 좋은 방법


10

내 생성자에 이와 같은 코드가 많이 있습니다.

function __construct($params) {

    $this->property = isset($params['property']) ? $params['property'] : default_val;

}

속성 정의에서 기본값을 지정하는 것보다이 작업을 수행하는 것이 더 낫습니까? 즉 public $property = default_val? 때로는 기본값에 대한 논리가 있으며 일부 기본값은 다른 속성에서 가져 왔으므로 생성자 에서이 작업을 수행 한 이유입니다.

기본값에 대한 모든 논리가 분리되도록 설정기를 사용해야합니까?

답변:


8

나는 전에 이런 종류의 철학적 토론을 해왔다. 이것이 의견에 기반한 답변이라는 것을 알고 있지만 대부분의 시간을 보내는 곳입니다.

내가 질문에 대답하는 데 도움이 될 수있는 한 가지는 속성 / 배열 구성원이 설정되어 있거나 없을 수있는 $ params의 전달입니다.

수년에 걸쳐 나는이 결론에 도달했다.

배열의 통과를 피하십시오.

왜? 선택적 전달 인수에 대해 센티넬 값을 정의하거나 정의 할 방법이 없습니다.

즉, 지정한 코드를 사용하면 다음과 같은 작업을 수행 할 수 없습니다.

function __construct($arg1 = NULL, $arg2 = DEFAULT_VAL) {

    $this->arg1 = $arg1;

    $this->arg2 = $arg2;

}

$ arg1 및 $ arg2는 선택적 인수입니다. 전달되지 않은 경우 각각 NULL 및 DEFAULT_VAL이 있으므로 명시 적으로 확인할 필요가 없습니다.

아마도 이것은 임의의 것 같습니다.

나는 당신이 성취하려고하는 것을 얻는다고 생각합니다-수많은 주장과 달리 단일 참조의 전달. 이것은 다음의 결론에 이르게합니다.

"원자"변수 (문자열, 정수, 리터럴)를 전달하지 않으면 객체를 전달합니다.

객체 전달은 참조로 수행되므로 성능상의 이점이 있습니다 (배열은 PHP와 거의 동일하다고 생각하지만).

따라서 다음과 같은 작업을 수행 할 수 있습니다.

function __construct(MyAwesomeObject $oArg) {

        $this->oArg = $oArg;

    }

전달 된 객체 인수는 "property1", "property2"를 가질 수 있지만 기본값 자체는 가능합니다.

또한 여기에 힌트를 입력하면 좋은 IDE가 코드 완성을 자동으로 제안합니다.

그러나 우리는 닭과 달걀이 진행되고 있다는 것을 빨리 깨닫고 있습니다.

그럼 어디로 우리를 떠나? 글쎄, 나는 결국 모든 클래스가 "원자"변수 (문자열, 플로트, 더블, 정수, 내 요점을 얻는 자원)가 더 나은 용어가 없기 때문에 증류되고 결국 시도하는 경향이 있다는 결론에 도달했다. 변수 유형이나 객체로 배열을 제외한 모든 클래스를 구성합니다.

질문에 대답 했습니까? 아마 정확하지 않을 것입니다. 그러나 나는 비록 스타일이 있지만 유용한 것을 보여 주길 바랍니다. 코드가 좀 더 깔끔하고 읽기 쉽고 비용이 덜 든다고 생각합니다.

지금, 이것은 당신이 당신의 입력을 소독해서는 안된다는 말이 아닙니다. 그것은 또 다른 토론입니다.

도움이 되었기를 바랍니다.


1
좋은 지적이며 IDE 프롬프트에 매우 편리하지만 매개 변수로 전달할 수있는 개체 속성이 너무 많습니다. 7 개의 인수가 5 개가 선택적이라고하면 7 개의 인수는 다음과 같은 것으로 끝나 new object($param1,-some default value so I can specify the next parameter-, $param3);므로 기본값은 여러 다른 위치에 하드 코딩되어 있습니다
rgvcorley

3

배열을 생성자에 전달하지 않는 경향이 있지만 때로는 구성 파일에서 값을 읽는 클래스와 같이 들어오는 배열 값을 처리 해야하는 경우가 있습니다.

이 경우 PHP의 배열 함수를 사용하여 내가 생각하는 것과 정확히 일치하는지 확인합니다.

public function import( array $incoming )
{
  $defaults = array(
      'foo' => DEFAULT_FOO
    , 'bar' => DEFAULT_BAR
    ...
  );

  $values = array_merge($defaults, array_intersect_key($incoming, $defaults));

  ...
}

마지막 줄은 array_merge()에서 $defaults해당하는 값으로 값을 덮어 쓰는 데 사용 됩니다 $incoming. 또한 array_intersect_key()결과 배열에 클래스 / 메서드가 처리 방법을 알지 못하는 추가 키가 포함되지 않도록하는 데 사용합니다.


안녕하세요, $ defaults에 간단한 변수 대신 배열이 포함되어 있으면 어떻게됩니까?
Pol Dellaiera

@PolDellaiera를보십시오 array_merge_recursive.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.