Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Debug] UndefinedMethodFatalErrorHandler - Handle anonymous classes #21010

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

Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,13 @@ public function handleError(array $error, FatalErrorException $exception)

$message = sprintf('Attempted to call an undefined method named "%s" of class "%s".', $methodName, $className);

if (!class_exists($className) || null === $methods = get_class_methods($className)) {
// failed to get the class or its methods on which an unknown method was called (for example on an anonymous class)
return new UndefinedMethodException($message, $exception);
}

$candidates = array();
foreach (get_class_methods($className) as $definedMethodName) {
foreach ($methods as $definedMethodName) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could simply be

foreach ((array) get_class_methods($className) as $definedMethodName) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👎
I think code should be as explicit as possible. Here we want to iterate methods if there are any. We don't want to cast the result to an array and iterate that and be depended on the result of the cast. To me it makes no sense that (array) null result in an empty array, I would expect an error. Another side effect of always casting is that it would be done even when not needed.

Copy link
Contributor

@ogizanagi ogizanagi Dec 21, 2016

Choose a reason for hiding this comment

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

Casting to an array is something commonly used in the Symfony codebase, even in more critical paths where micro optimizations would matter more. To me the intention is clear, but I hear your arguments.

Also the issue here is more about class@anonymous not being a class name, which is why get_class_methods returns null as a way to notify there is an issue with the function call, not as I first thought a PHP inconsistency due to an anonymous class without any method. You don't access the generated internal class name here nor the instance, so it's expected to get null.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, micro optimizations are not needed here as it is already in error/exception path so fast execution is not that important.

Yes, sadly we cannot access the instance of the anonymous class here to figure out what methods are on there, so I guess this is the best we can do.

Let me know if the array cast is a deal breaker for the PR to be merged, always happy to agree to disagree and update a PR if the end-result is better than the current state :)

$lev = levenshtein($methodName, $definedMethodName);
if ($lev <= strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {
$candidates[] = $definedMethodName;
Expand All @@ -52,6 +57,7 @@ public function handleError(array $error, FatalErrorException $exception)
} else {
$candidates = '"'.$last;
}

$message .= "\nDid you mean to call ".$candidates;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ public function provideUndefinedMethodData()
),
"Attempted to call an undefined method named \"offsetFet\" of class \"SplObjectStorage\".\nDid you mean to call e.g. \"offsetGet\", \"offsetSet\" or \"offsetUnset\"?",
),
array(
array(
'type' => 1,
'message' => 'Call to undefined method class@anonymous::test()',
'file' => '/home/possum/work/symfony/test.php',
'line' => 11,
),
'Attempted to call an undefined method named "test" of class "class@anonymous".',
),
);
}
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.