@ 2024-03-28T18:31:58Z <?php
/**
* Strategy for converting a dynamic property that is initialized only when the property is invoked.
*
* This strategy declares the property but sets its visibility to private. By setting it to
* private (opr protected), the original intent still works, meaning it's only init and set when
* code invokes it (which invokes the __get()).
*/
class DynamicPropInitOnGet {
public $prop1;
public $prop2;
public $prop3;
private $known;
public function __construct( $props ) {
foreach ( $props as $prop => $value ) {
$this->$prop = $value;
}
}
public function __get( $prop ) {
if ( 'known' !== $prop ) {
trigger_error(
sprintf( 'Getting the dynamic property "%s" on %s is deprecated', $prop, __CLASS__ ),
E_USER_DEPRECATED
);
return null;
}
$this->known = new stdClass();
foreach ( array( 'prop1', 'prop2' ) as $column ) {
$this->known->{$column} = isset( $this->{$column} ) ? $this->{$column} : null;
}
return $this->known;
}
public function __isset( $prop ) {
if ( 'known' === $prop ) {
return isset( $this->known );
}
return false;
}
public function __set( $prop, $value ) {
if ( 'known' === $prop ) {
$this->known = $value;
return;
}
trigger_error(
sprintf( 'Setting the dynamic property "%s" on %s is deprecated', $prop, __CLASS__ ),
E_USER_DEPRECATED
);
}
public function __unset( $prop ) {
if ( 'known' === $prop ) {
unset( $this->known );
return;
}
trigger_error(
sprintf( 'Unsetting the dynamic property "%s" on %s is deprecated', $prop, __CLASS__ ),
E_USER_DEPRECATED
);
}
}
class TestMagicMethods {
private $obj;
private $is_known_prop = false;
public function __construct( $obj ) {
$this->obj = $obj;
}
public function test( $prop ) {
$this->is_known_prop = ( 'known' === $prop );
// __isset.
$this->test_isset( $prop );
// __get().
$this->test_get( $prop );
// __isset() after __get().
$this->test_isset( $prop, true );
// __unset().
$this->test_unset( $prop );
}
private function test_isset( $prop, $after_get = false ) {
$actual = isset( $this->obj->$prop );
if ( ! $after_get ) {
printf( "__isset() results should be false %s\n", $this->test_results( false === $actual ) );
} else {
$expected = $this->is_known_prop;
printf(
"\n\n__isset() after __get() results should be %s %s\n",
$this->is_known_prop ? 'true' : 'false',
$this->test_results( $expected == $actual )
);
}
var_dump( $actual );
}
private function test_get( $prop ) {
$actual = $this->obj->$prop;
$message = "\n\n__get() results should be %s %s\n";
if ( $this->is_known_prop ) {
printf( $message, 'an object with prop1 and prop2', $this->test_results( $actual instanceof stdClass ) );
} else {
printf( $message, 'null', $this->test_results( null === $actual ) );
}
var_dump( $actual );
}
private function test_set( $prop ) {
$value = $this->is_known_prop ? (array) $this->$obj->known : 'I am an unknown dynamic property';
$obj->$prop = $value;
$actual = $this->obj->$prop;
if ( $this->is_known_prop ) {
printf(
"\n\n" .
'__set() results should set the value %s and not throw a deprecation on PHP 8.2+.' .
'However, once the __get() is called again, it will set reset it to an object with prop1 and prop2.' .
"\n",
$this->test_results( $actual instanceof stdClass )
);
} else {
printf(
"\n\n" .
'__set() results should set the value %s and not throw a deprecation on PHP 8.2+.' .
'The set value should remain set when invoking __get()' .
"\n",
$this->test_results( $value === $actual )
);
}
var_dump( $actual );
}
private function test_unset( $prop ) {// unset.
unset( $this->obj->$prop );
$actual = $this->obj->$prop;
$message = "\n\n__unset() + __get() results should be %s %s\n";
if ( $this->is_known_prop ) {
printf(
$message,
're-init the object with prop1 and prop2',
$this->test_results( $actual instanceof stdClass )
);
} else {
printf(
$message,
'null',
$this->test_results( null === $actual )
);
}
var_dump( $actual );
}
private function test_results( $actual ) {
return $actual ? '✅' : '❌';
}
}
$obj = new DynamicPropInitOnGet(
array(
'prop1' => 'foo',
'prop2' => 'bar',
'prop3' => 'baz',
)
);
$tester = new TestMagicMethods( $obj );
echo "***** Test the 'known' property *****\n\n";
$tester->test( 'known' );
echo "\n\n***** Unknown, unexpected dynamic property *****\n\n";
$tester->test( 'unknown' );
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 8.4.1 0.005 0.005 19.60 8.3.14 0.013 0.006 17.14 8.3.13 0.009 0.009 18.52 8.3.12 0.000 0.009 19.30 8.3.11 0.005 0.003 20.94 8.3.10 0.009 0.000 24.06 8.3.9 0.005 0.003 26.77 8.3.8 0.008 0.004 17.97 8.3.7 0.007 0.015 16.75 8.3.6 0.010 0.007 16.72 8.3.5 0.020 0.003 16.73 8.3.4 0.010 0.017 21.59 8.3.3 0.010 0.010 19.14 8.3.2 0.014 0.003 21.82 8.3.1 0.017 0.000 21.77 8.3.0 0.012 0.003 18.89 8.2.25 0.006 0.003 16.63 8.2.24 0.000 0.009 17.21 8.2.23 0.000 0.009 22.58 8.2.22 0.000 0.011 37.54 8.2.21 0.003 0.006 26.77 8.2.20 0.006 0.003 18.41 8.2.19 0.007 0.015 16.75 8.2.18 0.010 0.010 25.92 8.2.17 0.007 0.007 19.09 8.2.16 0.012 0.006 20.05 8.2.15 0.007 0.007 19.10 8.2.14 0.009 0.006 20.55 8.2.13 0.012 0.006 20.35 8.2.12 0.004 0.011 19.22 8.2.11 0.006 0.016 19.22 8.2.10 0.019 0.003 19.28 8.2.9 0.011 0.011 20.69 8.2.8 0.007 0.011 19.45 8.2.7 0.012 0.006 18.68 8.2.6 0.006 0.009 18.88 8.2.5 0.007 0.011 19.25 8.2.4 0.010 0.010 18.82 8.2.3 0.010 0.007 18.69 8.2.2 0.013 0.007 20.61 8.2.1 0.016 0.003 18.72 8.2.0 0.000 0.018 18.56 8.1.30 0.005 0.005 18.13 8.1.29 0.006 0.003 30.84 8.1.28 0.013 0.006 25.92 8.1.27 0.011 0.007 22.22 8.1.26 0.008 0.008 22.15 8.1.25 0.009 0.006 22.30 8.1.24 0.011 0.011 18.70 8.1.23 0.010 0.007 18.66 8.1.22 0.006 0.012 18.95 8.1.21 0.010 0.010 18.76 8.1.20 0.012 0.003 18.95 8.1.19 0.010 0.007 18.59 8.1.18 0.014 0.010 18.49 8.1.17 0.008 0.012 18.81 8.1.16 0.010 0.010 18.43 8.1.15 0.013 0.006 18.86 8.1.14 0.006 0.013 18.77 8.1.13 0.013 0.010 18.85 8.1.12 0.013 0.007 18.75 8.1.11 0.012 0.006 18.66 8.1.10 0.003 0.015 19.89 8.1.9 0.008 0.008 18.81 8.1.8 0.003 0.012 19.86 8.1.7 0.012 0.003 19.07 8.1.6 0.008 0.008 18.94 8.1.5 0.009 0.006 18.63 8.1.4 0.010 0.007 18.88 8.1.3 0.009 0.006 18.77 8.1.2 0.000 0.016 20.09 8.1.1 0.006 0.009 18.77 8.1.0 0.013 0.003 18.52
preferences:dark mode live preview
46.16 ms | 403 KiB | 5 Q