Skip to content

Reflection: have some indication of property hooks in _property_string() #17927

Closed

Description

@DanielEScherzer

Description

The following code (https://3v4l.org/1fUfI)

<?php

interface IHookedDemo {
    public mixed $prop1 { get; }
    public mixed $prop2 { set; }
    public mixed $prop3 { get; set; }
}
abstract class HookedDemo {
    abstract public mixed $prop1 { get; }
    abstract public mixed $prop2 { set; }
    abstract public mixed $prop3 { get; set; }
}
class WithHooks {
    public mixed $prop1 {
        get => "always this string";
    }
    public mixed $prop2 {
        set => strtolower($value);
    }
    public mixed $prop3 {
        get => $this->prop3;
        set => strtolower($value);
    }
}
class WithFinalHooks {
    public mixed $prop1 {
        final get => "always this string";
    }
    public mixed $prop2 {
        final set => strtolower($value);
    }
    public mixed $prop3 {
        final get => $this->prop3;
        final set => strtolower($value);
    }
}
$classes = [
    IHookedDemo::class,
    HookedDemo::class,
    WithHooks::class,
    WithFinalHooks::class,
];
foreach ( $classes as $clazz ) {
    echo "$clazz:\n";
    $ref = new ReflectionClass( $clazz );
    echo $ref;
    foreach ( [ 'prop1', 'prop2', 'prop3' ] as $prop ) {
        $propRef = new ReflectionProperty( $clazz, $prop );
        echo $propRef;
    }
    echo "\n";
}

Resulted in this output:

IHookedDemo:
Interface [ <user> <iterateable> interface IHookedDemo ] {
  @@ /in/1fUfI 3-7

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [3] {
    Property [ public mixed $prop1 ]
    Property [ public mixed $prop2 ]
    Property [ public mixed $prop3 ]
  }

  - Methods [0] {
  }
}
Property [ public mixed $prop1 ]
Property [ public mixed $prop2 ]
Property [ public mixed $prop3 ]

HookedDemo:
Class [ <user> <iterateable> abstract class HookedDemo ] {
  @@ /in/1fUfI 8-12

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [3] {
    Property [ public mixed $prop1 ]
    Property [ public mixed $prop2 ]
    Property [ public mixed $prop3 ]
  }

  - Methods [0] {
  }
}
Property [ public mixed $prop1 ]
Property [ public mixed $prop2 ]
Property [ public mixed $prop3 ]

WithHooks:
Class [ <user> <iterateable> class WithHooks ] {
  @@ /in/1fUfI 13-24

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [3] {
    Property [ public mixed $prop1 ]
    Property [ public mixed $prop2 ]
    Property [ public mixed $prop3 ]
  }

  - Methods [0] {
  }
}
Property [ public mixed $prop1 ]
Property [ public mixed $prop2 ]
Property [ public mixed $prop3 ]

WithFinalHooks:
Class [ <user> <iterateable> class WithFinalHooks ] {
  @@ /in/1fUfI 25-36

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [3] {
    Property [ public mixed $prop1 ]
    Property [ public mixed $prop2 ]
    Property [ public mixed $prop3 ]
  }

  - Methods [0] {
  }
}
Property [ public mixed $prop1 ]
Property [ public mixed $prop2 ]
Property [ public mixed $prop3 ]

But I expected this output instead:

[similar but with some indication of what properties have hooks]

In #17827 I added an indication for abstract and final properties, and was told that the missing indication was a bug, which is why I've also filed this as a bug.

PHP Version

8.4+

Operating System

No response

Activity

  1. DanielEScherzer commented on Feb 25, 2025

    @DanielEScherzer
    MemberAuthor

    CC @iluuu1994
    I figured before sending a patch it might be worth discussing how things should be shown - I propose something like

    Property [ public mixed $prop1 { get; } ]
    Property [ public mixed $prop2 { set; }]
    Property [ public mixed $prop3 { get; set; } ]
    
    Property [ public mixed $prop1 { final get; } ]
    Property [ public mixed $prop2 { final set; }]
    Property [ public mixed $prop3 { final get; final set; } ]
    

    to indicate the presence (or requirement, for interfaces and abstract cases) of property hooks, and if they are final or not

  2. iluuu1994 commented on Feb 25, 2025

    @iluuu1994
    Member

    Would be ok for me. I'm unsure whether this should also indicate "virtual", because otherwise public $prop { get; } becomes ambiguous. Is this a backed property and set is a valid, implicit operation, or is set forbidden? public virtual $prop { get; } would disambiguate.

  3. DanielEScherzer commented on Mar 20, 2025

    @DanielEScherzer
    MemberAuthor

    Would be ok for me. I'm unsure whether this should also indicate "virtual", because otherwise public $prop { get; } becomes ambiguous. Is this a backed property and set is a valid, implicit operation, or is set forbidden? public virtual $prop { get; } would disambiguate.

    Okay, I'll put the virtual before the property type. Should this be for 8.4 or master?

  4. iluuu1994 commented on Mar 21, 2025

    @iluuu1994
    Member

    master should be fine. This seems like an improvement rather than a bug fix.

  5. added a commit that references this issue on Aug 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions