Author: Markus Staab (staabm)
Committer: Derick Rethans (derickr)
Date: 2026-06-17T12:10:29+01:00

Commit: 
https://github.com/php/web-php/commit/aaf36935fbe31ff603a537fb9ecd87f864ff5c8f
Raw diff: 
https://github.com/php/web-php/commit/aaf36935fbe31ff603a537fb9ecd87f864ff5c8f.diff

Setup PHPStan

Changed paths:
  A  phpstan-baseline.neon
  A  phpstan.neon.dist
  M  .github/CONTRIBUTING.md
  M  .github/workflows/integrate.yaml
  M  Makefile


Diff:

diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index c00267ff51..28456451f9 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -74,6 +74,19 @@ about what you're working on, you can contact us via the
   ```
 
   to automatically fix coding standard issues.
+- Run
+
+  ```shell
+  make static-analysis
+  ```
+
+  to run a static analysis or, if applicable, run
+
+  ```shell
+  make static-analysis-baseline
+  ```
+
+  to regenerate the baseline.
 - Review the change once more just before submitting it.
 
 ## What happens after submitting contribution?
@@ -134,6 +147,20 @@ Having said that, here are the organizational rules:
    make coding-standards
    ```
 
-6. Use reasonable commit messages.
+6. Run
+
+  ```shell
+  make static-analysis
+  ```
+
+to run a static analysis or, if applicable, run
+
+  ```shell
+  make static-analysis-baseline
+  ```
+
+to regenerate the baseline.
+
+7. Use reasonable commit messages.
 
 Thank you for contributing to https://www.php.net!
diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml
index 14a7a72a1c..16fd55c1f9 100644
--- a/.github/workflows/integrate.yaml
+++ b/.github/workflows/integrate.yaml
@@ -107,6 +107,49 @@ jobs:
       - name: "Validate XML files"
         run: "for a in $(find . -name '*.xml'); do xmllint --quiet --noout $a; 
done"
 
+  static-analysis:
+    name: "Static Analysis"
+
+    runs-on: "ubuntu-latest"
+
+    strategy:
+      matrix:
+        php-version:
+          - "8.2"
+
+        dependencies:
+          - "locked"
+
+    steps:
+      - name: "Checkout"
+        uses: "actions/checkout@v3"
+
+      - name: "Set up PHP"
+        uses: "shivammathur/setup-php@v2"
+        with:
+          coverage: "none"
+          extensions: "none, curl, dom, json, mbstring, tokenizer, xml, 
xmlwriter, iconv"
+          php-version: "${{ matrix.php-version }}"
+
+      - name: "Set up problem matchers for PHP"
+        run: "echo \"::add-matcher::${{ runner.tool_cache }}/php.json\""
+
+      - name: "Determine composer cache directory"
+        run: "echo \"COMPOSER_CACHE_DIR=$(composer config cache-dir)\" >> 
$GITHUB_ENV"
+
+      - name: "Cache dependencies installed with composer"
+        uses: "actions/cache@v3"
+        with:
+          path: "${{ env.COMPOSER_CACHE_DIR }}"
+          key: "php-${{ matrix.php-version }}-composer-${{ 
hashFiles('composer.lock') }}"
+          restore-keys: "php-${{ matrix.php-version }}-composer-"
+
+      - name: "Install dependencies with composer"
+        run: "composer install --ansi --no-interaction --no-progress"
+
+      - name: "Run static analysis"
+        run: "vendor/bin/phpstan"
+
   tests:
     name: "Tests"
 
diff --git a/Makefile b/Makefile
index 12de398fe1..724f253731 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ HTTP_HOST:=localhost:8080
 CORES?=$(shell (nproc  || sysctl -n hw.ncpu) 2> /dev/null)
 
 .PHONY: it
-it: coding-standards tests ## Runs all the targets
+it: coding-standards static-analysis tests ## Runs all the targets
 
 .PHONY: code-coverage
 code-coverage: vendor ## Collects code coverage from running unit tests with 
phpunit/phpunit
@@ -18,6 +18,14 @@ coding-standards: vendor ## Fixes code style issues with 
friendsofphp/php-cs-fix
 help: ## Displays this list of targets with descriptions
        @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 
'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}'
 
