Skip to content

Bug: "Only variables should be passed by reference" with end() in Enum Validation #234

@nhanifah

Description

@nhanifah

Bug/Improvement: Inefficient & Erroneous Enum Validation Logic

Current Issue

The current enum validation logic in the Xendit-PHP-SDK, specifically where getAllowableEnumValues() is used, has two primary problems:

// xendit-php/lib/ObjectSerializer.php (approx. lines 495-500)
if (method_exists($class, 'getAllowableEnumValues')) {
    if (!in_array($data, $class::getAllowableEnumValues(), true)) {
        $data = end($class::getAllowableEnumValues());
    }
    return $data;
}

Fatal Error: "Only variables should be passed by reference": This is the most critical issue. The end() function in PHP requires a variable reference as its argument. When $class::getAllowableEnumValues() is passed directly to end(), it provides a temporary return value (an array literal), not a variable. PHP cannot manipulate the internal pointer of such a temporary value, leading to this fatal error.

Inefficiency: The getAllowableEnumValues() method is called twice if the $data value is not found within the allowable enum values. It's called once inside in_array() and again when passed to end(). For methods that involve more complex operations (like fetching data from a database, file I/O, or heavy computation), these redundant calls can negatively impact the SDK's performance.


Proposed Solution

This solution was suggested by Jonas Mulingbayan (@jonasmulingbayan). To resolve both the fatal error and the inefficiency, the proposal is to refactor the code to store the result of getAllowableEnumValues() in a variable first. This ensures the method is called only once and provides a proper variable reference for end().

if (method_exists($class, 'getAllowableEnumValues')) {
    $enumValues = $class::getAllowableEnumValues(); // Call method once and store result
    if (!in_array($data, $enumValues, true)) {
        $data = end($enumValues); // Use the stored variable for end()
    }
    return $data;
}

Thank you for your consideration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions