php-lsp-0.1.17 is not a library.
php-lsp
A PHP Language Server Protocol (LSP) implementation written in Rust.
Features
Language intelligence
- Diagnostics — syntax errors reported in real time; semantic warnings for undefined symbols, argument-count mismatches, undefined variables inside function/method bodies, return-type literal mismatches, and null-safety violations; workspace-wide diagnostics available for all indexed files (not just open ones); clients can refresh diagnostics on demand via
workspace/diagnostic/refresh - Hover — PHP signature for functions, methods, classes, interfaces, traits, and enums (including
implements); includes@param/@return/@throws/@deprecated/@see/@link/@template/@mixindocblock annotations when present; deprecated symbols show a> Deprecatedbanner; built-in PHP functions include a link to the official php.net documentation - PHPDoc type system — full docblock support:
@param,@return,@var,@throws,@deprecated,@see,@link;@template T/@template T of Basegenerics;@mixin ClassName;@psalm-type/@phpstan-typetype aliases; callable type signaturescallable(int, string): voidparsed correctly - Go-to-definition — jump to where a symbol is declared, including across open files and into Composer vendor packages via PSR-4 autoload maps
- Go-to-implementation — find all classes that implement an interface or extend a class
- Find references — locate every usage of a symbol across the workspace, including
useimport statements - Rename — rename any function, method, or class across all open files, including its
useimport statements
Editing aids
- Completion — keywords, ~200 built-in PHP functions, PHP superglobals (
$_SERVER,$_GET,$_POST, etc.), classes, methods, properties, constants, enums, and enum cases;->completions scoped to the inferred receiver type; built-in class stubs — full member completions for PHP's standard library (Exception hierarchy, DateTime, PDO, SPL collections, Iterator/Countable/ArrayAccess interfaces, Closure, Generator, and more); method-chain type inference —$result = $obj->method()uses the method's return type hint or@returndocblock to scope subsequent$result->completions;@paramdocblock inference —@param Foo $xin docblocks maps$xtoFooeven without a PHP type hint;instanceoftype narrowing —if ($x instanceof Foo)makesFoo's members available in$x->; constructor-chain —(new DateTime())->completes DateTime's members; bound-closure$this—Closure::bind/bindTo/callmap$thisto the bound object's class;array_map/array_filterpropagation — typed callback return type flows throughforeachto the loop variable;ClassName::/self::/static::show static members and constants;parent::shows parent-class static members;funcName(offers named-argument (param:) completions; cross-file symbols from all indexed documents;@mixin ClassNamedocblock causes mixin members to appear in->completions; enum built-ins —->name,->value(backed enums),::from(),::tryFrom(),::cases(); camel/underscore-case fuzzy matching — typingGRFmatchesgetRecentFiles,str_rmatchesstr_replace; snippet completions — functions with parameters use snippet format so the cursor lands inside parentheses; auto use-insertion — selecting a class from another namespace automatically inserts the requiredusestatement;completionItem/resolve— documentation is fetched lazily when a completion item is focused, keeping the menu instant - Signature help — parameter hints while typing a call, including overload narrowing; signatures for ~150 PHP built-in functions are bundled so hints work without any external source
- Inlay hints — parameter name labels at call sites; return-type labels after assigned function calls, closures, and arrow functions;
inlayHint/resolve— hovering over an inlay hint shows the full function/method signature as a tooltip - Code actions — "Add use import" quick-fix for undefined class names; PHPDoc stub generation; "Implement missing methods" generates stubs for all abstract/interface methods not yet present; "Generate constructor"/"Generate getters/setters" from declared properties; "Extract variable" from a selection;
codeAction/resolve— edits for PHPDoc, implement, constructor, and getters/setters are computed lazily when the action is selected, so the action menu appears instantly - Document links —
include/requirepaths are clickable links to the target file;documentLink/resolvesupported - Linked editing — placing the cursor on any variable or symbol shows all its occurrences as linked ranges; typing replaces all occurrences simultaneously (Alt+Shift+F2 in VS Code)
Navigation
- Document symbols — file outline of all functions, classes, enums (with cases and methods), methods, properties, and constants
- Workspace symbols — fuzzy-search symbols across the entire project;
workspaceSymbol/resolvefills in source ranges lazily for clients that request them - Call hierarchy — incoming callers and outgoing callees for any function or method, including cross-file
- Type hierarchy — navigate supertypes and subtypes for classes and interfaces; registered dynamically so all LSP clients discover it correctly
- Go-to-declaration — jump to the abstract or interface declaration of a method
- Go-to-type-definition — jump to the class of the type of a variable
- Selection range — smart expand/shrink selection (Alt+Shift+→) from expression → statement → function/class → file
- Document highlight — highlights all occurrences of the symbol under the cursor in the current file
- Folding ranges — collapse functions, classes, methods, loops, and control-flow blocks; consecutive
useimport groups fold as a single region; multi-line comments fold;// #region/// #endregionmarkers create named foldable regions - Code lens — inline reference counts on functions, classes, and methods; implementations count on interfaces and abstract classes; "overrides" label on methods that override a parent-class method; "Run test" lens for PHPUnit test methods — result shown via
window/showMessageRequestwith Run Again and Open File action buttons;codeLens/resolvesupported
Syntax & formatting
- Semantic tokens — richer syntax highlighting for functions, methods, classes, interfaces, traits, enums, parameters, properties, and PHP 8
#[Attribute]names withdeclaration/static/abstract/readonly/deprecatedmodifiers; symbols marked@deprecatedrender with strikethrough; supports full, range, and incremental delta requests; clients are notified to refresh viaworkspace/semanticTokens/refreshafter indexing completes - On-type formatting — auto-indents the new line on Enter; aligns
}to its matching{on keypress - Formatting — delegates to
php-cs-fixer(PSR-12) orphpcbf; supports full-file and range formatting
Workspace
- Multi-root workspace — all
workspaceFoldersare indexed at startup; folders added or removed at runtime viaworkspace/didChangeWorkspaceFolderstrigger incremental scans and PSR-4 map updates - Live configuration — the server registers
workspace/didChangeConfigurationand pulls settings viaworkspace/configurationwhenever the client changes them, sophpVersionandexcludePathstake effect without restarting - Workspace indexing — background scan indexes all
*.phpfiles on startup (includingvendor/), with a 50 000-file cap; LRU eviction keeps memory bounded at 10 000 indexed-only files; progress is reported via$/progressso editors display a spinner; after indexing completes, semantic tokens, code lenses, inlay hints, and diagnostics are automatically refreshed in all open editors - PSR-4 resolution — reads
composer.jsonandvendor/composer/installed.jsonto resolve fully-qualified class names to files on demand; merged across all workspace roots in multi-root setups - PHPStorm metadata — reads
.phpstorm.meta.phpfrom the workspace root and usesoverride(ClassName::method(0), map([...]))declarations to infer factory method return types - File watching — index stays up to date when files are created, changed, or deleted on disk; open editors are refreshed automatically
- File rename — moving or renaming a PHP file automatically updates all
useimport statements across the workspace (workspace/willRenameFiles) - File create/delete lifecycle —
workspace/willCreateFilesindexes new files immediately;workspace/willDeleteFilesremoves alluseimports referencing the deleted file;workspace/didDeleteFilesdrops the file from the index and clears its diagnostics textDocument/moniker— returns a PHP-scheme moniker with the PSR-4 FQN as the identifier, for cross-repository symbol linkingtextDocument/inlineValue— returns variable lookup entries in the requested range for debugger variable display; refreshed viaworkspace/inlineValue/refresh- Async parsing — edits are debounced (100 ms) and parsed off the tokio runtime; stale results from superseded edits are discarded
Configuration
Pass options via initializationOptions in your editor's LSP config:
The same options are also read live from the php-lsp settings section via workspace/configuration, so changes take effect without restarting.
Installation
Or build from source:
# binary at target/release/php-lsp
Editor Setup
PHPStorm (2023.2+)
- Open Settings → Languages & Frameworks → Language Servers
- Click + and configure:
- Name:
php-lsp - Language:
PHP - Command:
/path/to/php-lsp
- Name:
- Set file pattern to
*.php
Neovim (via nvim-lspconfig)
vim..
VS Code
Use the custom LSP client extension or any extension that supports arbitrary LSP servers. Set the server command to the php-lsp binary.
How It Works
The server communicates over stdin/stdout using the Language Server Protocol. It uses php-ast (backed by php-rs-parser and a bumpalo arena) to parse PHP source into an AST, which is cached per document and reused across all requests.
License
MIT