저는 PHP 개발자가 아니기 때문에 PHP에서 명시적인 getter/setter를 순수한 OOP 스타일로 사용할 경우의 장점과 단점은 무엇인지 궁금합니다(제가 좋아하는 방식).
class MyClass {
private $firstField;
private $secondField;
public function getFirstField() {
return $this->firstField;
}
public function setFirstField($x) {
$this->firstField = $x;
}
public function getSecondField() {
return $this->secondField;
}
public function setSecondField($x) {
$this->secondField = $x;
} }
또는 퍼블릭 필드만:
class MyClass {
public $firstField;
public $secondField; }
질문에 대한 답변
php magic 메서드를 사용할 수 있습니다. __get
그리고.__set
.
<?php class MyClass {
private $firstField;
private $secondField;
public function __get($property) {
if (property_exists($this, $property)) {
return $this->$property;
}
}
public function __set($property, $value) {
if (property_exists($this, $property)) {
$this->$property = $value;
}
return $this;
} } ?>
왜 getter와 setter를 사용하는가?
- 확장성:프로젝트 코드의 모든 var 할당을 검색하는 것보다 getter를 재팩터화하는 것이 더 쉽습니다.
- 디버깅:세터나 게터에 브레이크 포인트를 둘 수 있습니다.
- 클리너: 매직 기능은 쓰기 횟수를 줄이는 데 적합하지 않습니다.IDE 에서는 코드를 제안하지 않습니다.빠른 쓰기 getter에는 템플릿을 사용하는 것이 좋습니다.
Google은 이미 PHP 최적화에 대한 가이드를 발행했고 결론은 다음과 같습니다.
getter 및 setter 없음 PHP 최적화
그리고 당신은 마법의 방법을 사용해서는 안됩니다.PHP에게 매직 메서드는 사악합니다. 왜일까요?
- 디버깅은 어렵습니다.
- 퍼포먼스에 부정적인 영향이 있습니다.
- 더 많은 코드를 작성해야 합니다.
PHP는 Java, C++ 또는 C#이 아닙니다.PHP는 다르며 다른 규칙을 사용합니다.
캡슐화는 어떤 OO 언어든 중요하며, 인기는 아무런 관련이 없습니다.PHP와 같은 동적 유형 언어에서는 특히 세터를 사용하지 않고 속성을 특정 유형으로 만들 수 있는 방법이 거의 없기 때문에 유용합니다.
PHP에서는 다음과 같이 동작합니다.
class Foo {
public $bar; // should be an integer } $foo = new Foo; $foo->bar = "string";
Java에서는 다음 기능이 없습니다.
class Foo {
public int bar; } Foo myFoo = new Foo(); myFoo.bar = "string"; // error
마법의 방법 사용(__get
그리고.__set
)도 동작합니다만, 현재 스코프가 액세스 할 수 있는 것보다 가시성이 낮은 속성에 액세스 하고 있는 경우 뿐입니다.올바르게 사용하지 않으면 디버깅을 시도할 때 두통이 생기기 쉽습니다.
__call 함수를 사용하는 경우 이 메서드를 사용할 수 있습니다.와 함께 동작합니다.
- GET = >
$this->property()
- SET = >
$this->property($value)
- GET = >
$this->getProperty()
- SET = >
$this->setProperty($value)
칼즈
public function __call($name, $arguments) {
//Getting and setting with $this->property($optional);
if (property_exists(get_class($this), $name)) {
//Always set the value if a parameter is passed
if (count($arguments) == 1) {
/* set */
$this->$name = $arguments[0];
} else if (count($arguments) > 1) {
throw new Exception("Setter for $name only accepts one parameter.");
}
//Always return the value (Even on the set)
return $this->$name;
}
//If it doesn't chech if its a normal old type setter ot getter
//Getting and setting with $this->getProperty($optional);
//Getting and setting with $this->setProperty($optional);
$prefix = substr($name, 0, 3);
$property = strtolower($name[3]) . substr($name, 4);
switch ($prefix) {
case 'get':
return $this->$property;
break;
case 'set':
//Always set the value if a parameter is passed
if (count($arguments) != 1) {
throw new Exception("Setter for $name requires exactly one parameter.");
}
$this->$property = $arguments[0];
//Always return the value (Even on the set)
return $this->$name;
default:
throw new Exception("Property $name doesn't exist.");
break;
} }