Bug #72408 [Fbk->Csd]: Coalescing operator on classes with overridden __get() method and NOT __isset()

From: Date: Wed, 15 Jun 2016 11:56:49 +0000
Subject: Bug #72408 [Fbk->Csd]: Coalescing operator on classes with overridden __get() method and NOT __isset()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-201647@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72408&edit=1 ID: 72408 User updated by: kostasxx at gmail dot com Reported by: kostasxx at gmail dot com Summary: Coalescing operator on classes with overridden __get() method and NOT __isset() -Status: Feedback +Status: Closed Type: Bug Package: Scripting Engine problem Operating System: Linux 4.1.13 PHP Version: 7.0.7 Block user comment: N Private report: N New Comment: Now it makes sense. Since the parameter does not exist, the __get() is triggered. Thanks for the explanation and sorry for the trouble :). I will mark the issue as closed. Previous Comments: ------------------------------------------------------------------------ [2016-06-15 11:50:27] requinix@php.net Which it does for both tests. Your expected results are that it should say "value1" for the first test, thus invoking __get, but not try to do the same for the second. That's inconsistent. So you mean to say that both of them should show "default", right? Neither of the tests should call __get because $attribute1 and 2 are not actually defined. However, Like I said in the other bug report, ($x??$y) is equivalent to (isset($x)?$x:$y). So in this case var_dump($coal->attribute1 ?? 'default'); should be the same as var_dump(isset($coal->attribute1) ? $coal->attribute1 : 'default'); but without the second trip to ->attribute1. Since your class did not implement __isset, doing "$coal->attribute1" will call __get. That's how it is supposed to work. Because the very existence of __get means that PHP should not look only at properties defined directly on the instance to determine values. Make sense? ------------------------------------------------------------------------ [2016-06-15 11:40:24] kostasxx at gmail dot com Based on RFC, the use of coalescing operator should be equal to isset() and is based to the given example: // Fetches the request parameter user and results in 'nobody' if it doesn't exist $username = $_GET['user'] ?? 'nobody'; // equivalent to: $username = isset($_GET['user']) ? $_GET['user'] : 'nobody'; taken from here https://wiki.php.net/rfc/isset_ternary. So if you see in the updated code here https://3v4l.org/VUCFF, that isn't happening. It bypass isset() and goes to __get() directly. ------------------------------------------------------------------------ [2016-06-15 11:33:26] requinix@php.net Why is the first test supposed to call __get but the second should not? Neither $attribute1 nor $attribute2 exist so the behavior should be the same for both. ------------------------------------------------------------------------ [2016-06-15 07:27:17] kostasxx at gmail dot com Description: ------------ When __get() method is overridden in a class and NOT the __isset(), when the null coalescing operator is used, the __get() is triggered instead of native isset(). This issue is related to https://bugs.php.net/bug.php?id=71359 Test script: --------------- https://3v4l.org/RMS3W ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=72408&edit=1

« previous php.bugs (#201647) next »