PHP 의 7 개의 미리 정 의 된 인 터 페 이 스 를 자세히 설명 합 니 다.
13345 단어 php미리 정 의 된 인터페이스
이 인 터 페 이 스 는 클래스 에 의 해 직접 실현 되 지 않 습 니 다.일반 클래스 를 직접 써 서 이 인 터 페 이 스 를 옮 겨 다 니 면 치 명 적 인 오 류 를 직접 보고 할 수 있 습 니 다.Iterator(교체 기 인터페이스)나 Iterator Aggregate(취 합 교체 기 인터페이스)를 사용 하여 이 루어 지 는 것 을 알려 줍 니 다.이 두 인 터 페 이 스 는 나중에 소개 합 니 다.모든 일반적인 상황 에서 우 리 는 이 종 류 를 foreach 로 옮 겨 다 닐 수 있 는 지 판단 하 는 데 만 사용 합 니 다.
class Test implements Traversable
{
}
, :
Fatal error: Class Test must implement interface Traversable as part of either Iterator or
IteratorAggregate in Unknown on line 0
위의 대체적인 뜻 은 이 인 터 페 이 스 를 실현 하려 면 Iterator 나 Iterator Aggregate 와 함께 정확 한 방법 을 실현 해 야 한 다 는 것 이다.우리 가 foreach 를 사용 하여 옮 겨 다 닐 수 있 는 지 판단 하려 면 traversable 의 인 스 턴 스 인지 판단 해 야 한다.
class Test
{
}
$test = new Test;
var_dump($test instanceOf Traversable);
2.Iterator(교체 기)인터페이스교체 기 인터페이스 가 실제 적 으로 실현 되 는 원 리 는 포인터 와 유사 한 이동 이다.우리 가 종 류 를 쓸 때 해당 하 는 5 가지 방법:key(),current(),next(),rewind(),valid()를 실현 하면 데이터 의 교체 이동 을 실현 할 수 있다.구체 적 으로 다음 코드 를 볼 수 있다.
<?php
class Test implements Iterator
{
private $key;
private $val = [
'one',
'two',
'three',
];
public function key()
{
return $this->key;
}
public function current()
{
return $this->val[$this->key];
}
public function next()
{
++$this->key;
}
public function rewind()
{
$this->key = 0;
}
public function valid()
{
return isset($this->val[$this->key]);
}
}
$test = new Test;
$test->rewind();
while($test->valid()) {
echo $test->key . ':' . $test->current() . PHP_EOL;
$test->next();
}
\#\#이 출력 결과: 0: one
1: two
2: three
이 원 리 를 보면 알 수 있 듯 이 교체 하 는 이동 방식:rewind()->valid()->key()->current()->next()->valid()->key()...->valid();
알 겠 습 니 다.위 에서 이 해 했 습 니 다.Iterator 의 인 터 페 이 스 를 열 었 는데 Traversable(옮 겨 다 니 기)인 터 페 이 스 를 실현 한 것 을 발 견 했 습 니 다.다음 에 증명 하 겠 습 니 다.
var_dump($test instanceOf Traversable);
결 과 는 true 로 돌아 와 서 이 종류의 대상 이 옮 겨 다 닐 수 있다 는 것 을 증명 합 니 다.
foreach ($test as $key => $value){
echo $test->key . ':' . $test->current() . PHP_EOL;
}
이 결 과 는 while 순환 이 이 루어 진 모델 과 같다.3.Iterator Aggregate(폴 리머 교체 기)인터페이스
취 합 교체 기와 교체 기의 원 리 는 같 습 니 다.다만 취 합 교체 기 는 이미 교체 기 원 리 를 실현 하 였 을 뿐 입 니 다.당신 은 하나의 getIterator()방법 으로 교 체 를 실현 해 야 합 니 다.구체 적 으로 다음 코드 를 보 세 요.
<?php
class Test implements IteratorAggregate
{
public $one = 1;
public $two = 2;
public $three = 3;
public function __construct()
{
$this->four = 4;
}
public function getIterator()
{
return new AraayIterator($this);
}
}
$test = (new Test())->getIterator();
$test->rewind();
while($test->valid()) {
echo $test->key() . ' : ' . $test->current() . PHP_EOL;
$test->next();
}
// , Test , while , getIterator() , , key() 。
// , foreach ?
$test = new Test;
var_dump($test instanceOf Traversable);
// bool true, foreach 。
$test = new Test;
foreach($test as $key => $value) {
echo $key . ' : ' . $value . PHP_EOL;
}
// , , ?
class Test implements IteratorAggregate
{
public $data;
public function __construct()
{
$this->data = [''one' => 1 , 'two' => 2];
}
public function getIterator()
{
return new AraayIterator($this->data);
}
}
// 。
4.ArrayAccess(배열 접근)인터페이스일반적으로,우 리 는 this[name]와 같은 용법 을 볼 수 있 습 니 다.그러나 우 리 는$this 가 하나의 대상 이 고,어떻게 배열 방식 으로 접근 하 는 지 알 고 있 습 니 다.정 답 은 데이터 그룹 액세스 인터페이스 Array Access 를 실현 한 것 입 니 다.구체 적 인 코드 는 다음 과 같 습 니 다.
<?php
class Test implements ArrayAccess
{
public $container;
public function __construct()
{
$this->container = [
'one' => 1,
'two' => 2,
'three' => 3,
];
}
public function offsetExists($offset)
{
return isset($this->container[$offset]);
}
public function offsetGet($offset)
{
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetUnset($offset)
{
unset($this->container[$offset]);
}
}
$test = new Test;
var_dump(isset($test['one']));
var_dump($test['two']);
unset($test['two']);
var_dump(isset($test['two']));
$test['two'] = 22;
var_dump($test['two']);
$test[] = 4;
var_dump($test);
var_dump($test[0]);
//
class Test implements ArrayAccess
{
public $name;
public function __construct()
{
$this->name = 'gabe';
}
public function offsetExists($offset)
{
return isset($this->$offset);
}
public function offsetGet($offset)
{
return isset($this->$offset) ? $this->$offset : null;
}
public function offsetSet($offset, $value)
{
$this->$offset = $value;
}
public function offsetUnset($offset)
{
unset($this->$offset);
}
}
$test = new Test;
var_dump(isset($test['name']));
var_dump($test['name']);
var_dump($test['age']);
$test[1] = '22';
var_dump($test);
unset($test['name']);
var_dump(isset($test['name']));
var_dump($test);
$test[] = 'hello world';
var_dump($test);
5.Serializable(직렬 화)인터페이스일반적으로 우리 클래스 에서 마술 방법,sleep(),wakeup()을 정의 하면 serialize()를 진행 할 때 sleep()의 마술 방법 을 먼저 호출 합 니 다.우 리 는 하나의 배열 로 돌아 가 대상 의 어떤 속성 을 직렬 화 하 는 지 정의 합 니 다.마찬가지 로 우 리 는 반 직렬 화 unserialize()방법 을 호출 할 때,또한 먼저 사용 하 는 wakeup()마술 방법 도 초기 화 할 수 있 습 니 다.예 를 들 어 대상 의 속성 을 할당 하 는 등 작업 을 할 수 있 습 니 다.그러나 이 클래스 가 직렬 화 인 터 페 이 스 를 실현 한다 면 우 리 는 serialize()방법 과 unserialize()방법 을 실현 해 야 한다.동시에 sleep()와 wakeup()두 가지 마술 방법 은 동시에 지원 되 지 않 을 것 이다.구체 적 인 코드 는 다음 과 같다.
<?php
class Test
{
public $name;
public $age;
public function __construct()
{
$this->name = 'gabe';
$this->age = 25;
}
public function __wakeup()
{
var_dump(__METHOD__);
$this->age++;
}
public function __sleep()
{
var_dump(__METHOD__);
return ['name'];
}
}
$test = new Test;
$a = serialize($test);
var_dump($a);
var_dump(unserialize($a));
// ,
class Test implements Serializable
{
public $name;
public $age;
public function __construct()
{
$this->name = 'gabe';
$this->age = 25;
}
public function __wakeup()
{
var_dump(__METHOD__);
$this->age++;
}
public function __sleep()
{
var_dump(__METHOD__);
return ['name'];
}
public function serialize()
{
return serialize($this->name);
}
public function unserialize($serialized)
{
$this->name = unserialize($serialized);
$this->age = 1;
}
}
$test = new Test;
$a = serialize($test);
var_dump($a);
var_dump(unserialize($a));
6.Closure 클래스익명 함 수 를 대표 하 는 클래스 에 사 용 됩 니 다.익명 함 수 는 모두 Closure 폐쇄 류 의 인 스 턴 스 입 니 다.이 클래스 에는 주로 두 가지 방법 이 있 습 니 다.bindto()와 bind()는 소스 코드 를 보면 두 가지 방법 이 서로 다른 길 로 돌아 가 는 것 을 발견 할 수 있 습 니 다.bind()는 정적 방법 일 뿐 구체 적 인 용법 은 다음 과 같 습 니 다.
<?php
$closure = function () {
return 'hello world';
}
var_dump($closure);
var_dump($closure());
위의 예 를 통 해 첫 번 째 로 인쇄 된 것 은 Closure 의 인 스 턴 스 이 고 두 번 째 는 익명 함수 가 되 돌아 오 는 hello World 문자열 을 인쇄 하 는 것 임 을 알 수 있 습 니 다.다음은 이 익명 류 를 사용 하 는 방법 입 니 다.이 두 가지 방법의 목적 은 모두 익명 함 수 를 한 종류 에 연결 하여 사용 하 는 것 입 니 다.bindTo()
<?php
namespace demo1;
class Test {
private $name = 'hello woeld';
}
$closure = function () {
return $this->name;
}
$func = $closure->bindTo(new Test);
$func();
// ,
//
$func = $closure->bindTo(new Test, Test::class);
$func();
namespace demo2;
class Test
{
private statis $name = 'hello world';
}
$closure = function () {
return self::$name;
}
$func = $closure->bindTo(null, Test::class);
$func();
bind()
<?php
namespace demo1;
class Test
{
private $name = 'hello world';
}
$func = \Closure::bind(function() {
return $this->name;
}, new Test, Test::class);
$func();
namespace demo2;
class Test
{
private static $name = 'hello world';
}
$func = \Closure::bind(function() {
return self::$name;
}, null, Test::class);
$func()
7.Generator(생 성기)Generator 는 Iterator 를 실 현 했 지만 그 는 계승 되 지 못 하고 인 스 턴 스 도 생 성 했다.Iterator 를 실현 한 이상 앞에서 소개 한 바 와 같이 Iterator 와 같은 기능 을 가지 게 되 었 습 니 다.rewind->valid->current->key->next.........................................................yield 는 한 번 순환 하 는 중계 역 과 같 습 니 다.이번 활동 궤적 을 기록 하고 Generator 의 인 스 턴 스 를 되 돌려 줍 니 다.Generator 의 장점 은 우리 가 빅 데 이 터 를 옮 겨 다 니 거나 큰 파일 의 읽 기와 쓰 기 를 사용 해 야 하 는데 우리 의 메모리 가 부족 한 상황 에서 메모리 에 대한 소 모 를 크게 줄 일 수 있다 는 것 이다.왜냐하면 전통 적 인 옮 겨 다 니 는 데 이 터 는 모든 데 이 터 를 되 돌려 주기 때문이다.이 데 이 터 는 메모리 에 존재 하고 yield 는 현재 값 만 되 돌려 준다.그러나 우리 가 yield 를 사용 할 때,사실 그 중 에 기억 체 를 처리 하 는 과정 이 있 기 때문에 사실은 시간 으로 공간 을 바 꾸 는 방법 이다.
<?php
$start_time = microtime(true);
function xrange(int $num){
for($i = 0; $i < $num; $i++) {
yield $i;
}
}
$generator = xrange(100000);
foreach ($generator as $key => $value) {
echo $key . ': ' . $value . PHP_EOL;
}
echo 'memory: ' . memory_get_usage() . ' time: '. (microtime(true) - $start_time);
출력:memory: 388904 time: 0.12135100364685
<?php
$start_time = microtime(true);
function xrange(int $num){
$arr = [];
for($i = 0; $i < $num; $i++) {
array_push($arr, $i);
}
return $arr;
}
$arr = xrange(100000);
foreach ($arr as $key => $value) {
echo $key . ': ' . $value . PHP_EOL;
}
echo 'memory: ' . memory_get_usage() . ' time: '. (microtime(true) - $start_time);
출력:memory: 6680312 time: 0.10804104804993
이상 은 PHP 의 7 개의 미리 정 의 된 인터페이스 에 대한 상세 한 내용 입 니 다.PHP 의 7 개의 미리 정 의 된 인터페이스 에 대한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Laravel - 변환된 유효성 검사 규칙으로 API 요청 제공동적 콘텐츠를 위해 API를 통해 Laravel CMS에 연결하는 모바일 앱(또는 웹사이트) 구축을 고려하십시오. 이제 앱은 CMS에서 번역된 콘텐츠를 받을 것으로 예상되는 다국어 앱이 될 수 있습니다. 일반적으로 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.