+.PHONY: static-analysis
+static-analysis: vendor ## Runs a static code analysis
+       vendor/bin/phpstan
+
+.PHONY: static-analysis-baseline
+static-analysis-baseline: vendor ## Generates a baseline for static analysis
+       vendor/bin/phpstan --generate-baseline
+
 .PHONY: tests
 tests: vendor ## Runs unit and end-to-end tests with phpunit/phpunit
        vendor/bin/phpunit --configuration=tests/phpunit.xml --testsuite=unit
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
new file mode 100644
index 0000000000..e9ed039c3a
--- /dev/null
+++ b/phpstan-baseline.neon
@@ -0,0 +1,295 @@
+parameters:
+       ignoreErrors:
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-debian-cli-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-debian-web-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: 
include/download-instructions/linux-docker-cli-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: 
include/download-instructions/linux-docker-web-community.php
+
+               -
+                       message: '#^Variable \$multiversion might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-fedora-cli-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-fedora-cli-community.php
+
+               -
+                       message: '#^Variable \$versionNoDot might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-fedora-cli-community.php
+
+               -
+                       message: '#^Variable \$multiversion might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-fedora-web-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-fedora-web-community.php
+
+               -
+                       message: '#^Variable \$versionNoDot might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-fedora-web-community.php
+
+               -
+                       message: '#^Variable \$multiversion might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-redhat-cli-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-redhat-cli-community.php
+
+               -
+                       message: '#^Variable \$versionNoDot might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-redhat-cli-community.php
+
+               -
+                       message: '#^Variable \$multiversion might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-redhat-web-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-redhat-web-community.php
+
+               -
+                       message: '#^Variable \$versionNoDot might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-redhat-web-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-ubuntu-cli-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/linux-ubuntu-web-community.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/download-instructions/osx-docker-cli.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/download-instructions/osx-docker-web.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/download-instructions/osx-homebrew-php.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/download-instructions/osx-homebrew.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/download-instructions/osx-macports.php
+
+               -
+                       message: '#^Variable \$versionNoDot might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/download-instructions/osx-macports.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/windows-chocolatey.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: 
include/download-instructions/windows-docker-cli.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: 
include/download-instructions/windows-docker-web.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/windows-downloads.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/download-instructions/windows-native.php
+
+               -
+                       message: '#^Variable \$versionNoDot might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: 
include/download-instructions/windows-scoop-versions.php
+
+               -
+                       message: '#^Variable \$version might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 4
+                       path: include/download-instructions/windows-winget.php
+
+               -
+                       message: '#^Variable \$MYSITE might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/get-download.inc
+
+               -
+                       message: '#^Variable \$CSS might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/header.inc
+
+               -
+                       message: '#^Variable \$MYSITE might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 9
+                       path: include/header.inc
+
+               -
+                       message: '#^Variable \$classes might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/header.inc
+
+               -
+                       message: '#^Variable \$config might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 3
+                       path: include/header.inc
+
+               -
+                       message: '#^Variable \$curr might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/header.inc
+
+               -
+                       message: '#^Variable \$lang might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/header.inc
+
+               -
+                       message: '#^Variable \$shorturl might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 3
+                       path: include/header.inc
+
+               -
+                       message: '#^Variable \$title might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/header.inc
+
+               -
+                       message: '#^Variable \$userPreferences might not be 
defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/langchooser.inc
+
+               -
+                       message: '#^Variable \$MYSITE might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/layout.inc
+
+               -
+                       message: '#^Variable \$TOC might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 6
+                       path: include/layout.inc
+
+               -
+                       message: '#^Variable \$link might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/layout.inc
+
+               -
+                       message: '#^Variable \$title might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: include/layout.inc
+
+               -
+                       message: '#^Variable \$MYSITE might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 2
+                       path: include/mozopensearch.inc
+
+               -
+                       message: '#^Variable \$MYSITE might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 5
+                       path: include/mozsearch.inc
+
+               -
+                       message: '#^Variable \$LANG might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: manual/index.php
+
+               -
+                       message: '#^Variable \$N might not be defined\.$#'
+                       identifier: variable.undefined
+                       count: 1
+                       path: manual/vote-note.php
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000000..e81fcf4243
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,13 @@
+includes:
+       - phpstan-baseline.neon
+
+parameters:
+       level: 3
+       paths:
+               - src
+               - tests
+               - manual
+               - include
+       fileExtensions:
+               - php
+               - inc

Reply via email to