快速稳定的维护PHP
Just to recap, previously we'd have this sort of thing:
namespace me\adamcameron\testApp; use GuzzleHttp\Client; class GuzzleAdapter { private $client; private $endPoint; public function __construct($endPoint){ $this->endPoint = $endPoint; $this->client = new Client(); } public function get($id){ $response = $this->client->requestAsync( "get", $this->endPoint . $id ); return $response; } }
And say a logging decorator for that:
namespace me\adamcameron\testApp; class LoggedGuzzleAdapter { private $adapter; private $logger; public function __construct($adapter, $logger) { $this->adapter = $adapter; $this->logger = $logger; } public function get($id){ $this->logger->logMessage(sprintf("Requesting for %s", $id)); $response = $this->adapter->get($id); $body = $response->getBody(); $this->logger->logMessage(sprintf("Response for %s: %s", $id, $body)); return $response; } }
And we'd init our adapter thus:
$endPoint = "http://cf2016.local:8516/cfml/misc/guzzleTestEndpoints/getById.cfm?id="; $guzzleAdapter = new GuzzleAdapter($endPoint); $logger = new LoggingService(); $adapter = new LoggedGuzzleAdapter($guzzleAdapter, $logger);
So the underlying GuzzleAdapter handles the Guzzle stuff, the LoggedGuzzleAdapter handles just the logging stuff, but defers to its GuzzleAdapter to do its part of the job, and keeps all the moving parts and bits of functionality sensibly separated. And it's pretty simple. And as detailed in those earlier articles, we can keep layering decorators around an adapter to add caching or what-have-you in a similar way. Easy. Nice.
However this only works cos the call to Guzzle actually returns the result on the spot. And this is cos we were using it synchronously: we make a call to it, it blocks until it gets the answer back from the target and gives us the answer.
Now that we're using async calls, Guzzle doesn't give us the answer, it just gives us a Promise which will eventually resolve to be the answer. This is in theory good cos it means the calling code can make a bunch of HTTP calls, and not wait around for each of them to resolve in series: Guzzle will actually make them all in parallel. I have a look at this in article " PHP: async requests using Guzzle and request pools ".
If we go back to our decorator we can see the problem :
public function get($id){ $this->logger->logMessage(sprintf("Requesting for %s", $id)); $response $promisedResponse = $this->adapter->get($id); $body = $response $promisedResponse->getBody(); $this->logger->logMessage(sprintf("Response for %s: %s", $id, $body)); return $response $promisedResponse; }
At the point at which our decorator needs the body ... we don't have it yet. All we have is a promise that at some point we'll have a body (or we'll have response object via the resolved promise, anyhow; and the response object will have the body ).
To get the body we first need to wait for the promise to resolve... which is a blocking operation and kinda defeats the purpose of using the async approach in the first place. IE: we could do this sort of thing :
public function get($id){ $this->logger->logMessage(sprintf("Requesting for %s", $id)); $promisedResponse = $this->adapter->get($id); $response = $promisedResponse->wait(); $body = $response->getBody(); $this->logger->logMessage(sprintf("Response for %s: %s", $id, $body)); return $response; }
But doing the wait immediately defeats the purpose of making the call async in the first place. We want the wait call to... err... wait ... until the calling code says "right I need to actually use that data now".
Our initial attempt to sort this out was to analyse the issue as being one of "well we don't have the data we need until we call wait , so then we need to do the logging then... which means we need to intercept the wait call... which means we need to return our own decorated version of the response from the call to the adapter with its own wait and have a LoggedResponse, and return that from the code above..." But... and I hope my colleague doesn't mind me saying... when I saw this code in code review I kinda went "there must be a better, more semantic way of doing this". I won't repeat the code as I cannot use our actual work code in my blog, and I am not in the office right now and can't remember the detail of the implementation anyhow. But it's not ideal, so I don't want to share it anyhow.
I've been off sick for the last coupla days, which gives me a lot of time to deliberate and mess around with stuff and google a lot more than I allow myself time for when I'm in the office. With a wee bit of "standing back and having another think about it", the solution became clear. We don't need to explicitly override the wait method before we call it... the promise builds that capability in! At the time we're making the call, we get to tell the Promise what happens when it gets resolved. So I've knocked together this proof of concept:
public function get($id){ $this->logger->logMessage(sprintf("(%s) Requesting for %s", $this->thisFile, $id)); $response = $this->adapter->get($id); $response->then(function($response) use ($id){ $body = $response->getBody(); $this->logger->logMessage(sprintf("(%s) Response for %s: %s", $this->thisFile, $id, $body)); $body->rewind(); }); return $response; }
默认路由从url映射到文件的应用层级可通过配置项:route_app_hierarchy=>1,来修改。即应用n层*控制器n层来处理复杂的业务分层
控制器后缀支持自定义配置.默认还是Controller
mysql支持关闭数据缓存
CmlPHP 是基于php5.3+(v2.7+要求php5.4+)版本(已经测试过php7)开发的MVC/HMVC/MVSC/HMVSC框架,支持composer、分布式数据库、分布式缓存,支持文件、memcache、redis、apc等缓存,thg支持多种url模式、URL路由[RESTful],支持多项目集成、第三方扩展、支持插件。
快速稳定的维护PHP的更多相关文章
- 最新番茄花园win7系统快速稳定版
这是最新番茄花园win7系统64位快速稳定版 V2016年2月,该系统由系统妈整理和上传,系统具有更安全.更稳定.更人性化等特点.集成最常用的装机软件,集成最全面的硬件驱动,精心挑选的系统维护工具,加 ...
- Win7 SP1 32位 旗舰版 IE8 快速稳定 纯净优化 无人值守 自动激活 20170518
一.系统特色 1.采用微软原版旗舰版定制而成. 2.优化系统服务,关闭一些平时很少使用的服务. 3.精简掉一些无用的东西. 4.系统全程离线制作,不包含任何恶意插件,放心使用. 5.右下角时间加上星期 ...
- Win7 SP1 64位 旗舰版 IE8 快速稳定 纯净优化 无人值守 自动激活 20180604
一.系统特色 1.采用微软原版旗舰版定制而成. 2.优化系统服务,关闭一些平时很少使用的服务. 3.精简掉一些无用的东西. 4.系统全程离线制作,不包含任何恶意插件,放心使用. 5.右下角时间加上星期 ...
- ThinkPHP框架介绍
什么是框架 php框架是许多代码的集合,这些代码的程序结构的代码(并不是业务代码)代码中有许多的函数,类,功能类包 不使用框架开发的缺陷 代码编写不规范 牵一发而动全身 不能很好满足客户各方面的需求 ...
- ASP.NET MVC 多语言实现技巧 最简、最易维护和最快速开发
说说传统做法的缺点 1.做过多语言的都知道这玩意儿太花时间 2.多语言架构一般使用资源文件.XML或者存储数据库来实现.这样就在一定程序上降低了性能 3.页面的可读性变差,需要和资源文件进行来回切换 ...
- 转:ASP.NET MVC 多语言实现技巧 最简、最易维护和最快速开发
说说传统做法的缺点 1.做过多语言的都知道这玩意儿太花时间 2.多语言架构一般使用资源文件.XML或者存储数据库来实现.这样就在一定程序上降低了性能 3.页面的可读性变差,需要和资源文件进行来回切换 ...
- CODING 静态网站服务升级,快速、稳定、高拓展!
CODING 静态网站拥有强大的页面托管服务,目前已有数万开发者.设计师.产品经理.团队与企业使用 CODING 静态网站托管了他(她)们的个人网站.博客.企业与产品官网.在线文档等.CODING 静 ...
- IPFS - 可快速索引的版本化的点对点文件系统(草稿3)
摘要 星际文件系统是一种点对点的分布式文件系统, 旨在连接所有有相同的文件系统的计算机设备.在某些方面, IPFS类似于web, 但web 是中心化的,而IPFS是一个单一的Bittorrent 群集 ...
- github入门到上传本地项目【网上资源整合】
[在原文章的基础上,修改了描述的不够详细的地方,对内容进行了扩充,整合了网上的一些资料] [内容主要来自http://www.cnblogs.com/specter45/p/github.html#g ...
随机推荐
- SSH项目练习的时候报错:[applicationContext.xml]: Invocation of init method failed;
这里是控制台的报错信息:org.springframework.beans.factory.BeanCreationException: Error creating bean with name ' ...
- jquery在线预览PDF文件,打开PDF文件(向下兼容ie8、ie7)
最主要的是使用到了一个jquery的插件jquery.media.js,使用这个插件就很容易实现了. 核心代码 <!DOCTYPE html PUBLIC "-//W3C//DTD X ...
- java获取泛型的真实类型
ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass(); Type[] actualTyp ...
- iOS 自定义UITabBarController的tabBar
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDeleg ...
- App上架出现问题-ERROR ITMS-90034
1.打开钥匙串,显示->显示已过期的证书,因为有些过期的证书会被钥匙串隐藏起来,让过期的证书都显示出来,删掉过期的证书. 2.经检查,我发现我的AppleWWDRCA.cer证书过期了,所以我就 ...
- javascript 函数返回值(return)、定时器(setTimeout、setInterval)
一.函数的返回值:return 1.函数名+括号=return后面的值 <script> function fn1(){ return 100; } alert(fn1()); // 10 ...
- java程序员从笨鸟到菜鸟之(七)一—java数据库操作
本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 数据库访问几乎每一个稍微成型的程序都要用到的知识,怎么高效的访问数据库也是我们学习的一个 ...
- Swift实战-豆瓣电台(五)播放音乐
观看地址 http://v.youku.com/v_show/id_XNzMwODM0MzI0.html 在这节里面,我们简单学习了一下MediaPlayer的使用 引入媒体框架 import Med ...
- Lintcode: Nth to Last Node in List
Find the nth to last element of a singly linked list. The minimum number of nodes in list is n. Exam ...
- SQL 数据库 存储过程 视图
一.存储过程 1.概述 存储过程是一组编译在单个执行计划中的T-SQL语句 存储过程:就像函数一样的会保存在数据库中(可编程性) 存储过程的优点: 1.允许模块化程序设计 2.允许更快执行如果某操作需 ...