# PHP

## Language-specific properties <a href="#language-specific-properties" id="language-specific-properties"></a>

Discover and update the PHP-specific [analysis-parameters](https://docs.sonarsource.com/sonarqube-server/9.9/analyzing-source-code/analysis-parameters "mention") in **Administration > General Settings > Languages > PHP**

## Analyze php.ini Files <a href="#analyze-files" id="analyze-files"></a>

The PHP analyzer can analyze `php.ini` files with some specific rules (if these rules are activated in your quality profile). `php.ini` files must be part of the project you are analyzing, meaning the `php.ini` files have to be inside the directories listed in `sonar.sources`. Rules targeting `php.ini` files can be quickly identified through the php-ini tag set on them.

## Custom Rules <a href="#custom-rules" id="custom-rules"></a>

### Overview <a href="#overview" id="overview"></a>

The PHP analyzer parses the source code, creates an Abstract Syntax Tree (AST), and then walks through the entire tree. A coding rule is a visitor that is able to visit nodes from this AST.

As soon as the coding rule visits a node, it can navigate its children and log issues if necessary.

### Example plugin <a href="#example-plugin" id="example-plugin"></a>

To get started a sample plugin can be found here: [php-custom-rules-plugin](https://github.com/SonarSource/sonar-php/tree/master/php-custom-rules-plugin).

### Writing a plugin <a href="#writing-a-plugin" id="writing-a-plugin"></a>

Custom rules for PHP can be added by writing a SonarQube Plugin and using PHP analyzer APIs. Here are the steps to follow:

**Create SonarQube plugin**

* create a standard SonarQube plugin project
* attach this plugin to the SonarQube PHP analyzer through the `pom.xml` (Gradle Kotlin: `build.gradle.kts` )
* implement the following extension points:
  * [Plugin](https://javadocs.sonarsource.org/latest/org/sonar/api/Plugin.html)
  * [RulesDefinition](https://javadocs.sonarsource.org/latest/org/sonar/api/server/rule/RulesDefinition.html) and [PHPCustomRuleRepository](https://github.com/SonarSource/sonar-php/blob/master/php-frontend/src/main/java/org/sonar/plugins/php/api/visitors/PHPCustomRuleRepository.java), which can be implemented by a single class, to declare your custom rules
* declare the RulesDefinition as an extension in the Plugin extension point.

**Implement a rule**

* create a class that will hold the implementation of the rule, it should:
  * extend `PHPVisitorCheck` or `PHPSubscriptionCheck`
  * define the rule name, key, tags, etc. with Java annotations.
* declare this class in the `RulesDefinition`.

**Implementation details**

**Using** **`PHPVisitorCheck`**

To explore a part of the AST, override a method from the PHPVisitorCheck. For example, if you want to explore "if statement" nodes, override [PHPVisitorCheck#visitIfStatement](https://github.com/SonarSource/sonar-php/blob/master/php-frontend/src/main/java/org/sonar/plugins/php/api/visitors/PHPVisitorCheck.java#L265) method that will be called each time an [ifStatementTree](https://github.com/SonarSource/sonar-php/blob/master/php-frontend/src/main/java/org/sonar/plugins/php/api/tree/statement/IfStatementTree.java) node is encountered in the AST.

When overriding a visit method, you must call the super method in order to allow the visitor to visit the children of the node.

**Using** **`PHPSubscriptionCheck`**

To explore a part of the AST, override [`PHPSubscriptionCheck#nodesToVisit`](https://github.com/SonarSource/sonar-php/blob/master/php-frontend/src/main/java/org/sonar/plugins/php/api/visitors/PHPSubscriptionCheck.java#L33) by returning the list of the [`Tree#Kind`](https://github.com/SonarSource/sonar-php/blob/master/php-frontend/src/main/java/org/sonar/plugins/php/api/tree/Tree.java#L124) of node you want to visit. For example, if you want to explore "if statement" nodes the method will return a list containing the element [`Tree#Kind#IF_STATEMENT`](https://github.com/SonarSource/sonar-php/blob/master/php-frontend/src/main/java/org/sonar/plugins/php/api/tree/Tree.java#L761).

**Create Issues**

From the check, the issue can be created by calling [`CheckContext#newIssue`](https://github.com/SonarSource/sonar-php/blob/master/php-frontend/src/main/java/org/sonar/plugins/php/api/visitors/CheckContext.java#L90) method.

**Testing Checks**

To test custom checks you can use the method [`PHPCheckVerifier#verify`](https://github.com/SonarSource/sonar-php/blob/master/php-frontend/src/main/java/org/sonar/plugins/php/api/tests/PHPCheckVerifier.java#L55). You should end each line with an issue with a comment in the following form:

```css-79elbk
// Noncompliant {{Message}}
```

Comment syntax is described [here](https://github.com/SonarSource/sonar-analyzer-commons/blob/master/test-commons/README.md).

## Related Pages <a href="#related-pages" id="related-pages"></a>

* [overview](https://docs.sonarsource.com/sonarqube-server/9.9/analyzing-source-code/test-coverage/overview "mention")
* [adding-coding-rules](https://docs.sonarsource.com/sonarqube-server/9.9/extension-guide/adding-coding-rules "mention")
