Skip to content

[Soap] [DateTime] SoapVar mandatory for Datetime? Also from_xml still needed in SoapClient? #21981

@Hanmac

Description

@Hanmac

Description

Trying to reproduce (now fixed) Problem: https://bugs.php.net/bug.php?id=44383
Also, there: #11725

i used this WSDL for testing from the first link:

<?xml version ="1.0" encoding ="UTF-8" ?> 
    <wsdl:definitions name="GetCurrentDate" 
      targetNamespace="http://localhost"
      xmlns:tns="http://localhost"
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

      <wsdl:message name="GetCurrentDateRequest" />
      <wsdl:message name="GetCurrentDateResponse">
        <wsdl:part name="currentDate" type="xsd:datetime" />
      </wsdl:message>
  
      <wsdl:portType name="GetCurrentDatePortType">
        <wsdl:operation name="getCurrentDate">
          <wsdl:input message="tns:GetCurrentDateRequest" />
          <wsdl:output message="tns:GetCurrentDateResponse" />
        </wsdl:operation>
      </wsdl:portType>

      <wsdl:binding name="GetCurrentDateBinding" type="tns:GetCurrentDatePortType">
        <soap:binding style="rpc"
          transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="getCurrentDate">
          <soap:operation soapAction="http://localhost#getCurrentDate" />
          <wsdl:input>
            <soap:body use="encoded"
              namespace="urn:xmethods-delayed-quotes"
          encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
          </wsdl:input>
          <wsdl:output>
            <soap:body use="encoded"
              namespace="urn:xmethods-delayed-quotes"
              encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
          </wsdl:output>
        </wsdl:operation>
      </wsdl:binding>

      <wsdl:service name="GetCurrentDateService">
        <wsdl:port name="GetCurrentDatePortType" binding="GetCurrentDateBinding">
          <soap:address location="http://localhost/server.php" />
        </wsdl:port>
      </wsdl:service>
    </wsdl:definitions>

The following code for the server.php

<?php

    function getCurrentDate() {
       #return new DateTime("now", new DateTimeZone("UTC"));
       return new SoapVar(new DateTime("now", new DateTimeZone("UTC")), XSD_DATETIME);
    }

      $server = new SoapServer('bug.wsdl', [

		'cache_wsdl' => WSDL_CACHE_NONE
		]);
      $server->addFunction('getCurrentDate');
      $server->handle();

First i noticed, that it still wants me to use SoapVar which is different from the https://bugs.php.net/bug.php?id=44383 example
@ndossche maybe knows why?

Second in my Client, i still need to define "from_xml"
only "to_xml" was implemented by #11725

My client.php

<?php

class ABC
{
    protected static array $typeMap = [
        [
            "type_ns" => "http://www.w3.org/2001/XMLSchema",
            "type_name" => "date",
            "from_xml" => [self::class, "fromXSDDate"],
            #"to_xml"    => [self::class, 'toXSDDate'],
        ],
        [
            "type_ns" => "http://www.w3.org/2001/XMLSchema",
            "type_name" => "dateTime",
            "from_xml" => [self::class, "fromXSDDate"],
            #"to_xml"    => [self::class, 'toXSDDate'],
        ],
    ];

    public static function fromXSDDate(?string $string): ?DateTimeInterface
    {
        if (is_null($string)) {
            return null;
        }
        var_dump($string);
        #=> "<currentDate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:dateTime">2026-05-08T07:41:50.152132Z</currentDate>"
        $string = (string) simplexml_load_string($string);
        var_dump($string); #=> "2026-05-08T07:41:50.152132Z"

        # format doesn't seems to be parsable
        #$return = DateTime::createFromFormat(DateTimeInterface::RFC3339_EXTENDED, $string, new DateTimeZone("UTC"));
        $return = new DateTime($string, new DateTimeZone("UTC"));
        var_dump(DateTime::getLastErrors());
        return $return;
    }

    #public static function toXSDDate(?DateTimeInterface $dateTime): ?string
    #{
    #    if (is_null($dateTime)) {
    #        return null;
    #    }
    #    return $dateTime->format(DateTimeInterface::ATOM);
    #}

    public function getCurrentDate()
    {
        $client = new SoapClient("bug.wsdl", [
            "typemap" => self::$typeMap,
            "trace" => 1,
            "cache_wsdl" => WSDL_CACHE_NONE,
        ]);
        var_dump($client->__getFunctions());
        try {
            $date = $client->getCurrentDate();
            var_dump($date);
            echo "last response: " . $client->__getLastResponse();
            echo "current date: " .
                $date->format(DateTimeInterface::ATOM) .
                PHP_EOL;
        } catch (Exception $e) {
            var_dump($client->__getLastResponse());
            throw $e;
        }
    }
}

$abc = new ABC();
$abc->getCurrentDate();

without typemap on the client, getCurrentDate() returns string instead of DateTimeInterface, so it still does need from_xml

Second, "2026-05-08T07:41:50.152132Z" doesn't seem to be a format that can be parsed by createFromFormat, but need to be parsed by new DateTime directly?

It looks like RFC3339_EXTENDED
with s.vP at the end, but it's s.up with u a small p.
Why does ext-soap use something that isn't part of the format constants?

PHP Version

PHP 8.4.19 (cli) (built: Mar 12 2026 23:34:12) (NTS)
Copyright (c) The PHP Group
Built by https://github.com/docker-library/php
Zend Engine v4.4.19, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.19, Copyright (c), by Zend Technologies
    with Xdebug v3.5.0, Copyright (c) 2002-2025, by Derick Rethans

Operating System

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions