php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70791 Inconsistent method_exists() property_exists() behavior.
Submitted: 2015-10-26 13:28 UTC Modified: 2019-09-03 12:04 UTC
Votes:1
Avg. Score:2.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: phplists at stanvassilev dot com Assigned: nikic (profile)
Status: Closed Package: *General Issues
PHP Version: 7.0.0RC5 OS: OSX
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: phplists at stanvassilev dot com
New email:
PHP Version: OS:

 

 [2015-10-26 13:28 UTC] phplists at stanvassilev dot com
Description:
------------
The rules under which a class member is reported to "exist" for method_exists() property_exists() are inconsistent.

property_exists will look into all members visible from inside a given class, be it private, public or protected, but it won't report *parent class private properties* as existing for that class.

method_exists will report a parent class private method as existing for the child class, but the child class has no access to it internally.

This is not a new problem in PHP7, but it's an issue in general. I believe the property_exists() behavior is correct, and method_exists() causes unexpected results.

Test script:
---------------
class BobSenior {
	private $a;
	protected $b;
	
	private function a() {}
	protected function b() {}
}

class BobJunior extends BobSenior {
	private $c;
	protected $d;
	
	private function c() {}
	protected function d() {}
}

$senior = new BobSenior();
$junior = new BobJunior();

var_dump(property_exists($senior, 'a')); // bool(true) -> EXPECTED
var_dump(method_exists($senior, 'a')); // bool(true) -> EXPECTED

var_dump(property_exists($senior, 'b')); // bool(true) -> EXPECTED
var_dump(method_exists($senior, 'b')); // bool(true) -> EXPECTED

var_dump(property_exists($senior, 'c')); // bool(false) -> EXPECTED
var_dump(method_exists($senior, 'c')); // bool(false) -> EXPECTED

var_dump(property_exists($senior, 'd')); // bool(false) -> EXPECTED
var_dump(method_exists($senior, 'd')); // bool(false) -> EXPECTED

var_dump(property_exists($junior, 'a')); // bool(false) -> EXPECTED
var_dump(method_exists($junior, 'a')); // bool(true) -> *NOT* EXPECTED (EXPECTED = false)

var_dump(property_exists($junior, 'b')); // bool(true) -> EXPECTED
var_dump(method_exists($junior, 'b')); // bool(true) -> EXPECTED

var_dump(property_exists($junior, 'c')); // bool(true) -> EXPECTED
var_dump(method_exists($junior, 'c')); // bool(true) -> EXPECTED

var_dump(property_exists($junior, 'd')); // bool(true) -> EXPECTED
var_dump(method_exists($junior, 'd')); // bool(true) -> EXPECTED

Expected result:
----------------
Please check comments for expected results.

Actual result:
--------------
Please check comments for actual results.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-30 15:43 UTC] reeze@php.net
-Status: Open +Status: Not a bug
 [2015-10-30 15:43 UTC] reeze@php.net
I would say this is not a bug.  method_exists() did check for visibility. you could use `is_callable()` instead.
 [2015-10-31 13:53 UTC] phplists at stanvassilev dot com
reeze@php.net:

Can you please check the code example again. This is not about respecting or ignoring visibility.

method_exists() returns true for a situation where the method simply doesn't exist for the given class.

A private method in a superclass *does not exist* in the child class.
 [2019-09-03 12:04 UTC] nikic@php.net
-Status: Not a bug +Status: Closed -Assigned To: +Assigned To: nikic
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Jul 16 09:01:33 2025 UTC