### Compliant Solution: Using AWS Secrets Manager Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6418.html This example shows how to retrieve a secret using the AWS Secrets Manager client. Ensure the AWS SDK is installed and configured. ```php use Aws\SecretsManager\SecretsManagerClient; use Aws\Exception\AwsException; $client = new SecretsManagerClient(...); $secretName = 'example'; doSomething($client, $secretName) function doSomething($client, $secretName) { try { $result = $client->getSecretValue([ 'SecretId' => $secretName, ]); } catch (AwsException $e) { ... } if (isset($result['SecretString'])) { $secret = $result['SecretString']; } else { $secret = base64_decode($result['SecretBinary']); } // do something with the secret MyClass->callMyService($secret); } ``` -------------------------------- ### Compliant Solution: Initialized Variable Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S836.html This example shows the correct way to handle the variable '$text' by initializing it to an empty string before the loop. This ensures the variable has a defined value and type from the start, preventing potential issues. ```php callMyService($secret); ``` -------------------------------- ### Compliant PHP Code Example Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S2011.html This example demonstrates the compliant solution where the global variable is passed as a parameter to the function. ```php function foo($myStateVariable) { // ... } ``` -------------------------------- ### Compliant Interface Naming Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S114.html This example demonstrates an interface name that follows the default regular expression `^[A-Z][a-zA-Z0-9]*$`, starting with an uppercase letter. ```php interface MyInterface {...} ``` -------------------------------- ### Noncompliant Code Example with TODO Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1135.html This example shows a function with a TODO comment that will be flagged by the rule. ```php function doSomething() { // TODO } ``` -------------------------------- ### Install PHPUnit Dependency with Composer Source: https://github.com/sonarsource/sonar-php/blob/master/its/plugin/projects/phpunit/README.adoc Use Composer to install the PHPUnit dependency for your project. Ensure Composer version 2.* is installed. ```bash composer install ``` -------------------------------- ### Compliant Solution: Correct PHP Opening Tag Usage Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S2000.html This is the compliant way to start a PHP file, with the ` [ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT ], 'http'=>array( 'method'=>"GET" ) ); $context = stream_context_create($opts); $fp = fopen('https://www.example.com', 'r', false, $context); fpassthru($fp); fclose($fp); ``` -------------------------------- ### Connect to MySQL with a secure password from environment variable (Compliant) Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S2115.html This example shows how to securely connect to a MySQL database by retrieving the password from an environment variable. ```php $password = getenv('MYSQL_SECURE_PASSWORD'); $conn = new mysqli($servername, $username, $password); ``` -------------------------------- ### Noncompliant Interface Naming Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S114.html This example shows an interface name that does not conform to the default regular expression `^[A-Z][a-zA-Z0-9]*$`, which requires interface names to start with an uppercase letter. ```php interface myInterface {...} // Noncompliant ``` -------------------------------- ### Noncompliant Code Example: Reassigning Parameters Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1226.html This example shows parameters being reassigned before their values are used. This pattern is flagged as noncompliant. ```php function foo($str, $array) { $str = "name; // Noncompliant foreach ($array as $item) { $item = "hello world"; // Noncompliant } } ``` -------------------------------- ### Noncompliant PHP Code Example Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S2011.html This example shows how global variables are accessed using the 'global' keyword and the $GLOBALS array, which are considered noncompliant practices. ```php $myGlobalVariable; function foo() { global $myGlobalVariable; // Noncompliant $GLOBALS['myGlobalVariable']; // Noncompliant // ... } ``` -------------------------------- ### Noncompliant Code Example with Redundant Parentheses Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1110.html This example shows code with redundant parentheses that do not change the order of operations or clarify intent. These should be removed. ```php $x = (($y / 2 + 1)); ``` ```php if ($a && (($x + $y > 0))) { return (($x + 1)); } ``` -------------------------------- ### Compliant File Header Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1451.html A compliant file header includes copyright information and license details. This example shows the expected format for the header. ```text /* * SonarQube, open source software quality management tool. * Copyright (C) 2008-2013 SonarSource * mailto:contact AT sonarsource DOT com * * SonarQube is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * SonarQube is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ``` -------------------------------- ### Compliant Regex Syntax and String Replacement Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S5856.html These examples demonstrate compliant regular expressions with properly escaped special characters and correct capturing group references. The str_replace example shows an alternative that avoids regular expression interpretation. ```php preg_match("/\\(\\[/", $input); ``` ```php str_replace("(\[", "{", $input); ``` ```php preg_replace("/(\\w+)-(\\d+)/", "1234", $input); ``` -------------------------------- ### Compliant Function with Echo and Loop Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1116.html This compliant example shows a function that echoes a variable and then executes a loop with a clear body. ```php function doSomethingElse($p) { echo $p; for ($i = 1; $i <= 10; $i++) { doSomething($i); } } ``` -------------------------------- ### Noncompliant Use of TLSv1.1 Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S4423.html This example demonstrates the noncompliant usage of STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, which is considered a weak and deprecated protocol. ```php $opts = array( 'ssl' => [ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT // Noncompliant ], 'http'=>array( 'method'=>"GET" ) ); $context = stream_context_create($opts); $fp = fopen('https://www.example.com', 'r', false, $context); fpassthru($fp); fclose($fp); ``` -------------------------------- ### Compliant Assertions with Distinct Values Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S5863.html These examples demonstrate compliant assertions where a variable is compared against a different value. ```PHP assertEqual($expected, $a); ``` ```PHP assertSame($expected, $a); ``` ```PHP assertNotEqual($expected, $a); ``` ```PHP assertNotSame($expected, $a); ``` -------------------------------- ### Noncompliant: Allow External Requests Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6345.html This code example shows a noncompliant configuration where external requests are not blocked. This can lead to security vulnerabilities. ```php define( 'WP_HTTP_BLOCK_EXTERNAL', false ); // Noncompliant ``` -------------------------------- ### Compliant Function Name Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S100.html This is the corrected version of the previous example, adhering to the default camelCase naming convention. ```php function doSomething(){ // ... } ``` -------------------------------- ### Compliant: Single Property Per Statement Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1766.html This example demonstrates the compliant solution where each property is declared in its own statement. This improves code readability and maintainability. ```php divide($divisor, $dividend); // Compliant } ``` -------------------------------- ### Noncompliant Nested Control Flow Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S134.html This example shows code that exceeds the default nesting depth limit of 3. Issues are reported starting at the first level that violates the threshold. ```php if (condition1) { // Compliant - depth = 1 ... if (condition2) { // Compliant - depth = 2 ... for($ = 0; $i < 10; $i++) { // Compliant - depth = 3, not exceeding the limit ... if (condition4) { // Non-Compliant - depth = 4 if (condition5) { // Depth = 5, exceeding the limit, but issues are only reported on depth = 4 ... } return; } } } } ``` -------------------------------- ### Compliant Constant Naming Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S115.html This example demonstrates constants defined using `define` and as class constants that adhere to the expected naming convention. Ensure all your constants follow this pattern for better code quality. ```php define("CONST1", true); class Foo { const CONST2 = "bar"; } ``` -------------------------------- ### Build Project and Run Unit Tests Source: https://github.com/sonarsource/sonar-php/blob/master/README.md Execute this command from the project's root directory to build the SonarPHP plugin and run its unit tests. ```shell ./gradlew build ``` -------------------------------- ### Refactor Duplicate Method Implementations Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S4144.html This example shows how to refactor duplicate method logic by having one method call the other, improving code clarity and maintainability. ```php class A { private const CODE = "secret"; public function getCode() { doTheThing(); return A::CODE; } public function getName() { // Intent is clear return $this->getCode(); } } ``` -------------------------------- ### Initialize Git Submodules Source: https://github.com/sonarsource/sonar-php/blob/master/README.md Before running integration tests, ensure all submodules are checked out by running this command. ```shell git submodule update --init ``` -------------------------------- ### Compliant Code: Brace on Same Line Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1105.html This example demonstrates the compliant code where the opening curly brace is placed on the same line as the condition. This adheres to the rule. ```php if(condition) { doSomething(); } ``` -------------------------------- ### Compliant PHP Code with Unique `define` Statements Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6344.html This example demonstrates the correct way to define constants, ensuring each constant is defined only once. This prevents warnings and ensures the intended value is used. ```php define( 'SCRIPT_DEBUG', 1 ); // Compliant define( 'CONSTANT_VALUE', 'intended value' ); echo CONSTANT_VALUE; // output: 'intended value' ``` -------------------------------- ### Noncompliant Code Example using goto Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S907.html This snippet demonstrates the noncompliant use of `goto` to create a loop. Using `goto` makes the control flow harder to follow compared to standard loop constructs. ```php $i = 0; loop: echo("i = $i"); $i++; if ($i < 10){ goto loop; } ``` -------------------------------- ### Example of a Laravel Validation String Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1192.html This example shows a string that is an exception to the rule. Laravel validation strings like 'required' are not flagged. ```php $severity = $request->getParam('severity-score'); ``` -------------------------------- ### Compliant open_basedir Configuration Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S3333.html These examples demonstrate compliant configurations for the open_basedir directive. They specify restricted directories, enhancing security by limiting file system access. ```ini ; php.ini open_basedir="${USER}/scripts/data" ``` ```ini ; php.ini try 1 open_basedir="/var/www/myapp/data" ``` -------------------------------- ### Compliant Solution: Corrected Variable Usage Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S4142.html This example demonstrates the correct way to pass arguments to a method, ensuring that different variables or distinct computed values are used when necessary. ```php if (compare($a+$y, $a+$x) != 0) { //... } ``` ```php $v1 = getValue($a); $v2 = getValue($a); if (compare($v1, $v2) != 0) { // ... } ``` -------------------------------- ### Noncompliant Code Example: Duplicate Variable in Method Call Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S4142.html This example shows a method call where the same variable is passed twice. This is usually a mistake and should be corrected. ```php if (compare($a+$x, $a+$x) != 0) { // Noncompliant //... } ``` ```php if (compare(getValue($a), getValue($a)) != 0) { // Noncompliant // ... } ``` -------------------------------- ### Compliant: Enable Automatic Updates Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6343.html These examples demonstrate compliant ways to enable automatic updates, ensuring security patches are applied promptly. Options include enabling all updates or only minor ones. ```php define( 'WP_AUTO_UPDATE_CORE', true ); // Minor and major automatic updates enabled ``` ```php define( 'WP_AUTO_UPDATE_CORE', 'minor' ); // Only minor updates are enabled ``` ```php define( 'AUTOMATIC_UPDATER_DISABLED', false ); ``` -------------------------------- ### Noncompliant Code Example: Unused Parameter Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1172.html This noncompliant code example demonstrates a function where the parameter '$a' is declared but not used within the function's body. ```php function doSomething($a, $b) { // "$a" is unused return compute($b); } ``` -------------------------------- ### Update All Rule Descriptions Source: https://github.com/sonarsource/sonar-php/blob/master/README.md Run this command to update all rule descriptions in the project. ```shell ./gradlew ruleApiUpdate ``` -------------------------------- ### Noncompliant Code Example: Variable Shadowing Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1117.html This example demonstrates a local variable '$myField' shadowing a class property '$myField'. This can lead to confusion and unintended behavior. ```php class Foo { public $myField; public function doSomething() { $myField = 0; // Noncompliant ... } } ``` -------------------------------- ### Compliant Test Skipping with Explanation Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1607.html This example shows a compliant way to skip a test by providing a clear message explaining why it's being skipped. This ensures the reason is documented. ```php protected function setUp() { if (!extension_loaded('mysqli')) { $this->markTestSkipped( 'The MySQLi extension is not available.' ); // Compliant } } ``` -------------------------------- ### Noncompliant Code Example: Uninitialized Variable Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S836.html This example demonstrates the incorrect usage of an uninitialized variable '$text' within a loop. The variable is used before it has been assigned a value, which can lead to notices or warnings. ```php > checkClasses() { return List.of(DangerousFunctionCheck.class, DeprecatedFunctionCheck.class); } @Override public void define(Context context) { NewRepository repo = context.createRepository(repositoryKey(), "php") .setName("My Company PHP Rules"); // Load metadata from @Rule annotations on each check class RulesDefinitionAnnotationLoader loader = new RulesDefinitionAnnotationLoader(); checkClasses().forEach(cls -> loader.load(repo, cls)); // Optionally override descriptions with HTML files from classpath: // src/main/resources/org/sonar/l10n/php/rules/my-company-php/S42.html repo.rules().forEach(rule -> { var url = getClass().getResource("/org/sonar/l10n/php/rules/my-company-php/" + rule.key() + ".html"); if (url != null) { rule.setHtmlDescription(/* load url content */); } }); // Set remediation costs (constant per issue) repo.rule("S42").setDebtRemediationFunction( repo.rule("S42").debtRemediationFunctions().constantPerIssue("10min")); repo.done(); } } // Plugin entry point wiring the repository into SonarQube import org.sonar.api.Plugin; public class MyPhpPlugin implements Plugin { @Override public void define(Context context) { context.addExtension(MyPhpRules.class); } } ``` -------------------------------- ### Noncompliant Code: Hard-coded Secret Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6418.html This example shows a secret being assigned directly to a variable. Secrets should never be hard-coded. ```php $secret = '47828a8dd77ee1eb9dde2d5e93cb221ce8c32b37'; // Noncompliant MyClass->callMyService($secret); ``` -------------------------------- ### Noncompliant Code Example: Self-Assignment Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1656.html This code demonstrates a self-assignment where the variable $name is assigned to itself. This is redundant and should be removed or corrected. ```php public function setName($name) { $name = $name; } ``` -------------------------------- ### Use namespaces for compliant code Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S4833.html This demonstrates the compliant solution using namespaces to import classes. Ensure your project is set up with Composer and follows the PSR-4 autoloading standard. ```php use Shop\Vegetable\Tomato; ``` -------------------------------- ### Compliant RSA Private Key Generation (PHP) Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S4426.html This example shows how to generate an RSA private key with a minimum recommended key size of 2048 bits. This provides a stronger level of security against attacks. ```php $config = [ "digest_alg" => "sha512", "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_RSA, ]; $res = openssl_pkey_new($config); ``` -------------------------------- ### Regex with Lookahead Contradiction Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6002.html This example shows a noncompliant regex where the lookahead assertion creates a contradiction. The same character cannot simultaneously be 'a' and 'b'. ```php preg_match("/(?=a)b/", $str); ``` -------------------------------- ### Avoid Reluctant Quantifiers in Regex Patterns Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S5857.html Noncompliant examples using reluctant quantifiers. These can be inefficient and vulnerable to catastrophic backtracking. ```regex /<.+?>/ ``` ```regex /".*?"/ ``` -------------------------------- ### Parsing PHP Source Code Source: https://context7.com/sonarsource/sonar-php/llms.txt Demonstrates how to use `PHPParserBuilder.createParser()` to parse PHP source code into an Abstract Syntax Tree (AST). This is useful for standalone analysis requiring access to the full AST. ```APIDOC ## Parsing PHP Source Code with `PHPParserBuilder` `PHPParserBuilder.createParser()` creates an `ActionParser` that parses a PHP source string or file into a `CompilationUnitTree`. This is the entry point for any standalone analysis that needs access to the full AST. ```java import com.sonar.sslr.api.typed.ActionParser; import org.sonar.php.parser.PHPParserBuilder; import org.sonar.plugins.php.api.tree.Tree; import org.sonar.plugins.php.api.tree.CompilationUnitTree; // Create a full-file parser (starts at COMPILATION_UNIT grammar rule) ActionParser parser = PHPParserBuilder.createParser(); String phpSource = "params()->fromPost('name'); ``` -------------------------------- ### Noncompliant: Throwing a non-Throwable class instance Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S5632.html This example shows a class that does not implement 'Throwable' being thrown. This will cause a runtime error. ```php class NoThrowable {} throw new NoThrowable(); // Noncompliant ``` -------------------------------- ### Use Full PHP Tags Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1757.html Always use the full ` ``` -------------------------------- ### Generate License Resources Source: https://github.com/sonarsource/sonar-php/blob/master/README.md Use this command to fix license packaging issues by regenerating license files for third-party libraries. Note that this overwrites existing license files in the specified folder. ```shell ./gradlew generateLicenseResources ``` -------------------------------- ### Noncompliant: Single-Line If Statement Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S2681.html This example shows a single-line `if` statement where the subsequent line is unconditionally executed because curly braces are omitted. ```php if($condition) firstActionInBlock(); // Noncompliant ``` -------------------------------- ### Noncompliant Test Skipping Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1607.html This example shows a test that is skipped without providing a reason. This can lead to tests being ignored indefinitely. ```php protected function setUp() { if (!extension_loaded('mysqli')) { $this->markTestSkipped(); // Noncompliant } } ``` -------------------------------- ### Noncompliant: Sending OS Signal with Untrusted PID Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S4828.html This example shows a noncompliant way to send an OS signal. The process ID is directly taken from user input (`$_GET["pid"]`) without any validation, making it vulnerable to manipulation. ```php $targetPid = (int)$_GET["pid"]; posix_kill($targetPid, 9); // Noncompliant ``` -------------------------------- ### Remove Unused Local Variable Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1481.html This example shows a function with an unused local variable '$seconds'. Removing it improves the code. ```php function numberOfMinutes($hours) { $seconds = 0; // Noncompliant - $seconds is unused return hours * 60; } ``` ```php function numberOfMinutes($hours) { return hours * 60; } ``` -------------------------------- ### Namespace and Use Declaration Placement Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1808.html The 'use' declaration must follow the 'namespace' declaration. A blank line is required after the 'namespace' declaration and before the first 'use' declaration. ```php namespace Vendor\Package; use FooClass; ``` -------------------------------- ### Running Checks with `PHPAnalyzer` Source: https://context7.com/sonarsource/sonar-php/llms.txt Illustrates how to use `PHPAnalyzer` to orchestrate parsing, symbol table construction, and check execution for a given `InputFile`. It allows loading, parsing, analyzing code, and computing metrics. ```APIDOC ## Running Checks with `PHPAnalyzer` `PHPAnalyzer` orchestrates parsing, symbol table construction, and check execution for a given `InputFile`. Call `nextFile()` to load and parse a file, then `analyze()` to run all registered checks, and `analyzeTest()` for test-file-specific checks. ```java import org.sonar.php.PHPAnalyzer; import org.sonar.php.symbols.ProjectSymbolData; import org.sonar.php.filters.SuppressWarningFilter; import org.sonar.DurationStatistics; import org.sonar.api.batch.fs.InputFile; import org.sonar.plugins.php.api.visitors.PHPCheck; import org.sonar.plugins.php.api.visitors.PhpIssue; import java.util.List; // Build an analyzer with a set of checks List checks = List.of(new MyCustomCheck()); List testChecks = List.of(); ProjectSymbolData projectSymbolData = new ProjectSymbolData(); DurationStatistics statistics = new DurationStatistics(false); SuppressWarningFilter suppressFilter = new SuppressWarningFilter(); PHPAnalyzer analyzer = new PHPAnalyzer( checks, testChecks, null, // workingDir projectSymbolData, statistics, null, // cacheContext suppressFilter, true // frameworkDetectionEnabled ); // Load and parse a file InputFile inputFile = /* obtained from SensorContext */; analyzer.nextFile(inputFile); // Execute all checks → collect issues List issues = analyzer.analyze(); for (PhpIssue issue : issues) { System.out.println(issue); } // Compute code metrics // FileLinesContext fileLinesContext = /* from SensorContext */; // FileMeasures measures = analyzer.computeMeasures(fileLinesContext); // System.out.println("LOC: " + measures.getLinesOfCodeNumber()); // System.out.println("Complexity: " + measures.getFileComplexity()); // Clean up check state between files analyzer.terminate(); ``` ``` -------------------------------- ### Missing Newline Example Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S113.html Illustrates how a Git diff appears when a file is missing a newline at the end. This indicates the rule violation. ```text +class Test { } \ No newline at end of file ``` -------------------------------- ### Throwing a Specific Exception (Compliant) Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S112.html This example shows how to throw a specific exception, `UnexpectedValueException`. This allows consumers to catch and handle this particular error type intentionally, improving robustness. ```php function checkValue($value) { if ($value == 42) { throw new UnexpectedValueException("Value is 42"); // Compliant } } ``` -------------------------------- ### Compliant Test Incompleteness with Explanation Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1607.html This example demonstrates a compliant test marked as incomplete, including a message that explains the reason. This practice helps maintain test quality and trackability. ```php public function testSomething() { $this->assertTrue($result->isValid()); $this->markTestIncomplete( 'Testing result validation is incomplete.' ); // Compliant } ``` -------------------------------- ### Noncompliant: Hardcoded Secret Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6437.html This example shows a hardcoded password that is directly embedded in the source code. This is a security vulnerability as it can be easily exposed. ```php use Defuse\Crypto\KeyOrPassword; function createKey() { $password = "3xAmpl3"; // Noncompliant return KeyOrPassword::createFromPassword($password); } ``` -------------------------------- ### Compliant Solution After Removing Redundant Parentheses Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1110.html This example demonstrates the compliant code after removing the redundant parentheses from the noncompliant version. The logic remains the same, but the code is cleaner. ```php $x = ($y / 2 + 1); ``` ```php if ($a && ($x + $y > 0)) { return ($x + 1); } ``` -------------------------------- ### Compliant: Using Dependency Injection in Constructor Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S2830.html This code demonstrates the compliant solution using dependency injection. The dependency is passed into the constructor, allowing for loose coupling and easier testing. ```php class SomeClass { public function __construct(SomeOtherClass $object) { $this->object = $object; } } ``` -------------------------------- ### Compliant regex after removing superfluous quantifiers Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6396.html These examples show the simplified versions of the previous regular expressions after removing the redundant quantifiers. ```regex "/abc/" ``` ```regex "/ac/" ``` -------------------------------- ### Class Inheritance Placement Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S1808.html The class name and the 'extends' or 'implements' keyword should appear on the same line. ```php class ClassB extends ParentClass ``` -------------------------------- ### Noncompliant: Disable Automatic Updates Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6343.html These examples show how to disable automatic updates, which is considered noncompliant due to potential security risks. ```php define( 'WP_AUTO_UPDATE_CORE', false ); // Noncompliant ``` ```php define( 'AUTOMATIC_UPDATER_DISABLED', true ); // Noncompliant ``` -------------------------------- ### Noncompliant Regex with Empty Group Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S6331.html This example shows a regular expression with an empty group that will not capture as intended. It is likely a mistake and should be corrected. ```regex "/foo()/" ``` -------------------------------- ### Compliant str_replace for simple string replacement Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S5361.html This example demonstrates the compliant solution using str_replace for simple string replacements, avoiding the performance cost of regex evaluation. ```php $str = "Bob is a Bird... Bob is a Plane... Bob is Superman!"; $changed = str_replace("Bob is", "It's", $str); $changed = str_replace("...", ";", $changed); ``` -------------------------------- ### Compliant Regex Solutions Source: https://github.com/sonarsource/sonar-php/blob/master/php-checks/src/main/resources/org/sonar/l10n/php/rules/php/S5855.html These are the corrected versions of the noncompliant examples, with the redundant alternatives removed. They represent the simplified and efficient regex patterns. ```regex "/\\\[ab\\\\]/" ``` ```regex "/.* /" ```