Phpstan laravel Truy cập vào một thuộc tính không xác định

Gần đây tôi có cơ hội mới để làm việc với một công ty với tư cách là nhà phát triển. Một trong những nhiệm vụ đầu tiên của tôi là triển khai Phân tích tĩnh PHP trên cơ sở mã 8 năm tuổi. Nhiệm vụ ban đầu có vẻ khó khăn nhưng tôi có 2 điều phù hợp với mình;

Trong blog này, tôi mong muốn cung cấp cho bạn một số mẹo khi triển khai phân tích tĩnh trên cơ sở mã cũ và giải thích cho bạn một số lỗi phân tích tĩnh mà tôi gặp phải và cách tôi giải quyết nó

Lần đầu tiên

Nếu đây là lần đầu tiên bạn triển khai phân tích tĩnh, tôi khuyên bạn nên đọc qua Tài liệu PHPStan trước khi cài đặt nó trên cơ sở mã của bạn. Tài liệu của họ khá toàn diện nên bạn sẽ không mất nhiều thời gian. Tôi cũng đề nghị, mặc dù không cần thiết, hãy xem bài nói chuyện của Nuno Maduro về Các loại trong PHP để hiểu rõ hơn về các loại PHP và Larastan

Bây giờ bạn nên biết rằng có các cấp quy tắc trong PHPStan - từ Cấp 0 đến Cấp 9. Các cấp độ xác định mức độ nghiêm ngặt của các quy tắc trong đó 0 là lỏng lẻo nhất và 9 là nghiêm ngặt nhất. Nếu bạn đang triển khai nó trên một cơ sở mã lớn, bạn phải luôn bắt đầu ở Cấp độ 0, nếu không bạn sẽ bị choáng ngợp với quá nhiều lỗi cần sửa

Cài đặt

Cài đặt Larastan sẽ nhanh chóng và dễ dàng, chỉ cần làm theo tài liệu trên tệp readme trong kho lưu trữ. Đến bây giờ, bạn sẽ có một tệp cấu hình trong thư mục gốc của thư mục dự án của mình. Của tôi được lưu trữ dưới dạng

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
1 và trông giống như thế này

includes:
    - ./vendor/nunomaduro/larastan/extension.neon

parameters:
    checkMissingIterableValueType: false
    noUnnecessaryCollectionCall: false
    reportUnmatchedIgnoredErrors: false

    # Paths to scan and analyse.
    paths:
        - app

    # The level: 9 is the highest level.
    level: 0

    # Circle CI configuration.
    parallel:
        jobSize: 20
        maximumNumberOfProcesses: 8

    # List of errors to be ignored.
    ignoreErrors:
        - '#PHPDoc tag @var#'
        - '#Unsafe usage of new static#'

    # List of paths that are excluded.
    excludePaths:
        - tests/

Khi bạn đã tạo tệp cấu hình, chỉ cần chạy

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
2, đợi vài giây [có thể lâu hơn tùy thuộc vào quy mô dự án của bạn] và nó sẽ hiển thị cho bạn các lỗi trên thiết bị đầu cuối của bạn

Hãy cùng điểm qua một số lỗi mà tôi đã gặp phải

Mẫu lỗi

Truy cập vào thuộc tính không xác định Ứng dụng\Foobar. $ baz

Lỗi này là tự giải thích. Trong lớp Foobar, bạn đang thực hiện cuộc gọi thuộc tính

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
3. Tuy nhiên, thuộc tính không thực sự được khai báo trong lớp. Mặc dù PHP cho phép điều này thông qua thuộc tính động, nhưng phân tích tĩnh đang bảo vệ bạn khỏi việc thực hiện các lệnh gọi thuộc tính không mong muốn đến một đối tượng

Sửa chữa. Chỉ cần khai báo thuộc tính trên lớp hoặc xóa hoàn toàn

Ứng dụng phương thức\Foobar. handle[] sẽ trả về int nhưng thiếu câu lệnh trả về

Một lỗi tự giải thích khác. Phương thức

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
4 trong lớp Foobar dự kiến ​​sẽ trả về một cái gì đó nhưng không có câu lệnh trả về. Điều này thường là do có một khối tài liệu phía trên phần khai báo phương thức

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}

Sửa chữa. Thêm câu lệnh trả về hoặc xóa khối tài liệu

Không tìm thấy mối quan hệ 'người dùng' trong mô hình Ứng dụng\Mô hình\Bài đăng

Lỗi này ban đầu hơi phức tạp vì nó vẫn xuất hiện mặc dù quan hệ

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
5 đã được khai báo trên lớp mô hình
/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
0

Sửa chữa. Thêm một kiểu trả về trên phương thức quan hệ

// In App\Models\Post class...

use Illuminate\Database\Eloquent\Relations\BelongsTo;

public function user[] : BelongsTo // Add this..
{
        return $this->belongsTo[User::class];
}

Không dùng nữa trong PHP 8. 0. Tham số bắt buộc $foo theo sau tham số tùy chọn $bar

Một lỗi tự giải thích khác và rõ ràng chỉ là sự cố trên PHP 8. 0 trở lên. Về cơ bản, điều đang xảy ra là có một phương thức trong lớp của bạn trông giống như thế này

public function something[$bar = null, int $foo]
{
        // ...
}

Như bạn có thể thấy,

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
1 là một tham số tùy chọn trong khi
/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
2 thì không. Các tham số bắt buộc phải ở bên trái các tham số tùy chọn

Sửa chữa. Tái cấu trúc phương thức và cách sử dụng của nó để đảm bảo các tham số bắt buộc ở bên trái

ứng dụng/Bảng điều khiển/Lệnh/Foo. php. Kết quả của phương thức Illuminate\Console\Command. error[] [void] được sử dụng

Điều này là do trong phương thức

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
3 của lớp
/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
4, chúng ta có cuộc gọi này

public function handle[]
{
        // Some codes...

        return $this->error['...']; 
}

Vấn đề là kết quả của cuộc gọi

/*
 * @return int
 */
public function handle[]
{
        // Some code without return statement...
}
5 là loại void và do đó không nên được sử dụng làm câu lệnh trả về

Sửa chữa. Cập nhật câu lệnh trả về với mã số nguyên chính xác

Và đó là gần như tất cả các mẫu lỗi mà tôi gặp phải khi triển khai phân tích tĩnh cấp 0. Trong lần chạy đầu tiên, có 380 lỗi được tìm thấy với các mẫu này trên các phần khác nhau của cơ sở mã

Hy vọng rằng bạn đang bắt đầu nhận ra những lợi ích và khả năng bảo vệ mà phân tích tĩnh có thể mang lại cho bạn ngay từ đầu

Chủ Đề