Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\Debug\FatalErrorHandler; Chris@0: Chris@17: use Symfony\Component\Debug\Exception\FatalErrorException; Chris@0: use Symfony\Component\Debug\Exception\UndefinedFunctionException; Chris@0: Chris@0: /** Chris@0: * ErrorHandler for undefined functions. Chris@0: * Chris@0: * @author Fabien Potencier Chris@0: */ Chris@0: class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface Chris@0: { Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function handleError(array $error, FatalErrorException $exception) Chris@0: { Chris@17: $messageLen = \strlen($error['message']); Chris@0: $notFoundSuffix = '()'; Chris@17: $notFoundSuffixLen = \strlen($notFoundSuffix); Chris@0: if ($notFoundSuffixLen > $messageLen) { Chris@0: return; Chris@0: } Chris@0: Chris@0: if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) { Chris@0: return; Chris@0: } Chris@0: Chris@0: $prefix = 'Call to undefined function '; Chris@17: $prefixLen = \strlen($prefix); Chris@0: if (0 !== strpos($error['message'], $prefix)) { Chris@0: return; Chris@0: } Chris@0: Chris@0: $fullyQualifiedFunctionName = substr($error['message'], $prefixLen, -$notFoundSuffixLen); Chris@0: if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\')) { Chris@0: $functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1); Chris@0: $namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex); Chris@0: $message = sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix); Chris@0: } else { Chris@0: $functionName = $fullyQualifiedFunctionName; Chris@0: $message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName); Chris@0: } Chris@0: Chris@17: $candidates = []; Chris@0: foreach (get_defined_functions() as $type => $definedFunctionNames) { Chris@0: foreach ($definedFunctionNames as $definedFunctionName) { Chris@0: if (false !== $namespaceSeparatorIndex = strrpos($definedFunctionName, '\\')) { Chris@0: $definedFunctionNameBasename = substr($definedFunctionName, $namespaceSeparatorIndex + 1); Chris@0: } else { Chris@0: $definedFunctionNameBasename = $definedFunctionName; Chris@0: } Chris@0: Chris@0: if ($definedFunctionNameBasename === $functionName) { Chris@0: $candidates[] = '\\'.$definedFunctionName; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: if ($candidates) { Chris@0: sort($candidates); Chris@0: $last = array_pop($candidates).'"?'; Chris@0: if ($candidates) { Chris@0: $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last; Chris@0: } else { Chris@0: $candidates = '"'.$last; Chris@0: } Chris@0: $message .= "\nDid you mean to call ".$candidates; Chris@0: } Chris@0: Chris@0: return new UndefinedFunctionException($message, $exception); Chris@0: } Chris@0: }