apache / apache/netbeans

[PHP] Accessing undeclared/inaccessible instance property might produce error

Open
#6,029 0 comments 0 reactions 0 assignees View on GitHub
kind:feature needs:triage PHP
Dominant language
Java
Stars
3.1k
Forks
935
Avg merge
2d 3h
Merged PRs (30d)
17

Description

### Apache NetBeans version

Apache NetBeans 18

### What happened

Recent PHP RFC related to dinamic property does not allow dinamic property by default.
Classes must declare it by ```#[AllowDynamicProperties]``` annotation or by ```__get```/```__set``` magic method.

### How to reproduce

```php
publicProp = "foo"; // OK
$this->protectedProp = "foo"; // OK
$this->privateProp = "foo"; // OK
$this->undefinedProp = "foo"; // this statement must display error

echo $this->publicProp; // OK
echo $this->protectedProp; // OK
echo $this->privateProp; // OK
echo $this->undefinedProp; // this statement must display error
}
}

class MyStrictClass2 extends MyStrictClass1 {
public function fnInstance() {
$this->publicProp = "foo"; // OK
$this->protectedProp = "foo"; // OK
$this->privateProp = "foo"; // this statement must display error
$this->undefinedProp = "foo"; // this statement must display error

echo $this->publicProp; // OK
echo $this->protectedProp; // OK
echo $this->privateProp; // this statement must display error
echo $this->undefinedProp; // this statement must display error
}
}

#[\AllowDynamicProperties]
class MyClassWithAnnotation1 {
public string $publicProp;
protected string $protectedProp;
private string $privateProp;

public function fnInstance() {
$this->publicProp = "foo"; // OK
$this->protectedProp = "foo"; // OK
$this->privateProp = "foo"; // OK
$this->undefinedProp = "foo"; // OK

echo $this->publicProp; // OK
echo $this->protectedProp; // OK
echo $this->privateProp; // OK
echo $this->undefinedProp; // OK
}
}

class MyClassWithAnnotation2 extends MyClassWithAnnotation1 {
public function fnInstance() {
$this->publicProp = "foo"; // OK
$this->protectedProp = "foo"; // OK
$this->privateProp = "foo"; // OK
$this->undefinedProp = "foo"; // OK

echo $this->publicProp; // OK
echo $this->protectedProp; // OK
echo $this->privateProp; // OK
echo $this->undefinedProp; // OK
}
}

class MyClassWithMagicMethods1 {
public string $publicProp;
protected string $protectedProp;
private string $privateProp;

public function __set($name, $value) {
$this->$name = $value;
}

public function __get($name) {
return $this->$name;
}

public function fnInstance() {
$this->publicProp = "foo"; // OK
$this->protectedProp = "foo"; // OK
$this->privateProp = "foo"; // OK
$this->undefinedProp = "foo"; // OK

echo $this->publicProp; // OK
echo $this->protectedProp; // OK
echo $this->privateProp; // OK
echo $this->undefinedProp; // OK
}
}

class MyClassWithMagicMethods2 extends MyClassWithMagicMethods1 {
public function fnInstance() {
$this->publicProp = "foo"; // OK
$this->protectedProp = "foo"; // OK
$this->privateProp = "foo"; // OK
$this->undefinedProp = "foo"; // OK

echo $this->publicProp; // OK
echo $this->protectedProp; // OK
echo $this->privateProp; // OK
echo $this->undefinedProp; // OK
}
}

$strict = new MyStrictClass1;
$strict->publicProp = "foo"; // OK
$strict->protectedProp = "foo"; // this statement must display error
$strict->privateProp = "foo"; // this statement must display error
$strict->undefinedProp = "foo"; // this statement must display error

echo $strict->publicProp; // OK
echo $strict->protectedProp; // this statement must display error
echo $strict->privateProp; // this statement must display error
echo $strict->undefinedProp; // this statement must display error

$anno = new MyClassWithAnnotation1;
$anno->publicProp = "foo"; // OK
$anno->protectedProp = "foo"; // OK
$anno->privateProp = "foo"; // OK
$anno->undefinedProp = "foo"; // OK

echo $anno->publicProp; // OK
echo $anno->protectedProp; // OK
echo $anno->privateProp; // OK
echo $anno->undefinedProp; // OK

$magic = new MyClassWithMagicMethods1;
$magic->publicProp = "foo"; // OK
$magic->protectedProp = "foo"; // OK
$magic->privateProp = "foo"; // OK
$magic->undefinedProp = "foo"; // OK

echo $magic->publicProp; // OK
echo $magic->protectedProp; // OK
echo $magic->privateProp; // OK
echo $magic->undefinedProp; // OK

function myFunc(
MyStrictClass1 $strict,
MyClassWithAnnotation1 $anno,
MyClassWithMagicMethods1 $magic,
) {
$strict->publicProp = "foo"; // OK
$strict->protectedProp = "foo"; // this statement must display error
$strict->privateProp = "foo"; // this statement must display error
$strict->undefinedProp = "foo"; // this statement must display error

echo $strict->publicProp; // OK
echo $strict->protectedProp; // this statement must display error
echo $strict->privateProp; // this statement must display error
echo $strict->undefinedProp; // this statement must display error

$anno->publicProp = "foo"; // OK
$anno->protectedProp = "foo"; // OK
$anno->privateProp = "foo"; // OK
$anno->undefinedProp = "foo"; // OK

echo $anno->publicProp; // OK
echo $anno->protectedProp; // OK
echo $anno->privateProp; // OK
echo $anno->undefinedProp; // OK

$magic->publicProp = "foo"; // OK
$magic->protectedProp = "foo"; // OK
$magic->privateProp = "foo"; // OK
$magic->undefinedProp = "foo"; // OK

echo $magic->publicProp; // OK
echo $magic->protectedProp; // OK
echo $magic->privateProp; // OK
echo $magic->undefinedProp; // OK
}

$strict->fnInstance();
$anno->fnInstance();
$magic->fnInstance();
myFunc($strict, $anno, $magic);
(new MyStrictClass2)->fnInstance();
(new MyClassWithAnnotation2)->fnInstance();
(new MyClassWithMagicMethods2)->fnInstance();
```

### Did this work correctly in an earlier version?

No / Don't know

### Operating System

Windows 10

### JDK

Java: 14.0.1; Java HotSpot(TM) 64-Bit Server VM 14.0.1+7 Runtime: Java(TM) SE Runtime Environment 14.0.1+7

### Apache NetBeans packaging

Apache NetBeans binary zip

### Anything else

_No response_

### Are you willing to submit a pull request?

No

Contributor guide

Open the contributing guide

Research direction

Start by running the supplied PHP reproduction in Apache NetBeans 18 and compare its diagnostics with the annotated OK/error expectations. Trace the PHP editor or analyzer entry point that handles instance-property access; done means declared, inaccessible, dynamic, annotated, and magic-method cases are diagnosed consistently with the example.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.