glhd/laralint
Composer 安装命令:
composer require glhd/laralint
包简介
Laravel linting framework
README 文档
README
This is a very early work-in-progress linter for Laravel projects. It’s different from other PHP linters in that it focuses on building custom rules for your specific needs.
The goal is to make writing custom linters easy and fluent, just like writing Laravel-backed code. While the project uses an AST/tokenizers/etc under-the-hood, most common use-cases shouldn’t need a deep understanding of how that works.
Getting Started
Install this into your project with:
composer require glhd/laralint --dev
Once installed, you can lint your project using LaraLint’s default rules by running:
php artisan laralint:lint
If you only want to lint uncommitted Git changes, you can pass the --diff
flat to the command
php artisan laralint:lint --diff
Or, ff you only want to lint specific files, pass their filenames as the first argument:
php artisan laralint:lint app/Http/Controllers/HomeController.php
Configuration and Presets
LaraLint comes with a very opinionated preset installed. If this works for you, great, but you’ll probably want to customize things to match your team’s code standards.
To start, publish the LaraLint config file:
php artisan vendor:publish --tag=laralint-config
This will install a laralint.php file into your project’s config/
directory with the default LaraLint config.
In some cases, you may be able to simply tweak the config to meet your needs. But it’s more likely that you’ll want to create your own preset.
Take a look at the Preset contract, or the default LaraLint Preset to get started. From there you can create a custom preset for your project that uses linters that make sense for your team. Mix and match the pre-built linters with your own custom linters to your heart’s content!
Custom Linters
If you’re interested in LaraLint, you’re probably interested in custom linters. Each team’s needs are different, and LaraLint tries to make it as easy as possible to quickly add logic that enforces your agreed upon conventions.
That said, LaraLint does rely on concepts like Abstract Syntax Trees, which can be intimidating at first. But with a few key concepts under your belt, you should be traversing that tree like a champ in no time!
Real Quick: How LaraLint Works
In as few words as possible:
LaraLint uses Microsoft’s Tolerant PHP Parser to parse your PHP code into an Abstract Syntax Tree, or AST. We use Microsoft’s parser because it’s fast and works well with partially-written code (like code you’re typing in your IDE). It’s also the basis for VS Code’s IntelliSense, so it’s got a good track record.
Think of this tree as a structured view of your code. Given the following PHP code:
class Foo { public function bar() { return 'baz'; } }
The AST will look something like this (simplified for clarity’s sake):
- ClassDeclaration (
class Foo)- MethodDeclaration (
public function bar())- CompoundStatementNode (
return 'baz';)- ReturnStatement (
return)- StringLiteral (
'baz')
- StringLiteral (
- ReturnStatement (
- CompoundStatementNode (
- MethodDeclaration (
LaraLint walks that tree from top to bottom, and passes each node to each applicable Linter for inspection. Linters are simply objects that receive AST nodes and optionally return linting results once the tree is fully walked.
This means you can write incredibly complex and custom linters, but hopefully you won't have to.
How to Write a LaraLint Linter
The core of most LaraLint Linters is a Matcher object. These objects
are designed to easily match a general AST “shape” and flag part of the
code if the entire “shape” is found. for example, if you wanted to flag
any method named bar that returns the string 'baz', you could use
the following matcher:
(new TreeMatcher()) // (1) Find a method declaration where the method name is "bar" ->withChild(function(MethodDeclaration $node) { return 'bar' === $node->getName(); }) // (2) Find any return statement ->withChild(ReturnStatement::class) // (3) Find a string literal that matches the string "baz" ->withChild(function(StringLiteral $node) { return 'baz' === $node->getStringContentsText(); }) ->onMatch(function(Collection $all_matched_nodes) { // Create a linting result using the matched nodes. // LaraLint will automatically map the AST nodes to line // numbers when printing the results. });
As soon as LaraLint finds a node that matches the first rule, it will
begin looking for a child that matches the second rule. If it finds a
child that matches the second rule, it will move on to the third rule.
When it's matched all the rules, the matcher will trigger the onMatch
callback, where you can perform any additional logic you choose.
LaraLint comes with several “strategies” that apply to common use-cases. These strategies abstract away even more of the logic, and are the best place to start. Look at some of the existing linters to understand how best to use each strategy.
But Wait… How Do I Write a LaraLint Linter?
OK, you’re probably looking at ReturnStatement and StringLiteral and
thinking, “I don’t speak Abstract Syntax Tree.”
Neither does anyone else.
That's where the laralint:dump command comes into play. Say you’re
trying to write the silly bar/baz linter from the example above. Simply
create a PHP file that should fail, and dump its tree:
php artisan laralint:dump barbaz_source.php
Which will output something like:
┏━━ ClassDeclaration ━━━━━━┓
┃ ┃
┃ class Foo ┃
┃ { ┃
┃ public function bar() ┃
┃ { ┃
┃ return 'baz'; ┃
┃ } ┃
┃ } ┃
┃ ┃
┃ ┏━━ ClassMembersNode ━━━━━━┓
┃ ┃ ┃
┃ ┃ { ┃
┃ ┃ public function bar() ┃
┃ ┃ { ┃
┃ ┃ return 'baz'; ┃
┃ ┃ } ┃
┃ ┃ } ┃
┃ ┃ ┃
┃ ┃ ┏━━ MethodDeclaration ━━━┓
┃ ┃ ┃ ┃
┃ ┃ ┃ public function bar() ┃
┃ ┃ ┃ { ┃
┃ ┃ ┃ return 'baz'; ┃
┃ ┃ ┃ } ┃
┃ ┃ ┃ ┃
┃ ┃ ┃ ┏━━ CompoundStatementNode ━━┓
┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ { ┃
┃ ┃ ┃ ┃ return 'baz'; ┃
┃ ┃ ┃ ┃ } ┃
┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┏━━ ReturnStatement ━━┓
┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ return 'baz'; ┃
┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┏━━ StringLiteral ━━┓
┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┃ 'baz' ┃
┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┗━━━━━━━━━━━━━━━━━━━┛
┃ ┃ ┃ ┃ ┗━━━━━━━━━━━━━━━━━━━━━┛
┃ ┃ ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃ ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Between the output of the dump command, and the example of existing Linters,
you’d be surprised how easy it is to start writing your own rules.
IDE Integration
The best place for linting results is right in your IDE. Rather than publishing
our own IDE plugins, LaraLint can simply pretend to be PHP_CodeSniffer:
php artisan laralint:lint --printer=phpcs
This will give you XML output that is compatible with any plugin that can
parse PHP_CodeSniffer’s XML output (such as PhpStorm).
Running php artisan laralint:install will install a nice helper file that
makes this a little easier. Just configure your IDE to point to that
file, and your LaraLint lints should get flagged in your IDE.
glhd/laralint 适用场景与选型建议
glhd/laralint 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 30.12k 次下载、GitHub Stars 达 8, 最近一次更新时间为 2020 年 01 月 05 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「lint」 「linting」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 glhd/laralint 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 glhd/laralint 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 glhd/laralint 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Generate reports from lint results
A short bash script to recursively lint PHP files with a nice output
PHP linting rules set used by Opay developers
This is the ZooRoyal coding standard.
Syntax-aware proofreading for your Laravel application.
Linting configurations for PHP projects
统计信息
- 总下载量: 30.12k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 8
- 点击次数: 17
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2020-01-05