因为WeatherReport实际上并不是你程序中定义的类, SoapClient都象stdClass的实例化一样的返回所有的对象。这时你也可以获得返回对象的属性的值。
class ProxyTestCase extends UnitTestCase { |
class ProxyTestCase extends UnitTestCase { function TestGetWeatherReport() { // continued 。。。 $temp = $moline_weather->temperature; $temperature_tests = array( ‘ambient’ => ‘Float’ ,’dewpoint’ => ‘Float’ ,’relative_humidity’ => ‘Integer’ ,’string’ => ‘String’ ); foreach($temperature_tests as $key => $isa) { $this->assertIsA($temp->$key, $isa, “$key should be $isa, actually [%s]”); } } } |
上面的方法输出的实际效果如下:
stdClass Object ) // 。。。 ) |
现在你基本掌握了PHP5风格的SoapClient(如何做一个远程代理),但是你怎么才能写一个延迟实例化的代理给SoapClient呢?
class GlobalWeather { private $client; // ‘Station getStation(string $code)’, public function getStation($code) { return $this->client->getStation($code); } } |
getStation()可以代理$client变量指向的getStation()方法。不管如何,从这点上看, SoapClient实例并没有创建,也没有存储到$client变量,因为上面已说过,对WSDL文件进行远程处理应该延迟到真正需要的时候。
你可以在插入一段延迟加载的代码之前做一下client的调用,来延迟SoapClient的实例化
class GlobalWeather { private $client; private function lazyLoad() { if (! $this->client instanceof SoapClient) { $this->client = new SoapClient( ‘http://live。capescience。com/wsdl/GlobalWeather。wsdl’); } } // ‘Station getStation(string $code)’, public function getStation($code) { $this->lazyLoad(); return $this->client->getStation($code); } } |
lazyLoad()中创建SoapClient对象是一定要的。这里存在一个问题:如果我是一个懒惰的编码者,让我非常不爽是:我不得不在所有的代理方法中加入$this->lazyLoad();。有更加简便的方法吗?当然有,重写一遍吧,使用PHP5新的特性来返回对象。改lazyLoad()的名字为client(),并在这个方法里面实例化$client,代理中的方法访问client()方法优于访问$client属性。把延迟实例化做的更加简单!
延伸阅读:
从魔兽看PHP设计模式
《PHP设计模式介绍》导言
PHP设计模式介绍 第一章 编程惯用法
PHP设计模式介绍 第二章 值对象模式
PHP设计模式介绍 第三章 工厂模式
PHP设计模式介绍 第四章 单件模式
PHP设计模式介绍 第五章 注册模式
PHP设计模式介绍 第六章 伪对象模式
PHP设计模式介绍 第七章 策略模式
PHP设计模式介绍 第八章 迭代器模式
PHP设计模式介绍 第九章 观测模式
PHP设计模式介绍 第十章 规范模式