swagger-api / swagger-api/swagger-codegen
[PHP] DateTime should be DateTimeImmutable
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
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.
- Save the sample
test.yamlin$PWD. - Create a directory
$PWD/fooand place in that directory the sampleindex.php. - In
$PWDrunphp -S 127.0.0.1:80to start a quick web server. - Generate the client library from
$PWD:java -jar swagger-codegen-cli-2.3.0-20170921.031930-142.jar generate -i test.yaml -l php - Go into the directory
$PWD/SwaggerClient-php. - Run
composer update --no-dev - Save the sample
client.phpin$PWD/SwaggerClient-php. - Run the client:
php client.php - 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()).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the generated PHP client's response date casting and the ObjectSerializer->toString() entry point mentioned in the issue. Reproduce the behavior using test.yaml and client.php, then verify that date and date-time responses are immutable and that DateTimeInterface checks work as intended.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100