责任链模式:一个PHP实现的过滤器

上次讲到责任链模式的时候,我顺手实现了一个过滤器,分享给新人。SimpleMVC框架中,过滤器链是整个HTTP请求处理的核心组件。

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

fitlers

Talk is cheap, show me the code.

<?php
class FilterChain {
	
	private $filters = array();
	private $currentFilterPos = 0;
	
	public function add(Filter $filter) {
		$this->filters[] = $filter;
		return $this;
	}
	
	public function invoke() {
		if($this->currentFilterPos >= count($this->filters)) {
			return;
		}
		return $this->filters[$this->currentFilterPos++]->invoke($this);
	}
	
	public function start() {
		$this->invoke();
	}
	
}

interface Filter {
	public function invoke(FilterChain $chain);
}

class ExceptionFilter implements Filter {
	public function invoke(FilterChain $chain) {
		try {
			return $chain->invoke();
		} catch (Exception $e) {
			echo $e->getMessage().PHP_EOL;
		}
	}
}


class UserFilter implements Filter {
	public function invoke(FilterChain $chain) {
		echo 'Before User'.PHP_EOL;
		$result = $chain->invoke();
		echo 'After User'.PHP_EOL;
		return $result;
	}
}

class PermissionFilter implements Filter {
	public function invoke(FilterChain $chain) {
		echo 'Before Permission'.PHP_EOL;
		throw new Exception('403');
		httpReq(function () use ($chain) {
			$chain->invoke();
		});
		echo 'After Permission'.PHP_EOL;
		return $result;
	}
}


(new FilterChain())->add(new ExceptionFilter())->add(new UserFilter())->add(new PermissionFilter())->start();