www.gusucode.com > 同城苏州黄页系统php源码程序 > lib/http_soap.class.php
<? ###################################### // 默认 或 参数 $_REQUEST['sync']=true , 使用 异步方式 ignore_user_abort( empty($_REQUEST['sync']) or !$_REQUEST['sync'] ); ###################################### define( '__DEFAULT_ENDTIME', 600 ); define( '__OBJID_REGEXP', "/^(\w+)\-(\d+\.\d+)\-(\d+)$/" ); if( !class_exists('base') ) include dirname(__FILE__).'/base.class.php' ; if( !class_exists('http') ) include dirname(__FILE__).'/http.class.php' ; class msg { var $puter ; var $msg ; function msg( $msg, $puter ) { $this->puter = $puter ; $this->msg = $msg ; } function out() { if( empty($this->msg) ) return false ; return "[{$this->puter}]\r\n{$this->msg}\r\n\r\n" ; } } class http_soap_exception { var $msgs = array() ; function http_soap_exception() { } function put( $theMsg ) { if( !is_object($theMsg) or get_class($theMsg)!='msg' ) return false; $this->msgs[] = $theMsg ; return true ; } function get() { if( !count($this->msgs) ) return false; return array_shift( $this->msgs ); } function out_msg() { $outStr = '' ; while( $theMsg = $this->get() ) $outStr.= $theMsg->out() ; return $outStr ; } function load( $srcstr ) { if( !$exObj = @unserialize($srcstr) ) return false ; if( !is_object($exObj) or get_class($exObj)!='http_soap_exception' ) return false ; while( $theMsg = $exObj->get() ) $this->put( $theMsg ) ; return true ; } } $http_soap_exception = &new http_soap_exception(); class http_soap_base extends base { var $class_name ; var $ObjID ; // 对象 id var $class_dir ; var $obj_serialize_dir ; var $readonly = false; var $concrete_class_consr_parameter ; var $after_load_invoke_func ; var $after_load_invoke_param ; var $idle_time = __DEFAULT_ENDTIME ; var $exception ; /** * 用于在 _create() 和 _load() 之前 载入 所请求对象的 类的定义文件 * */ function _include_class_define() { $class_flie = "{$this->class_dir}{$this->class_name}.class.php" ; if( !file_exists($class_flie) or !is_file($class_flie) ) { $this->put_exception_msg("No class define file on server. The class name is:{$this->class_name}") ; return false ; } include_once( $class_flie ); // 定义 类 if( !class_exists($this->class_name) ) { $this->put_exception_msg("Class no defined. The class name is:{$this->class_name}") ; return false ; } return true ; } function put_exception_msg( $msg ) { if( empty($msg) ) return false ; $this->exception->put( new msg($msg, 'Http Soap User Class') ) ; } function http_soap_base( $if_conn_db = false /*$concrete_class_consr_parameter = array()*/ ) { $this->base( $if_conn_db ); // 初始化 基类,但不连接数据库 $this->class_dir = $this->root_path . 'lib/'; $this->obj_serialize_dir = $this->root_path . 'soap_obj_serialize/'; global $http_soap_exception; if( is_object($http_soap_exception) ) $this->exception = & $http_soap_exception ; // $this->concrete_class_consr_parameter = serialize( $concrete_class_consr_parameter ) ; } /** * 创建新的对象 * */ function create( $class_name, $constructor_parameter=array() ) { $this->class_name = $class_name ; // 创建 对象ID if( empty($this->ObjID) ) $this->ObjID = $this->_create_obj_id() ; // 包含 类定义文件 if( !$this->_include_class_define() ) return false ; // 创建新对象 $this->concrete_class_consr_parameter = base64_encode(serialize($constructor_parameter)) ; $Obj = & new $class_name( $constructor_parameter ); $Obj->class_name = $this->class_name ; $Obj->ObjID = $this->ObjID ; $Obj->class_dir = $this->class_dir ; $Obj->obj_serialize_dir = $this->obj_serialize_dir ; $Obj->concrete_class_consr_parameter = $this->concrete_class_consr_parameter ; $Obj->after_load_invoke_func = $this->after_load_invoke_func ; $Obj->after_load_invoke_param = $this->after_load_invoke_param ; $exception = & $this->exception ; $this = $Obj ; $this->exception = & $exception ; if( !empty($_REQUEST['end_time']) ) $this->idle_time = $_REQUEST['end_time'] ; return true; } /** * 销毁一个对象,当一件具体的工作完成后 * */ function destroy( $ObjID='' ) { if( !empty($ObjID) ) $this->ObjID = $ObjID ; $class_flie = $this->obj_serialize_dir . $this->ObjID ; if( !file_exists($class_flie) or !is_file($class_flie) ) { $this->put_exception_msg( "No ObjID parameter from client." ); return false; } $result = @unlink($class_flie); return $result; } function save( $after_load_invoke_func = '', $after_load_invoke_param=array() ) { # 保存状态 $this->after_load_invoke_func = $after_load_invoke_func ; $this->after_load_invoke_param = $after_load_invoke_param ; if( !$s = serialize($this) ) return false ; $s = base64_encode($s); # 序列化 存储到硬盘 $now = time() ; $endtime = $now + $this->idle_time ; $file_content = '<'."?\r\n" ; $file_content.= "\$last_action = {$now} ; // 该对象最后活动时间:" . date('Y.m.d G:i:s',$now) . " \r\n" ; // 最后活跃时间 $file_content.= "\$end_time = {$endtime} ; // 该对象空闲终止时间:" . date('Y.m.d G:i:s',$endtime) . " \r\n" ; // 终止时间 $file_content.= "\$constructor_parameter = '{$this->concrete_class_consr_parameter}' ;\r\n"; // 构造函数参数 $file_content.= "\$Obj_serialize = '{$s}' ;"; // 对象 序列化 存储 $file_content.= "\r\n?".'>'; return file_put_contents( $this->obj_serialize_dir . $this->ObjID, $file_content ); } function load( $ObjID='' ) { if( !empty($ObjID) ) $this->ObjID = $ObjID ; if( !$Obj_info = get_Obj_info($this->ObjID) ) { $this->put_exception_msg("The ObjID is invalid. The ObjID is:{$this->ObjID}") ; return false ; } // 载入 存储文件 $serialize_file = $this->obj_serialize_dir . $this->ObjID ; if( !file_exists( $serialize_file ) or !is_file($serialize_file) ) { $this->put_exception_msg("No Object serialize file on server. The Object ID is:{$this->ObjID}") ; return false; } include $serialize_file ; $consructor_parameter = @base64_decode($constructor_parameter); $consructor_parameter = @unserialize($consructor_parameter) ; if( !$consructor_parameter ) $consructor_parameter = array(); $this->concrete_class_consr_parameter = $consructor_parameter ; // 调用构造函数 初始化 if( !$this->create( $Obj_info['class_name'], $consructor_parameter ) ) { $this->put_exception_msg('Load Obj bad.') ; return false; } // 恢复存储前的状态 if( empty($Obj_serialize) ) { // echo $Obj_serialize; $this->put_exception_msg("The Object serialize file is empty. The Object ID is:{$this->ObjID}") ; return false; } $Obj_serialize = base64_decode($Obj_serialize); if( !$this = unserialize( $Obj_serialize ) ) { $this->put_exception_msg("The Object serialize file can not unserialize. The Object ID is:{$this->ObjID}") ; return false; } global $http_soap_exception ; if( is_object($http_soap_exception) and get_class($http_soap_exception)=='http_soap_exception' ) $this->exception = & $http_soap_exception ; if( empty($this->after_load_invoke_func) ) return true; return true; } function _create_obj_id() { list($usec, $sec) = explode( ' ', microtime() ); $usec = str_replace( '0.', '', $usec ) ; return $this->ObjID = "{$this->class_name}-{$sec}.{$usec}-".sprintf( "%04d", rand(1,9999) ) ; } } /** * SOAP 客户方,用于呼叫、调用 另一台主机上的 php class * */ class http_soap_client extends http { var $ObjID ; // 对象 id var $readonly = false ; var $soap_uri ; var $cient = 'php' ; var $exception ; var $additional = array() ; var $send_http_body = '' ; var $recv_http_body = '' ; function set_additional( $key, $value ) { $this->additional[ $key ] = $value ; } function put_exception_msg( $msg ) { if( empty($msg) ) return false ; $this->exception->put( new msg($msg, 'Http Soap Client') ) ; } /** * 创建一个客户端 * * @param string $remove_host 远程主机 * @param string $api_path 远程主机上的 http_soap_server api 路径 */ function http_soap_client( $remove_host, $api_path ) { $this->http(); $this->host = $remove_host ; $this->soap_uri = $api_path ; global $http_soap_exception; if( is_object($http_soap_exception) ) $this->exception = &$http_soap_exception ; } /** * 在另一台主机上,创建一个 php 对象。 创建的对象,会在所在主机上保存,直到调用 http_soap_client::destroy() , 或 到该对象生命期 自行结束 * * @param string $class_name 需要创建的类名 * @param int $life_span 生命周期,超过此时间如果没有被 destroy() ,将被自动销毁。 * @return string 远程主机传回的 对象ID */ function create( $class_name, $parameters=array(), $end_time = 0 ) { if( empty($end_time) ) $end_time = __DEFAULT_ENDTIME ; $send_data = array( 'action'=>'create', 'class_name'=>$class_name, 'end_time'=>$end_time ); if( !empty($parameters) ) $send_data['parameters'] = $parameters ; $this->ObjID = $this->_post_data( $send_data, true ); return $this->ObjID ; } /** * 销毁在远程主机 上创建的对象 * * @param string $ObjID 对象id ,默认 为最近创建的对象 * @return bool */ function destroy( $ObjID=0 ) { if( empty($ObjID) ) $ObjID = $this->ObjID ; return $this->_post_data( array('action'=>'destroy','ObjID'=>$ObjID), true ); } function get_attribute( $attribute_name, $ObjID=0 ) { if( empty($ObjID) ) $ObjID = $this->ObjID ; return $this->_post_data( array('action'=>'get_attribute','ObjID'=>$ObjID,'attribute_name'=>$attribute_name), true ); } function set_attribute( $attribute_name, $attribute_value, $if_sync = true, $ObjID=0 ) { if( empty($ObjID) ) $ObjID = $this->ObjID ; $data = array( 'action'=>'set_attribute', 'ObjID'=>$ObjID, 'attribute_name'=>$attribute_name, 'attribute_value'=>$attribute_value ) ; return $this->_post_data( $data, $if_sync ); } function method_invoke( $func_name, $parameters=array(), $if_sync = true, $ObjID=0 ) { if( empty($ObjID) ) $ObjID = $this->ObjID ; $result = $this->_post_data( array('action'=>'method_invoke','ObjID'=>$ObjID,'func_name'=>$func_name,'parameters'=>$parameters), $if_sync ); return $result ; } function output() { return $this->_response->get_body(); } function _post_data( $data, $if_sync ) { $this->waiting_response = $if_sync ; // 通知 server 使用 同步/异步 工作 $data['sync'] = $if_sync ; // 通知 client 使用 同步/异步 工作 $data['client'] = $this->cient ; // 通知 server, client 的身份 if( $this->readonly ) $data['readonly'] = '1' ; $data+= $this->additional ; $data = serialize_request_data($data) ; $this->send_http_body = $data; //pp($data); if( !$this->post( $this->soap_uri, $data, false, '', true ) ) // 发送请求 return false; $response = $this->_response->get_body() ; $this->recv_http_body = $response ; if( !preg_match( "/^(.*)\r\n\-{3} http soap server exception msg start -{3}\r\n(.*)\r\n-{3} http soap server response start -{3}\r\n(.*)$/s", $this->_response->get_body(), $re ) ) { print $response ; return '' ; } /*echo '{'.$response.'}';*/ if( trim($re[1])!=='' ) // 产生的输出 print "{$re[1]}\r\n<br />\r\n" ; $re[2] = base64_decode($re[2]) ; $re[3] = base64_decode($re[3]) ; if( !empty($re[2]) ) // 接收消息 $this->exception->load( $re[2] ) ; if( $o = @unserialize($re[3]) ) // 反序列化 $re[3] = $o ; return $re[3]; // 返回回应,如果 $if_sync = false ,则返回为空 } function out_exception_msg() { return $this->exception->out_msg() ; } } /** * SOAP 服务方,用于 相应协作来自其他主机,对本主机上的 php class 的 呼叫、调用 * */ class http_soap_server extends base { var $ObjID ; var $theObj ; var $readonly = false; var $exception ; function put_exception_msg( $msg ) { if( empty($msg) ) return false ; $this->exception->put( new msg($msg, 'Http Soap Server') ) ; } function http_soap_server() { $this->base( false ); // 初始化 基类,但不连接数据库 global $http_soap_exception; if( is_object($http_soap_exception) ) $this->exception = & $http_soap_exception ; $this->readonly = !empty($_REQUEST['readonly']) ; $this->theObj = & new http_soap_base(); $this->theObj->readonly = $this->readonly ; //$this->theObj->put_exception_msg('test msg'); } function proc() { if( empty($_REQUEST['action']) ) // 检查 操作 { $this->put_exception_msg( "No action parameter from client." ); $this->_print( false ); exit(); } if( $_REQUEST['action'] == 'create' ) // 创建一个新的对象 { if( empty( $_REQUEST['class_name'] ) ) { $this->put_exception_msg( 'No class name.' ); $this->_print( false ); exit(); } $this->_create() ; } else // 对已有对象进行操作 { $this->_load() ; // 载入对象 $action = '_'.$_REQUEST['action']; // 执行操作 $this->$action(); } $this-> theObj-> save(); // 保存对象 exit(); } /** * 恢复对象,继续工作 * */ function _load() { if( empty($_REQUEST['ObjID']) ) { $this->put_exception_msg( "No ObjID parameter from client." ); $this->_print( false ) ; exit() ; } if( !$this->theObj->load( $_REQUEST['ObjID'] ) ) { $this->put_exception_msg('Load Obj serialize file bad.') ; $this->_print(false); exit(); } return true ; } /** * 创建新的对象 * */ function _create() { if( $this->readonly ) { $this->put_exception_msg('Can`t create new object by read-only client.') ; $this->_print( false ) ; return false ; } if( !isset($_REQUEST['parameters']) ) $_REQUEST['parameters'] = array(); if( !$this->theObj->create( $_REQUEST['class_name'], $_REQUEST['parameters'] ) ) { $this->_print( false ) ; exit() ; } $this->ObjID = $this->theObj->ObjID ; $this->_print( $this->ObjID ) ; return true; } /** * 销毁一个对象,当一件具体的工作完成后 * */ function _destroy() { if( $this->readonly ) { $this->put_exception_msg('Can`t destroy object by read-only client.') ; $this->_print( false ); exit(); } $this->_print( $this->theObj->destroy() ); exit(); } /** * 获得对象 的属性 * */ function _get_attribute() { if( empty($_REQUEST['attribute_name']) ) return ; $attribute = $this->theObj->$_REQUEST['attribute_name']; $this->_print( $attribute ); return ; } /** * 设置对象的 属性 * */ function _set_attribute() { if( empty($_REQUEST['attribute_name']) ) { $this->put_exception_msg( "No 'attribute_name' from client." ); $this->_print( false ); exit(); } $this->theObj->$_REQUEST['attribute_name'] = $_REQUEST['attribute_value'] ; $this->theObj->save() ; // 保存 $this->_print( true ); return ; } /** * 调用对象的方法 * */ function _method_invoke() { if( empty($_REQUEST['func_name']) ) { $this->put_exception_msg( 'no func_name' ) ; $this->_print( false ) ; exit(); } if( !method_exists ( $this->theObj, $_REQUEST['func_name'] ) ) { $this->put_exception_msg( "No function {$_REQUEST['func_name']}()." ) ; $this->_print( false ) ; exit(); } $return = $this->theObj->$_REQUEST['func_name']( isset($_REQUEST['parameters'])?$_REQUEST['parameters']:null ); $this->_print( $return ); return ; } function _serialize_array( $arr ) { if( !is_array($arr) ) return $arr ; if( empty($_REQUEST['client']) ) $_REQUEST['client'] = 'php' ; if( in_array($_REQUEST['client'], array('python','js')) ) // python 和 javascript 的序列化格式相同 { $seria_str = '' ; foreach ($arr as $key=>$item) { if( $seria_str ) $seria_str.= ',' ; if( is_array($item) ) $seria_str.= "'{$key}':".$this->_serialize_array($item) ; else { $item = str_replace( "\r", '\r', $item ) ; $item = str_replace( "\n", '\n', $item ) ; // js client 中 eval 无法 反序列化 多行脚本 $seria_str.= "'{$key}':\"$item\"" ; } } return "{{$seria_str}}" ; } elseif ( $_REQUEST['client'] == 'java' ) // java { } elseif ( $_REQUEST['client'] == 'vc++' ) // vc++ { } elseif ( $_REQUEST['client'] == 'php' ) // php return serialize($arr) ; } function _print( $value ) { $outStr = '' ; if( $_REQUEST['client'] == 'php' or empty($_REQUEST['client']) ) $exception = serialize($this->exception) ; else { $exception = array() ; foreach ($this->exception->msgs as $theMsg) $exception[] = $theMsg->out() ; $exception = $this->_serialize_array( $exception ) ; } switch( 1 ) { case is_array($value) or is_object($value) : $outStr = $this->_serialize_array($value); break ; case is_bool($value) : $outStr = (int) $value; break ; default : $outStr = (string) $value; break; } $outStr = "\r\n--- http soap server exception msg start ---\r\n" . base64_encode($exception) . "\r\n--- http soap server response start ---\r\n" . base64_encode((string)$outStr) ; print $outStr ; } function destroy_endtime_obj() { if( ! $h = @opendir( $this->theObj->obj_serialize_dir ) ) { $this->put_exception_msg('Destroy Obj: the obj_serialize_dir is not Exists') ; return false ; } $destroied = array() ; while( $filename = readdir($h) ) { if( !preg_match( __OBJID_REGEXP, $filename, $re ) ) continue ; include_once( $this->theObj->obj_serialize_dir . $filename ) ; if( $end_time < time() ) { unlink( $this->theObj->obj_serialize_dir . $filename ); $destroied [] = array( 'ObjID'=>$filename , 'class_name'=>$re[1], 'create_time'=>$re[2] ) ; } } return $destroied ; } } function get_Obj_info( $ObjID ) { if( !preg_match( __OBJID_REGEXP, $ObjID, $re ) ) return false ; $info = array( 'ObjID' => $ObjID , 'class_name' => $re[1] , 'create_time' => $re[2] , 'rand_seed' => $re[3] ); return $info ; } if( !function_exists('serialize_request_data')) // 如果在 workframe 中使用, 则此函数已在 base.class.php 中定义 { function serialize_request_data( $request, $val_name_pre='' ) { $restr = array();//pp($request);sleep(10); foreach($request as $key=>$val) { /* if( !empty($restr) ) $restr.= '&';*/ $val_name_pre ? $key = "{$val_name_pre}%5B{$key}%5D" : null ; if( is_array($val) ) { $return = serialize_request_data( $val, $key ); if( empty($return) ) continue ; $restr+= $return; } else $restr[$key]= $val; } return $restr; } } ?>