베스트 프랙티스: PHP Magic 메서드 __set 및 __get
이것들은 단순한 예이지만, 여러분이 학급에 두 개보다 더 많은 속성을 가지고 있다고 상상해 보세요.
베스트 프랙티스는 무엇입니까?
a) __get 및 __set 사용
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;
}
}
}
$myClass = new MyClass();
$myClass->firstField = "This is a foo line";
$myClass->secondField = "This is a bar line";
echo $myClass->firstField;
echo $myClass->secondField;
/* Output:
This is a foo line
This is a bar line
*/
b) 기존 세터 및 게터 사용
class MyClass {
private $firstField;
private $secondField;
public function getFirstField() {
return $this->firstField;
}
public function setFirstField($firstField) {
$this->firstField = $firstField;
}
public function getSecondField() {
return $this->secondField;
}
public function setSecondField($secondField) {
$this->secondField = $secondField;
}
}
$myClass = new MyClass();
$myClass->setFirstField("This is a foo line");
$myClass->setSecondField("This is a bar line");
echo $myClass->getFirstField();
echo $myClass->getSecondField();
/* Output:
This is a foo line
This is a bar line
*/
이 기사 : http://blog.webspecies.co.uk/2011-05-23/the-new-era-of-php-frameworks.html
저자는 마법의 방법을 사용하는 것은 좋은 생각이 아니라고 주장한다.
우선 당시에는 PHP의 마법 기능(_get, __call 등)을 사용하는 것이 매우 인기가 있었습니다.그들은 언뜻 보기에는 아무 문제가 없지만, 실제로는 매우 위험하다.API가 불분명하고 자동 완성이 불가능하며 가장 중요한 것은 API 속도가 느립니다.그들의 사용 사례는 원치 않는 일을 하기 위해 PHP를 해킹하는 것이었습니다.그리고 그것은 성공하였다.하지만 나쁜 일이 생기게 했어
하지만 나는 이것에 대해 더 많은 의견을 듣고 싶다.
나는 예전에도 정확히 너의 경우였다.그리고 나는 마법의 방법을 택했다.
이것은 실수였습니다.질문의 마지막 부분은 모든 것을 나타내고 있습니다.
- (게터/세터보다) 느리다
- 자동완성은 없습니다(실제로 이것은 큰 문제입니다).또한 리팩터링과 코드브라우징을 위한 IDE에 의한 유형관리(Zend Studio/PhpStorm에서 이 작업은
@property, 이것은합니다. phpdoc 주석: 꽤스럽습니다.) phpdoc 주석, phpdoc 주석. - 문서(phdoc)가 코드 사용 방법과 일치하지 않으며 클래스를 살펴봐도 답이 많지 않습니다.이거 헷갈리네.
- 편집 후 추가: 속성에 대한 getter를 갖는 것이 "실제" 메서드와 더 일치합니다.
getXXX()사유재산을 반환하는 것뿐만 아니라 진짜 논리를 펴는 것입니다.이름이 똑같아요.를 들면, 「 」라고 하는 것이 있습니다.$user->getName()및 (사유재산)$user->getToken($key)보다 더 것을 어떤 날, 모든 일관성이 있다.당신의 게터가 게터보다 더 많은 것을 얻고 어떤 논리를 구사할 필요가 있는 날, 모든 것은 여전히 일관성이 있다.
마지막으로, 이것이 IMO의 가장 큰 문제입니다.이것은 마술입니다.마술은 매우 나쁜 것입니다마술을 제대로 사용하기 위해서는 마법을 알아야 하기 때문입니다그건 내가 팀에서 만난 문제야. 너뿐만 아니라 모두가 마법을 이해해야 해.
게터나 세터는 쓰기 귀찮지만(나는 그것들을 싫어하지만) 그만한 가치가 있다.
물체가 정말 "마법적"인 경우에만 마법을 사용하면 됩니다.고정 속성을 가진 클래식한 객체가 있는 경우 세터 및 게터를 사용하면 올바르게 작동합니다.
오브젝트가 데이터베이스 추상화 층의 일부이고 파라미터가 런타임에 설정되어 있는 경우 편리성을 위해 마법 메서드가 필요합니다.
용 i i i i를 쓴다.__get(및 공공재산은) 가능한 한 많이 사용합니다. 왜냐하면 그것들은 코드를 훨씬 더 쉽게 읽을 수 있게 해주기 때문입니다.★★★★
이 코드는 분명히 내가 뭘 하고 있는지 말해준다.
echo $user->name;
이 코드는 날 바보처럼 느끼게 해 하지만 난 그걸 즐기지 않아
function getName() { return $this->_name; }
....
echo $user->getName();
두 가지 속성 간의 차이는 한 번에 여러 속성에 액세스할 때 특히 두드러집니다.
echo "
Dear $user->firstName $user->lastName!
Your purchase:
$product->name $product->count x $product->price
"
그리고.
echo "
Dear " . $user->getFirstName() . " " . $user->getLastName() . "
Your purchase:
" . $product->getName() . " " . $product->getCount() . " x " . $product->getPrice() . " ";
★★의 유무$a->b정말로 무언가를 해야 하거나 값을 반환해야 하는 것은, 착신측의 책임입니다.발신자의 경우,$user->name ★★★★★★★★★★★★★★★★★」$user->accountBalance후자의 경우 복잡한 계산이 수반될 수 있지만 동일하게 보일 수 있습니다.데이터 클래스에서는 다음과 같은 작은 방법을 사용합니다.
function __get($p) {
$m = "get_$p";
if(method_exists($this, $m)) return $this->$m();
user_error("undefined property $p");
}
했을 때$obj->xxx 클래스에는 '반'이 있습니다.get_xxx정의된 경우 이 메서드는 암묵적으로 호출됩니다.따라서 필요에 따라 getter를 정의하면서 인터페이스를 균일하고 투과적으로 유지할 수 있습니다.추가 보너스로는 계산을 외우는 우아한 방법을 제공합니다.
function get_accountBalance() {
$result = <...complex stuff...>
// since we cache the result in a public property, the getter will be called only once
$this->accountBalance = $result;
}
....
echo $user->accountBalance; // calculate the value
....
echo $user->accountBalance; // use the cached value
결론: php는 동적 스크립트 언어이므로 Java 또는 C#을 실행하는 척하지 마십시오.
나는 세 번째 해결책에 투표한다.저는 이것을 제 프로젝트에서 사용하고 Symfony도 다음과 같은 것을 사용합니다.
public function __call($val, $x) {
if(substr($val, 0, 3) == 'get') {
$varname = strtolower(substr($val, 3));
}
else {
throw new Exception('Bad method.', 500);
}
if(property_exists('Yourclass', $varname)) {
return $this->$varname;
} else {
throw new Exception('Property does not exist: '.$varname, 500);
}
}
이렇게 하면 자동 getter(setters도 쓸 수 있음)를 사용할 수 있으며, 멤버 변수에 특별한 케이스가 있는 경우에만 새로운 메서드를 쓸 수 있습니다.
방법에서는 일반적인), 따라 할 수 있는 , 하지 않는 속성(오타 에(Getters) 의 이점을 얻을 수$foo->naem$foo->name속성 및 컴파운드 속성만 읽습니다.
class Foo
{
private $_bar;
private $_baz;
public function getBar()
{
return $this->_bar;
}
public function setBar($value)
{
$this->_bar = $value;
}
public function getBaz()
{
return $this->_baz;
}
public function getBarBaz()
{
return $this->_bar . ' ' . $this->_baz;
}
public function __get($var)
{
$func = 'get'.$var;
if (method_exists($this, $func))
{
return $this->$func();
} else {
throw new InexistentPropertyException("Inexistent property: $var");
}
}
public function __set($var, $value)
{
$func = 'set'.$var;
if (method_exists($this, $func))
{
$this->$func($value);
} else {
if (method_exists($this, 'get'.$var))
{
throw new ReadOnlyException("property $var is read-only");
} else {
throw new InexistentPropertyException("Inexistent property: $var");
}
}
}
}
번째 는 훨씬 더이에요. 이 코드 예제는 '부터'에 때문입니다. 왜냐하면 사용자는 다음과 같이 지정된 데이터를 완전히 제어할 수 있기 때문입니다.class가.러한, 한한, 한한, 한한, 한한__set그리고.__get유용하지만 이 경우에는 그렇지 않습니다.
매직 멤버를 원하는 경우 stdClass를 사용해야 합니다.클래스를 작성할 경우 클래스를 포함하는 내용을 정의합니다.
가장 좋은 방법은 자기성찰이나 성찰 때문에 전통적인 게터나 세터를 사용하는 것입니다.(Java와 똑같이) PHP에는 메서드 또는 모든 메서드의 이름을 얻는 방법이 있습니다.이러한 경우 첫 번째 케이스에서는 "_get"이 반환되고 두 번째 케이스에서는 "get First Field", "get Second Field"가 반환됩니다(및 세터).
자세한 것은, http://php.net/manual/en/book.reflection.php 를 참조해 주세요.
지금은 세터와 게터로 돌아가지만 세터와 세터를 마법의 메토 __get과 __set에 넣고 있습니다.이렇게 하면 기본 동작이 됩니다.
$class->var;
이렇게 하면 __get에 설정한 getter가 호출됩니다.보통 Getter를 직접 사용하지만, 이 방법이 더 간단한 경우도 있습니다.
언급URL : https://stackoverflow.com/questions/6184337/best-practice-php-magic-methods-set-and-get
'source' 카테고리의 다른 글
| String과 동등합니다.jQuery 형식 (0) | 2022.12.01 |
|---|---|
| MySQL 오프셋 무한 행 (0) | 2022.12.01 |
| JavaScript 변수에 PHP 문자열 전달(및 줄바꿈 이스케이프) (0) | 2022.12.01 |
| 휴지 상태 4에서5로의 이행 (0) | 2022.12.01 |
| Java - 이미지에서 픽셀 배열 가져오기 (0) | 2022.12.01 |