使用PHP和SOAP连接vCenter后无法获取数据中心信息的问题
问题分析与解决
你的问题核心出在会话Cookie未被正确传递,以及**RetrieveProperties的参数完全不符合vCenter SOAP API规范**两个方面,以下是具体修复方案:
1. 会话Cookie未自动携带
vCenter的SOAP会话依赖vmware_soap_session Cookie维护,但PHP的SoapClient默认不会自动保存和发送Cookie。登录成功后服务器已返回该Cookie,但后续请求未带上,导致服务器判定会话无效。
解决方法:通过stream_context配置Cookie文件,让SoapClient自动处理Cookie的存储与发送。
2. RetrieveProperties参数错误
你写的参数存在多处致命问题:
_this不能是字符串'PropertyCollector',必须使用RetrieveServiceContent返回的service_instance->propertyCollector这个ManagedObject引用- 无需传递
authentication参数,会话由Cookie维护 objectSet里的obj不能是字符串'Datacenter',需使用根目录对象service_instance->rootFolder- TraversalSpec的写法完全错误,必须定义正确的遍历路径(从根目录到数据中心再到主机系统)
修正后的完整代码
header('content-type: text/plain'); // 改为文本格式方便查看输出 ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); ini_set('soap.wsdl_cache_enabled', 0); ini_set('soap.wsdl_cache_ttl', 0); // Vcenter URL $vcenter_url = "https://vcenter.labs.local/sdk"; // WSDL File location $wsdl = './vmware/vimService.wsdl'; // Login Creds $username = "administrator@vsphere.local"; $password = "S0m3P@ssw0rd123!"; // 创建临时Cookie文件,用于存储会话Cookie $cookieJar = tempnam(sys_get_temp_dir(), 'vcenter_cookie'); // 初始化SOAP上下文,配置SSL和Cookie处理 $context = stream_context_create( array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true, ), 'http' => array( 'cookie_file' => $cookieJar, 'cookie_jar' => $cookieJar, ) ) ); $client = new SoapClient( $wsdl, array( 'trace' => true, 'exceptions' => true, "location" => $vcenter_url, 'stream_context' => $context ) ); // 获取vCenter服务内容 $soap_message["_this"] = new SoapVar("ServiceInstance", XSD_STRING, "ServiceInstance"); $result = $client->RetrieveServiceContent($soap_message); $service_instance = $result->returnval; // 登录vCenter $loginParams = array( '_this' => $service_instance->sessionManager, 'userName' => $username, 'password' => $password ); $login = $client->Login($loginParams); // 输出登录信息 print_r($login); echo "\n---\n"; // 定义遍历规则:从根目录→数据中心主机文件夹→主机系统 $traversalSpec = array( 'name' => 'traverseDatacenter', 'type' => 'Folder', 'path' => 'childEntity', 'skip' => false, 'selectSet' => array( array( 'name' => 'traverseHosts', 'type' => 'Datacenter', 'path' => 'hostFolder', 'skip' => false, 'selectSet' => array( array( 'name' => 'hosts', 'type' => 'Folder', 'path' => 'childEntity', 'skip' => false ) ) ) ) ); // 构造获取主机列表的正确参数 $retrieveParams = array( '_this' => $service_instance->propertyCollector, 'specSet' => array( 'propSet' => array( 'type' => 'HostSystem', 'pathSet' => array('name', 'config.product.version') // 可添加更多需要的属性 ), 'objectSet' => array( 'obj' => $service_instance->rootFolder, 'skip' => false, 'selectSet' => array($traversalSpec) ) ) ); try { $hosts = $client->RetrieveProperties($retrieveParams); print_r($hosts); } catch (SoapFault $e) { echo "错误信息: " . $e->getMessage() . "\n"; echo "最后一次请求内容:\n" . $client->__getLastRequest() . "\n"; } // 清理临时Cookie文件 unlink($cookieJar);
关键修正说明
- 新增Cookie文件配置,让
SoapClient自动处理会话Cookie的存储与发送 - 使用
$service_instance->propertyCollector作为_this参数,符合vCenter API对ManagedObject的引用要求 - 定义了正确的TraversalSpec遍历路径,从根目录开始逐层定位到主机系统
- 移除了无效的
authentication参数,会话由Cookie自动维护 - 增加异常捕获逻辑,方便调试错误
内容的提问来源于stack exchange,提问作者Joes Momma
相关产品推荐
相关产品推荐

