PHP의 값 유형 구조 클래스 에뮬레이션
-
18-09-2019 - |
문제
PHP에서 구조 클래스를 모방하는 방법이 있습니까? 즉, 참조가 아닌 가치별로 전달되는 클래스이므로 여전히 유형 힌트를받을 수 있습니다 ...
그렇다면 어떤 다른 기술을 사용할 수 있습니까? 최고의 기술은 무엇입니까?
이것이 가능하다면 분명히 PHP를위한 완전한 유형의 안전 레이어를 만들 수 있습니다. 그러한 층이 있습니까? 이것에 대한 경험이있는 사람이 있습니까?
해결책
객체는 항상 참조로 전달됩니다. 사본으로 통과시키는 유일한 방법은 명시 적으로 사용하는 것입니다. clone
키워드 (예, 어디서나).
내 권장 사항은 값 유형이므로 항상 복사하는 배열을 사용하는 것입니다. 연관 배열 (예 : 문자열 -> 값)으로 사용할 수 있으므로 객체 일 수도 있습니다. 단점은 물론 방법을 사용할 수 없다는 것입니다 (그러나 그것은 구조물과 같아서 이것에 만족할 수 있습니다). 그러나 유형 안전을 시행 할 방법은 없습니다.
그러나 모든 요구 사항을 통해 PHP가 당신의 언어가 아니라 정직한 것처럼 들립니다.
다른 팁
가장 쉬운 방법은 Java처럼 수행하는 것입니다. 가치 클래스를 불변으로하고 모든 "수정"방법을 대신 새 객체를 반환하도록하십시오.
PHP 코드만으로도 그 목표를 달성 할 수 있다고 생각하지 않습니다.
PHP 기능이 매개 변수를 처리하는 방법을 제어 할 수 없으며 PHP 바이너리 및 모듈에서 (하위 레벨) 코드를 변경하지 않고 원하는 방식으로 모든 것이 처리 될 수 있는지 알 수 없습니다.
그래도 꽤 시원 할 것입니다 :)
나는 객체의 돌연변이를 새로운 대상으로 되 돌리기 위해 익명의 제안을 가지고 놀았습니다. 그러나 이것은 작동하지만 어색합니다.
<?php
class FruityEnum {
private $valid = array("apple", "banana", "cantaloupe");
private $value;
function __construct($val) {
if (in_array($val, $this->valid)) {
$this->value = $val;
} else {
throw new Exception("Invalid value");
}
}
function __set($var, $val) {
throw new Exception("Use set()!!");
}
function set(FruityEnum &$obj, $val) {
$obj = new FruityEnum($val);
}
function __get($var) { //everything returns the value...
return $this->value;
}
function __toString() {
return $this->value;
}
}
그리고 지금 테스트하기 위해 :
function mutate(FruityEnum $obj) { // type hinting!
$obj->set($obj, 'banana');
return $obj;
}
$x = new FruityEnum('apple');
echo $x; // "apple"
$y = mutate($x);
echo $x // still "apple"
. $y // "banana"
작동하지만 이상한 방법을 사용하여 개체를 변경해야합니다.
$obj->set($obj, 'foo');
내가 생각할 수있는 유일한 방법은 __set()
방법, 그러나 그것은 훨씬 더 나빴습니다. 피의 혼란스러운 일을해야했습니다.
$obj = $obj->blah = 'foo';
결국, 변수를 비공개로 만들고 뮤지터를 제공하지 않는 것이 더 쉽기 때문에 변수의 "ENUM"값을 변경하는 유일한 방법은 새로운 것을 만드는 것입니다.
echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");