You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:05:19