php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75543 function "defined" should ignore class constant visibility
Submitted: 2017-11-20 13:55 UTC Modified: 2019-08-29 13:04 UTC
From: matej21 at matej21 dot cz Assigned: nikic (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 7.1.11 OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: matej21 at matej21 dot cz
New email:
PHP Version: OS:

 

 [2017-11-20 13:55 UTC] matej21 at matej21 dot cz
Description:
------------
When you check if private/protected constant is defined on a class, it currently triggers a fatal error. 
For a consistency with method_exists and property_exists it should probably ignore visibility and return true

Test script:
---------------
<?php

class Foo
{
    private const BAR = 1;
}


var_dump(defined('Foo::BAR'));

Expected result:
----------------
bool(true)

Actual result:
--------------
Fatal error: Uncaught Error: Cannot access private const Foo::BAR

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-11-20 13:59 UTC] spam2 at rhsoft dot net
it should return false but not raise a fatal error at all, but there is no valid reason to return true because you can't access it outside the class
 [2017-11-20 14:47 UTC] matej21 at matej21 dot cz
The reason (as I said in the bug report) is a consistency with property_exists and method_exists, see https://3v4l.org/7PYOQ
 [2017-11-20 14:54 UTC] spam2 at rhsoft dot net
you still compare different things here and for consistency they all should return false outside of the context $this because it's simply wrong behavior leading to errors like this one which couldn't work beause for the current scope it don't exist

if(property_exists($foo, 'bar')))
{
 $foo->bar = 10;
}
_________________________________

$foo = new Foo;
var_dump(property_exists($foo, 'bar'));
var_dump(method_exists($foo, 'bar'));

defined('Foo::BAR');
_________________________________
 [2017-11-20 15:06 UTC] matej21 at matej21 dot cz
I agree with you it would be better if a current scope were taken into account for all three methods.

But you can even see in a changelog of property_exists 
( http://cz2.php.net/manual/en/function.property-exists.php ) that "This function checks the existence of a property independent of accessibility." So I suppose there was some good reason for this behavior and therefore I think "defined" function should behave in the same way.
 [2017-11-20 15:11 UTC] nikic@php.net
I believe the closer analogon to defined() on constants is isset() on properties and is_callable() on methods, both of which will take visibility into account. property_exists() and method_exists() are more like reflection methods, from a time where reflection didn't exist yet.
 [2017-11-20 15:14 UTC] spam2 at rhsoft dot net
@nikic@php.net: but in no case it has to raise a exception / fatal error because such things are typically used to test if something exists instead blindly call it and then fail - so the current behavior defeats the whole purpose
 [2017-11-20 15:19 UTC] nikic@php.net
Yes, obviously. My comment was referring to the discussion whether the return value should be true or false for an inaccessible class constant.
 [2017-11-20 17:42 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2019-08-29 13:04 UTC] nikic@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: nikic
 [2019-08-29 13:04 UTC] nikic@php.net
This has been fixed at some point: https://3v4l.org/qUMeI
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Tue Oct 06 07:00:02 2026 UTC