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
 [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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Sun May 05 04:01:32 2024 UTC