Skip to content

[PHP] DateTime should be DateTimeImmutableย #6534

Open
@SunMar

Description

@SunMar
Description

Response strings with format: date and format: date-time are cast to a \DateTime object, but I think they should be a \DateTimeImmutable. The problem with a regular \DateTime is that it can be modified, then if the same response object instance is used in multiple places in the code you can not trust any of the returned \DateTime objects, if they are modified it may produce unexpected results. This can be fixed by using \DateTimeImmutable instead which after creation can no longer be modified. Any modifications are returned in a new \DateTimeImmutable instance that doesn't affect the original instance in the response.

Swagger-codegen version

I'm using the latest 2.3.0 snapshot (swagger-codegen-cli-2.3.0-20170921.031930-142.jar).

Swagger declaration file content or url

test.yaml

---
swagger: '2.0'

info:
  title: 'Test Codegen DateTimeImmutable'
  version: '1.0'
  
paths:
  '/foo':
    get:
      responses:
        200:
          description: 'Success'
          schema:
            type: object
            properties:
              timestamp:
                type: string
                format: 'date-time'

client.php

<?php

require 'vendor/autoload.php';

use Swagger\Client\Api\DefaultApi;

$api = new DefaultApi(
    new \GuzzleHttp\Client(),
    (new \Swagger\Client\Configuration())->setHost('http://localhost')
);

$response = $api->fooGet();

echo '$response->getTimestamp() value before add: ' . $response->getTimestamp()->format(DateTime::ATOM) . PHP_EOL;

$response->getTimestamp()->add(new DateInterval('P1W'));

echo '$response->getTimestamp() value after add:  ' . $response->getTimestamp()->format(DateTime::ATOM) . PHP_EOL;

index.php

<?php

echo json_encode([ 'timestamp' => date(DATE_ATOM) ]);
Command line used for generation

java -jar swagger-codegen-cli-2.3.0-20170921.031930-142.jar generate -i test.yaml -l php

Steps to reproduce

I am assuming $PWD is your current working directory where you are testing this. Replace of course as you like with a directory of your choice.

  1. Save the sample test.yaml in $PWD.
  2. Create a directory $PWD/foo and place in that directory the sample index.php.
  3. In $PWD run php -S 127.0.0.1:80 to start a quick web server.
  4. Generate the client library from $PWD: java -jar swagger-codegen-cli-2.3.0-20170921.031930-142.jar generate -i test.yaml -l php
  5. Go into the directory $PWD/SwaggerClient-php.
  6. Run composer update --no-dev
  7. Save the sample client.php in $PWD/SwaggerClient-php.
  8. Run the client: php client.php
  9. Check the output:
$response->getTimestamp() value before add: 2017-09-21T12:39:21+00:00
$response->getTimestamp() value after add:  2017-09-28T12:39:21+00:00

It should not have been possible to modify the response.

Related issues/PRs

This applies to both format: date and format: date-time, but see #6533 where I made a comment on whether a date should just be a string and not a \DateTime.

Suggest a fix/enhancement

\DateTime should be replaced with \DateTimeImmutable. Also any code that checks if a variable is a \DateTime should check not for the class but for the interface \DateTimeInterface (ObjectSerializer->toString()).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions