Skip to content

ext/standard: Deprecate calling class_exists with Enums #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ PHP 8.5 UPGRADE NOTES
4. Deprecated Functionality
========================================

- Standard:
. Calling class_exists() with an enum name is deprecated in favor of the
enum_exists() function.

========================================
5. Changed Functions
========================================
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/bug18556.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ echo "\n";
setlocale(LC_ALL, "tr_TR.utf8");
foreach(get_declared_classes() as $class)
{
if(!class_exists($class))
if(!enum_exists($class) && !class_exists($class))
echo "$class No Longer Exists!\n";

}
Expand Down
75 changes: 75 additions & 0 deletions Zend/tests/enum/class_exists-enums-deprecated.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
--TEST--
Calling class_exists() on Enums should trigger a deprecation
--DESCRIPTION--
Calling class_exists() on Enums is deprecated, but it should continue to return
the correct result. The underlying functionality for (class|trait|enum|interface)_exists
is shared, so this deprecation should only affect class_exists() function and no
other functions.
--FILE--
<?php

enum Foo {
case Bar;
}

class Bar {

}

spl_autoload_register(function ($className) {
echo "Triggered autoloader with Enum $className\n";

if ($className === 'Quux') {
enum Quux {}
}
});

echo "Testing: Foo";
var_dump(class_exists('Foo'));
var_dump(enum_exists('Foo'));

echo "Testing: Bar\n";
var_dump(class_exists('Bar'));
var_dump(!enum_exists('Bar'));
var_dump(!enum_exists('Bar', true));

echo "Testing: Quux\n";
var_dump(!class_exists('Quux', false));
var_dump(class_exists('Quux', true));
var_dump(class_exists('Quux', true));
var_dump(enum_exists('Quux', true));

echo "trait_exists() and interface_exists()\n";
var_dump(!trait_exists('Foo'));
var_dump(!trait_exists('Bar'));
var_dump(!trait_exists('Quux'));
var_dump(!interface_exists('Foo'));
var_dump(!interface_exists('Bar'));
var_dump(!interface_exists('Quux'));
?>
--EXPECTF--
Testing: Foo
Deprecated: using class_exists() for enums is deprecated, triggerred for calling class_exists() for enum "Foo". Use enum_exists() instead %s on line %d
bool(true)
bool(true)
Testing: Bar
bool(true)
bool(true)
bool(true)
Testing: Quux
bool(true)
Triggered autoloader with Enum Quux

Deprecated: using class_exists() for enums is deprecated, triggerred for calling class_exists() for enum "Quux". Use enum_exists() instead %s on line %d
bool(true)

Deprecated: using class_exists() for enums is deprecated, triggerred for calling class_exists() for enum "Quux". Use enum_exists() instead %s on line %d
bool(true)
bool(true)
trait_exists() and interface_exists()
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
6 changes: 6 additions & 0 deletions Zend/zend_builtin_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,9 @@ static inline void _class_exists_impl(zval *return_value, zend_string *name, boo
if (ZSTR_HAS_CE_CACHE(name)) {
ce = ZSTR_GET_CE_CACHE(name);
if (ce) {
if (flags == ZEND_ACC_LINKED && ce->ce_flags & ZEND_ACC_ENUM) {
zend_error(E_DEPRECATED, "using class_exists() for enums is deprecated, triggerred for calling class_exists() for enum \"%s\". Use enum_exists() instead", ZSTR_VAL(ce->name));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zend_error(E_DEPRECATED, "using class_exists() for enums is deprecated, triggerred for calling class_exists() for enum \"%s\". Use enum_exists() instead", ZSTR_VAL(ce->name));
zend_error(E_DEPRECATED, "using class_exists() for enums is deprecated, triggered for calling class_exists() for enum \"%s\". Use enum_exists() instead", ZSTR_VAL(ce->name));

(here and elsewhere)

}
RETURN_BOOL(((ce->ce_flags & flags) == flags) && !(ce->ce_flags & skip_flags));
}
}
Expand All @@ -1082,6 +1085,9 @@ static inline void _class_exists_impl(zval *return_value, zend_string *name, boo
}

if (ce) {
if (flags == ZEND_ACC_LINKED && ce->ce_flags & ZEND_ACC_ENUM) {
zend_error(E_DEPRECATED, "using class_exists() for enums is deprecated, triggerred for calling class_exists() for enum \"%s\". Use enum_exists() instead", ZSTR_VAL(ce->name));
}
RETURN_BOOL(((ce->ce_flags & flags) == flags) && !(ce->ce_flags & skip_flags));
} else {
RETURN_FALSE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ echo "\n-- Testing get_declared_classes() function with Zero arguments --\n";
var_dump(get_declared_classes());

foreach (get_declared_classes() as $class) {
if (!class_exists($class)) {
if (!enum_exists($class) && !class_exists($class)) {
echo "Error: $class is not a valid class.\n";
}
}
Expand Down
Loading