Dynamic class with property hints creation

Hi all,
Can someone tell me how to dynamically create class with properties (including type hint/docblock) but without using eval.

Say I have a model class like this:

/**
 * @OA\Schema()
 */
class User {
   /**
     * User's ID
     * @var int
     * @OA\Property()
     */
    public int $id;

    /**
     * User's first name
     * @var string
     * @OA\Property()
     */
    public string $first_name;

    /**
     * User's last name
     * @var string
     * @OA\Property()
     */
    public string $last_name;
}

When creating User object, I expect payload with mandatory first_name and last_name, but not containing id. When updating, id is mandatory, first_name and last_name are optional. So I would like somehow to create dynamically for example:

/**
 * @OA\Schema(required={"first_name", "last_name"})
 */
class CreateUserSchema {

    /**
     * User's first name
     * @var string
     * @OA\Property()
     */
    public string $first_name;

    /**
     * User's last name
     * @var string
     * @OA\Property()
     */
    public string $last_name;
}

So that Swagger-PHP can display it nicely and I can use some validators. I can generate classes with PHP script based on found model classes, but I would like to avoid it if possible. There are anonymous classes, like:

$newClass = new class {
    public string $first_name;

    public string $last_name;
};

$newClassName = get_class($newClass);
class_alias($newClassName, 'CreateUserSchema');

But I dont know how to generate it dynamically - fields depends on the model and also list of required/optional fields. Same goes for annotations/docblocks - their content will vary depending on model class and required/optional fields.

Thank you in advance.

Best regards

There are two ways in doing this and here’s an example in what I’m talking about. This is just pseudo code:

/*
 * Construct the data for the CMS
 */
public function __construct($args = [])
{
//        $this->user_id = $args['user_id'] ?? null;
//        $this->author = $args['author'] ?? null;
//        $this->heading = $args['heading'] ?? null;
//        $this->content = $args['content'] ?? null;
//        $this->date_updated = $args['date_updated'] ?? null;
//        $this->date_added = $args['date_added'] ?? null;


    // Caution: allows private/protected properties to be set
    foreach ($args as $k => $v) {
        if (property_exists($this, $k)) {
            $this->$k = $v; // This is the what I'm talking about:
        }
    }
} // End of construct method:

Then to use it simple do the following:

        $cms = new CMS($data);

where data is an array. I hoped that this helped a little. If you do it the first way (the commented out code) then you could simply use setters and getters.

Thanks, but how can I generate phpdoc/hints programatically? Like for example I want class to get

/**
 * @OA\Schema(required={"first_name", "last_name"})
 */

and last_name:

/**
  * User's last name
  * @var string
  * @OA\Property()
  */

Any hint on this?

I’m a little unsure what you’re asking. Do you want to generate code files based on some schema, or do you want to generate different classes at run time?

Hi,
that is actually my dilemma: I can - but would like to avoid generating php files. However I am not aware is it possible to generate classes dynamically without eval() with the restriction that I want also docblocks on classes/properties to be generated programatically.

Thank you kindly

What will the docblocks be used for?

Swagger-PHP uses it to display content. Also for my personal hinting in IDE.

Ok. I’m not sure about swagger, but unless you write your own custom hinting script you’ll absolutely need a written file if you want your IDE to pick up docblocks.

Ok,thanks. IDE is just a bonus. I am searching for days and it seems apart anonymous classes, eval is the only option, but if I go with anonymous classes, I am not sure how to create docblocks on the fly. So all in all, guess creating files directly will be necessity.

Regards

Sponsor our Newsletter | Privacy Policy | Terms of Service