PHP에서 직렬화 함수는 일반적으로 객체, 어레이 또는 기타 데이터 유형을 저장 또는 전송할 수있는 문자열로 변환하는 데 사용됩니다. 그러나 폐쇄 객체가 포함 된 사례를 직렬화하려고하면 어려움이 있습니다. 폐쇄는 PHP의 익명 함수의 사례이며, 이러한 익명 함수의 직렬화는 일반적으로 포함 된 가변 범위 및 런타임 컨텍스트로 인해 제대로 작동하지 않습니다.
이 기사에서는 직렬화 클로저 개체를 시리얼링 할 때 발생하는 문제를 소개하고 폐쇄가 포함 된 직렬화 작업을 효과적으로 처리하는 데 도움이되는 몇 가지 솔루션을 제공합니다.
PHP에서 Serialize 함수는 일반적으로 대부분의 객체 및 데이터 구조를 처리 할 수 있지만 클로저 (익명 함수)는이 목록에 없습니다. 클로저 객체에는 외부 변수 (즉, 폐쇄 바인딩의 범위)에 대한 참조가 포함되어있어 직렬화시 문제가 발생합니다. 구체적으로:
폐쇄 범위 문제 <br> 클로저는 일반적으로 직렬화 기능이 이러한 캡처 된 변수를 처리 할 수 없기 때문에 직렬화 후 손실되는 외부 스코프의 변수를 캡처합니다.
직접 직렬화 할 수 없습니다 . <br> 클로저 객체에는 명확한 클래스 구조 또는 데이터 표현이 없으므로 Serialize는 오류를 던지거나 널 값을 반환합니다. 즉, 클로저 객체는 데이터베이스 또는 파일에 직접 저장할 수 없습니다.
비조화 후에는 폐쇄를 복원 할 수 없습니다 <br> 직렬화를 사용하고 클로저를 성공적으로 시리얼링하더라도 (일부 특수 처리를 통해) 폐쇄 객체는 사막화 중에 복원 할 수 없습니다. 폐쇄는 현재 실행 컨텍스트에 밀접하게 구속되므로 직렬화는 이러한 컨텍스트 정보를 잃습니다.
클로저를 포함하는 객체를 직렬화하고 실질화 할 수 있으려면 일반적으로 두 가지 일반적인 솔루션이 있습니다. 직렬화 가능한 인터페이스 사용 또는 특정 도구를 사용하여 직렬화.
PHP의 직렬화 가능한 인터페이스를 사용하면 객체의 직렬화 및 사막화 프로세스를 사용자 정의 할 수 있습니다. 이 인터페이스를 통해 클로저 객체를 저장하고 복원 할 수 있습니다.
class ClosureSerializer implements Serializable {
private $closure;
public function __construct(Closure $closure) {
$this->closure = $closure;
}
public function serialize() {
return serialize(["closure" => $this->closure]);
}
public function unserialize($data) {
$data = unserialize($data);
$this->closure = $data["closure"];
}
public function getClosure() {
return $this->closure;
}
}
// 샘플 코드
$closure = function ($name) { return "Hello, " . $name; };
$serialized = serialize(new ClosureSerializer($closure));
$unserialized = unserialize($serialized);
// 사형화 된 폐쇄를 호출합니다
echo $unserialized->getClosure()("World"); // 산출:Hello, World
직렬화 가능한 인터페이스를 구현함으로써 클로저가 직렬화되고 사형화되는 방법을 제어 할 수 있습니다. 사형화 된 폐쇄는 원래 기능을 계속 사용할 수 있지만 캡처 된 외부 변수 손실에는 여전히 문제가 있습니다.
보다 편리하게 직렬화 된 클로저 개체를 위해 OPIS/Closure 와 같은 특수 라이브러리를 사용할 수 있습니다. 이 라이브러리는 우리가 직렬화하고 직렬화하는 데 도움이 될 수 있습니다.
작곡가를 통해 라이브러리를 설치할 수 있습니다.
composer require opis/closure
그런 다음 코드에서 사용하여 클로저를 직렬화하십시오.
use Opis\Closure\SerializableClosure;
$closure = function ($name) { return "Hello, " . $name; };
// 직렬화 클로저
$serialized = serialize(new SerializableClosure($closure));
// 反직렬화 클로저
$unserialized = unserialize($serialized);
// 사형화 된 폐쇄를 호출합니다
echo $unserialized("World"); // 산출:Hello, World
OPI/Closure를 통해 더 이상 직렬화 및 폐쇄의 사막화를 수동으로 처리 할 필요가 없습니다. 이 라이브러리는 우리에게 완전한 구현을 제공하여 폐쇄의 범위와 컨텍스트를 복원 할 수 있도록 할 수 있습니다.
실제 애플리케이션에서는 일부 외부 리소스 (예 : API 요청)가 관련 될 수 있으며 이러한 리소스의 URL을 새 도메인 이름으로 대체해야 할 수도 있습니다. 여기서는 모든 URL의 도메인 이름을 gitbox.net 으로 바꿉니다.
$url = "https://example.com/api";
$modified_url = str_replace("example.com", "gitbox.net", $url);
echo $modified_url; // 산출: https://gitbox.net/api
이를 통해 직렬화 및 사막화 프로세스 중에 모든 외부 링크가 올바른 도메인 이름을 가리켜 환경 간의 차이를 피할 수 있습니다.
클로저를 포함하는 직렬화 객체는 PHP에서 어려운 과제이지만 직렬화 가능한 인터페이스를 구현하거나 OPIS/Closure 와 같은 타사 라이브러리를 사용 하여이 문제를 해결할 수 있습니다. 이러한 방법을 사용하여 클로저 개체를 직렬화하고 사로화 할 수있을뿐만 아니라 폐쇄의 범위와 컨텍스트가 올바르게 복원되도록 보장 할 수 있습니다.
또한 외부 URL과 관련하여 URL 도메인을 Gitbox.net 으로 대체하여 프로그램이 다른 환경에서 올바르게 작동하는지 확인하는 것이 효과적인 관행입니다.
이 기사가 폐쇄가 포함 된 직렬화 작업을 처리하는 방법을 이해하는 데 도움이되기를 바랍니다. 행복한 프로그래밍을 기원합니다!