php / php-src

The PHP Interpreter
https://www.php.net
Other
38.23k stars 7.75k forks source link

Add get_public_members Function to PHP #15493

Open digitalcraftlabs opened 2 months ago

digitalcraftlabs commented 2 months ago

Description

This feature request proposes the addition of a new function, get_public_members, to PHP. The function will retrieve all public properties and methods of an object and return them in an associative array, enhancing PHP’s object introspection capabilities.

iluuu1994 commented 2 months ago

Hi @digitalcraftlabs. This sounds like a very narrow use-case. Does implementing this in core any benefits from solving this in useland with reflection? Also note that the names of properties and methods may clash.

digitalcraftlabs commented 2 months ago

Hi @iluuu1994 , You’re right that the get_public_members function might not be broadly needed in many standard applications. However, the main motivation behind this proposal is to simplify processes where comprehensive object introspection is required, particularly in frameworks and tools that rely heavily on dynamic object manipulation. For developers working in these areas, having such a function in the core library could significantly enhance code readability and maintainability.

The Reflection API is indeed powerful and flexible, providing detailed introspection capabilities. Implementing get_public_members in userland could be a valid alternative and offer the flexibility needed for specific requirements.

However, there are a few reasons why a core function might still be beneficial:

  1. Convenience and Standardization: A core function would provide a consistent and easy-to-use method without requiring developers to write their own solutions or depend on external libraries.
  2. Performance: A core implementation could potentially be more efficient, as it would directly leverage PHP’s internally optimized functions.

The risk of name clashes between properties and methods is a valid concern. One potential solution could be to clearly separate the results by using distinct keys in the returned array:

function get_public_members($object) {
    if (!is_object($object)) {
        throw new InvalidArgumentException("Argument must be an object.");
    }

    $publicVars = get_object_vars($object);

    $reflection = new ReflectionClass($object);
    $publicMethods = [];
    foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
        if ($method->getReturnType() && $method->getReturnType()->getName() !== 'void') {
            $publicMethods[] = $method->getName();
        }
    }

    return [
        'variables' => $publicVars,
        'methods' => $publicMethods
    ];
}

This approach would avoid confusion and make it easier to distinguish between properties and methods.

iluuu1994 commented 2 months ago
  1. Convenience and Standardization

I think this only really applies if the output of get_public_members() is directly applicable to your use-case. But I don't even know when I'd need both properties and methods at the same time.

  1. Performance

I'm not super convinced by this argument. Code using reflection of any kind (even internal reflection) inherently will rely on some slower code paths. So, I'm wondering if similar code is actually used in performance-critical codebases, and whether moving the code to core makes a meaningful difference.

Before moving forward, it would be good to know what the exact use-case is.

In any case, new functions usually need to go through the RFC process, which includes first sending an e-mail to the internals mailing list to gather feedback about the proposed feature. Is that something you would be interested in doing?

digitalcraftlabs commented 2 months ago

Yes, I am interested and will do it. Thank you.

cmb69 commented 2 months ago

This issue can stay open for now.