Skip to content
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

Add Sniff to ensure file only uses PHP native functions or functions defined in the current file #315

Open
1 task
aaronjorbin opened this issue Aug 14, 2024 · 1 comment

Comments

@aaronjorbin
Copy link

aaronjorbin commented Aug 14, 2024

Is your feature request related to a problem?

In WordPress, there are a handful of files that need to function on their own. A sniff that detects the use of functions besides those available from PHP itself and those declared in the file itself.

Describe the solution you'd like

File 1 which would pass without issue:

<?PHP 

function foo( $arg ){
 $arguments = func_get_args(); // allowed since function is a part of the PHP standard lib
}

function bar( $arg ){
 return foo( $arg ); // allowed since foo is defined in this file
}

File 2 which would raise an issue

<?PHP

function baz( $arg ){
  return foo( $arg ); // foo is defined in a different file and these this would trigger an issue
}

?>

Additional context (optional)

This is discussed in https://core.trac.wordpress.org/ticket/61694 which is a follow up to prevent issues like the one described in https://core.trac.wordpress.org/ticket/61680

  • I intend to create a pull request to implement this feature.
@jrfnl jrfnl changed the title Add Sniff to ensure file only uses already defined functions Add Sniff to ensure file only uses PHP native functions or functions defined in the current file Aug 14, 2024
@jrfnl
Copy link
Member

jrfnl commented Aug 15, 2024

Notes which I previously already shared about this feature request:

Would be quite doable to write in principle, but will never do exactly what you want - get_defined_functions()['internal'] (which such a sniff would use to determine the PHP native functions) will get you all the functions defined at runtime of the sniff and has no information on whether the function is defined in the PHP standard/Core library, in a bundled, always-on PHP extension or in an optional or even a PECL extension which happens to be enabled in the runtime running the sniff/script.

I have a utility lined up for PHPCSUtils 1.2.0 which will make writing the sniff straight-forward (and reliable).

Source: https://core.trac.wordpress.org/ticket/61694#comment:8

Regarding PHPCSUtils 1.2.0:

The specific utility in PHPCSUtils 1.2.0 which I'm talking about is a namespace aware DeclaredFunctionsTracker, which will be able to get the fully qualified name of all declared functions in a file.

Additionally, PHPCSUtils 1.2.0 is expected to include a NamespaceTracker and an ImportUseTracker, which will allow to resolve function calls to their fully qualified name, meaning that it will make the sniff more reliable.

Mind: it will still take a while before PHPCSUtils 1.2.0 is released (I'm currently still finishing off the 1.1.0 release).

Other caveats/Open questions

  • What about classes ? Should the sniff also check that any classes/interfaces/traits/enums used are declared in the file itself ? And if so desired, should this be handled in the same sniff or in a separate sniff ?
    Keep in mind, the sniff will not have any awareness of any autoloaders which may or may not be in place.
  • The sniff will not be able to follow (include|require)[_once] statements, which may include files which declare some additional functions, making them effectively available to the file from that point onwards.
    How should that be handled ? Should the sniff flag (include|require)[_once] statements ? Or should the sniff maybe lower the error level from error to warning when an include/require has been seen ?
  • And what about the use of global variables ? I'm not talking about the PHP native superglobals, but about variables used by functions via a global ... statement or via $_GLOBALS['name'], or in the global scope by their name, while those variable may or may not be defined in the file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants