Skip to content

Conversation

@jtreminio
Copy link
Contributor

@jtreminio jtreminio commented Mar 14, 2025

Currently the PHP generator cannot handle objects for content-type application/x-www-form-urlencoded and multipart/form-data.

This is because all parameters are run through ObjectSerializer::toFormValue() which calls ObjectSerializer::toString() when a value is not a SplFileObject. So, a Pet object will be attempted to be turned into a string but will fail. The issue is made worse when you have arrays of objects.

Additionally, the API methods will assign the return value of ObjectSerializer::toFormValue() to a single array key. Anything nested will not work.

Given the following:

openapi: 3.1.0
servers:
  - url: 'http://petstore.swagger.io/v2'
info:
  version: 1.0.0
  title: OpenAPI Petstore
tags:
  - name: pet
paths:
  /pet:
    post:
      tags:
        - pet
      operationId: addPet
      responses:
        '200':
          description: successful operation
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Pet'
        required: true
components:
  schemas:
    Category:
      title: Pet category
      description: A category for a pet
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
          pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
    Tag:
      title: Pet Tag
      description: A tag for a pet
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
    Pet:
      title: a Pet
      description: A pet for sale in the pet store
      type: object
      required:
        - name
        - photoUrls
      properties:
        id:
          type: integer
          format: int64
        category:
          $ref: '#/components/schemas/Category'
        name:
          type: string
          example: doggie
        photoUrls:
          type: array
          items:
            type: string
        tags:
          type: array
          items:
            $ref: '#/components/schemas/Tag'
        status:
          type: string
          description: pet status in the store
          deprecated: true
          enum:
            - available
            - pending
            - sold

and running with:

<?php

use SplFileObject;
use OpenAPI;

$config = OpenAPI\Client\Configuration::getDefaultConfiguration();

$category = (new OpenAPI\Client\Model\Category())
    ->setId(12345)
    ->setName("Category_Name");

$tags_1 = (new OpenAPI\Client\Model\Tag())
    ->setId(12345)
    ->setName("tag_1");

$tags_2 = (new OpenAPI\Client\Model\Tag())
    ->setId(98765)
    ->setName("tag_2");

$tags = [
    $tags_1,
    $tags_2,
];

try {
    (new OpenAPI\Client\Api\PetApi(config: $config))->addPet(
        name: "My pet name",
        photo_urls: [
            "https://example.com/picture_1.jpg",
            "https://example.com/picture_2.jpg",
        ],
        id: 12345,
        category: $category,
        tags: $tags,
        status: OpenAPI\Client\Model\Pet::STATUS_AVAILABLE,
    );
} catch (OpenAPI\Client\ApiException $e) {
    echo "Exception when calling PetApi#addPet: {$e->getMessage()}";
}

We see that arrays cause issues:

PHP Warning:  Array to string conversion in [...]/openapi/client/lib/ObjectSerializer.php on line 361

Objects are converted to a JSON string, and arrays are simply string literal "Array" in $formParams:

Screenshot 2025-03-14 at 12 04 19@2x

Instead, with the new ObjectSerializer::flatten_array() method, we flatten the array and make it compatible with formdata, where $formParams remains a single-level array but all nested keys are set in the correct formdata format:

Screenshot 2025-03-14 at 12 11 17@2x

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in Git BASH)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@wing328
Copy link
Member

wing328 commented Mar 14, 2025

https://github.com/OpenAPITools/openapi-generator/actions/runs/13861177290/job/38790025192?pr=20888

please update the samples to fix the CI failure

@jtreminio
Copy link
Contributor Author

Pending unit tests.

@jtreminio
Copy link
Contributor Author

Pinging maintainers:

@jebentier (2017/07), @dkarlovi (2017/07), @mandrean (2017/08), @jfastnacht (2017/09), @ybelenko (2018/07), @renepardon (2018/12)

@jtreminio jtreminio marked this pull request as ready for review March 15, 2025 20:40
@wing328
Copy link
Member

wing328 commented Mar 17, 2025

do we need to apply the same fix to php-nextgen as well?

@jtreminio
Copy link
Contributor Author

I'll take a look for php-nextgen!

@jtreminio
Copy link
Contributor Author

@wing328 I noticed that neither samples/client/petstore/php/psr-18 nor samples/client/petstore/php-nextgen have unit tests.

I'd suggest adding them in at some point, even if it's mostly copy/paste.

@wing328
Copy link
Member

wing328 commented Mar 19, 2025

linux tests passed via #20926

@wing328
Copy link
Member

wing328 commented Mar 19, 2025

I noticed that neither samples/client/petstore/php/psr-18 nor samples/client/petstore/php-nextgen

agreed. even better is to migrate to echo api tests instead: https://github.com/OpenAPITools/openapi-generator/wiki/Integration-Tests#echo-server, as we're moving away from petstore api tests

@wing328
Copy link
Member

wing328 commented Mar 19, 2025

tested locally and the result is good

@wing328 wing328 merged commit 8f24df4 into OpenAPITools:master Mar 19, 2025
15 of 21 checks passed
@wing328 wing328 added this to the 7.13.0 milestone Mar 19, 2025
@jtreminio jtreminio deleted the php-formdata-fix branch March 21, 2025 01:17
etremblay added a commit to kronostechnologies/openapi-generator that referenced this pull request May 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants