Generated Entity Setter Does Not Accept NULL for Nullable ENUM Columns

Database definition

status ENUM('ACTIVE','PENDING','EXPIRED') DEFAULT NULL

Generated Entity

PHPMaker generates a setter similar to this:

public function setStatus(string $value): static
{
    if (!in_array($value, ["ACTIVE", "PENDING", "EXPIRED"])) {
        throw new InvalidArgumentException("Invalid 'status' value");
    }

    $this->status = $value;
    return $this;
}

Problem

When the field is left empty (or the application passes NULL), the generated setter throws an InvalidArgumentException, even though the database column explicitly allows NULL.

This makes nullable ENUM fields unusable through the generated Entity API.

Expected behavior

If the database column is nullable, the generated setter should also allow NULL.

For example:

public function setStatus(?string $value): static
{
    if ($value !== null && !in_array($value, ["ACTIVE", "PENDING", "EXPIRED"], true)) {
        throw new InvalidArgumentException("Invalid 'status' value");
    }

    $this->status = $value;
    return $this;
}

Notice that:

  • The parameter type should be ?string instead of string.

  • Validation should only be performed when the value is not NULL.

Why this matters

This issue causes runtime exceptions whenever an optional ENUM field is submitted empty, despite the database schema allowing NULL.

It appears that the code generator ignores the column's nullability when generating Entity setters.

Suggested fix

// @phpmaker\php2026\entity.php

<# if (f.FldTypeName == 'enum') { #>
    <# if (IsBooleanField(f)) { // Handle boolean field #>
    $value = ConvertToBool($value) ? '<#= Code.quote(TrueValue) #>' : '<#= Code.quote(FalseValue) #>';
    <# } #>
//..
<# if (f.isNullable) { #>
    if ($value !== null && !in_array($value, [<#= f.fldValues #>], true)) {
<# } else { #>
    if (!in_array($value, [<#= f.fldValues #>], true)) {
<# } #>
        throw new InvalidArgumentException("Invalid '<#= f.FldName #>' value");
}

//..
    $this-><#= f.propertyName #> = $value;
<# } #>

Reason

  • Nullable ENUM columns should accept NULL without throwing an exception.
  • Validation should only be performed when a non-NULL value is provided.
  • Using in_array(..., true) performs a strict comparison and avoids unintended type coercion.

I also noticed a similar improvement for SET fields. Although it doesn't have the same nullable issue, it should also use strict comparison:

Current:

!in_array($v, [<#= f.fldValues #>])

Suggested:

!in_array($v, [<#= f.fldValues #>], true)

This makes the generated validation more type-safe and consistent.