phplint

package module
v0.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: MIT Imports: 16 Imported by: 0

README

go-phplint

phplint is a source-only PHP syntax and compile-time linter written in Go. It selects the PHP language profile explicitly, so one executable can check code for PHP 7.2 through 7.4 or any PHP 8 minor from 8.0 through 8.6 without installing those PHP runtimes. PHP 8.6 support is currently a preview profile.

The normal build is pure Go. The PHP lexer/parser sources are embedded in this repository, and the linter adds version gates and recoverable compile-time checks on top.

Build

Go 1.24 or newer is required.

go build -trimpath -o phplint ./cmd/phplint

To stamp a release version:

go build -trimpath -ldflags "-X main.buildVersion=v0.1.0" -o phplint ./cmd/phplint

CLI

Pass exactly one supported PHP minor and one or more files:

phplint --php-version 7.2 oldest-supported.php
phplint --php-version 7.4 legacy.php
phplint --php-version 8.4 src/App.php src/Domain.php
phplint --php-version 8.6 preview.php

A successful run is silent. A source failure is concise:

src/App.php:12:9: PHP 8.4: syntax error
    function broken( {
            ^
1 error(s) in 1 file(s)

The CLI accepts explicit regular files only. It deliberately has no directory walking, configuration discovery, standard-input mode, or implicit version default. PHP short tags are always recognized.

Exit codes:

  • 0: every file passed
  • 1: one or more source diagnostics
  • 2: invalid arguments, file I/O failure, or internal failure

Go API

package main

import (
	"fmt"

	phplint "github.com/shyim/go-phplint"
)

func main() {
	diagnostics, err := phplint.Lint(
		"example.php",
		[]byte("<?php function answer(): int { return 42; }"),
		phplint.Options{PHPVersion: phplint.PHP84},
	)
	if err != nil {
		panic(err)
	}
	for _, diagnostic := range diagnostics {
		fmt.Println(diagnostic)
	}
}

Lint returns source failures as diagnostics and reserves error for invalid options or an internal failure. Diagnostic offsets are zero-based byte offsets; line and column values are one-based. Each diagnostic also carries SourceLine, the text of the offending source line, so callers can render excerpts without re-reading the file.

Compatibility scope

The stable profiles are exactly 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, and 8.5. The 8.6 profile follows PHP 8.6.0 Alpha 2 and remains a preview until PHP 8.6 reaches general availability. Patch versions such as 8.4.2 are rejected because syntax profiles are maintained at minor-version granularity.

The goal is native php -l pass/fail behavior for syntax errors and single-file compile-time fatal errors, not identical diagnostic wording. Warnings and deprecations for which php -l exits successfully are not reported. Tests compare the linter with native PHP binaries across the full version matrix. PHP itself remains the final authority for edge cases that depend on engine semantics rather than parsing or single-file compilation.

Development

go test ./...
go vet . ./cmd/phplint

If a supported php executable is on PATH, go test also runs the native pass/fail oracle. Set PHPLINT_PHP_BINARY to select another executable:

PHPLINT_PHP_BINARY=/opt/php/8.4/bin/php go test -run TestNativePHPOracle

The CI oracle builds one Go test binary and runs it in official PHP CLI containers for every supported minor.

Origin and license

The embedded parser is adapted from laytan/php-parser v0.10.0, which is MIT-licensed. Its original license is retained in internal/LICENSE. This project is also released under the MIT License.

Documentation

Overview

Package phplint checks PHP source against an explicit PHP minor-language profile without invoking a PHP runtime.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Diagnostic

type Diagnostic struct {
	Filename string
	Message  string
	Phase    Phase
	Start    Position
	End      Position

	// SourceLine is the text of the line Start points into, without the
	// line terminator. It is empty when the position is unknown.
	SourceLine string
}

Diagnostic describes one source-level lint failure.

func Lint

func Lint(filename string, source []byte, options Options) (diagnostics []Diagnostic, err error)

Lint parses and compile-validates one PHP source file.

Syntax and compile failures are returned as diagnostics. The error return is reserved for invalid options or an internal linter failure.

func (Diagnostic) String

func (d Diagnostic) String() string

type Options

type Options struct {
	PHPVersion Version
}

Options configures a lint operation.

type Phase

type Phase uint8

Phase identifies the stage that produced a diagnostic.

const (
	PhaseLex Phase = iota + 1
	PhaseParse
	PhaseCompile
)

func (Phase) String

func (p Phase) String() string

type Position

type Position struct {
	Offset int
	Line   int
	Column int
}

Position identifies a byte position in source code.

type Version

type Version uint8

Version identifies a PHP minor-language profile.

const (
	PHP72 Version = iota + 1
	PHP73
	PHP74
	PHP80
	PHP81
	PHP82
	PHP83
	PHP84
	PHP85
	// PHP86 is the preview profile for the current PHP 8.6 prerelease.
	PHP86
)

func ParseVersion

func ParseVersion(value string) (Version, error)

ParseVersion parses one of the supported PHP minor versions.

Patch versions are deliberately rejected: PHP syntax profiles are maintained at minor-version granularity.

func SupportedVersions

func SupportedVersions() []Version

SupportedVersions returns all supported PHP profiles in ascending order.

func (Version) String

func (v Version) String() string

String returns the canonical major.minor form of the version.

Directories

Path Synopsis
cmd
phplint command
internal
ast
parser
A Parser for PHP written in Go
A Parser for PHP written in Go
php7
line internal/php7/scanner.rl:1
line internal/php7/scanner.rl:1
php8
line internal/php8/php8.y:2
line internal/php8/php8.y:2
visitor/nsresolver
Package visitor contains walker.visitor implementations
Package visitor contains walker.visitor implementations

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL