Yêu cầu Laravel :: all () Không nên được gọi là tĩnh


90

Trong Laravel, tôi đang cố gọi $input = Request::all();một store()phương thức trong bộ điều khiển của mình, nhưng tôi gặp lỗi sau:

Phương thức non-static Illuminate\Http\Request::all()không nên được gọi là static , giả sử $thistừ ngữ cảnh không tương thích

Bất kỳ sự giúp đỡ nào để tìm ra cách tốt nhất để sửa lỗi này? (Tôi đang theo dõi một chiếc Laracast)


@patricus, xin lỗi, tôi nên nói 5.
Moose

Có vẻ như bạn không sử dụng mặt tiền. Bạn có một use Illuminate\Http\Request;tuyên bố trong bộ điều khiển của bạn?
patricus

@patricus, tôi có ʻuse Illuminate \ Http \ Request; ở đầu bộ điều khiển của tôi.
Moose

1
@patricus Mặc dù vậy, tôi không có Illuminate\Http\Requestgói trong / nhà cung cấp. Tôi có phải tải xuống riêng không?
Moose

Các Illuminategói này được bao gồm như một phần của gói laravel / framework. Nếu bạn muốn nhìn vào bất kỳ của mã nguồn Laravel, bạn sẽ tìm thấy nó dưới/vendor/laravel/framework/src/Illuminate/...
patricus

Câu trả lời:


222

Thông báo lỗi là do cuộc gọi không qua Requestmặt tiền.

Thay đổi

use Illuminate\Http\Request;

Đến

use Request;

và nó sẽ bắt đầu hoạt động.

Trong tệp config / app.php, bạn có thể tìm thấy danh sách các bí danh của lớp. Ở đó, bạn sẽ thấy rằng lớp cơ sở Requestđã được đặt bí danh cho Illuminate\Support\Facades\Requestlớp. Bởi vì điều này, sử dụng Requestmặt tiền trong một file namespaced, bạn cần phải xác định để sử dụng các lớp cơ sở: use Request;.

Biên tập

Vì câu hỏi này dường như nhận được một số lưu lượng truy cập, tôi muốn cập nhật câu trả lời một chút kể từ khi Laravel 5 chính thức được phát hành.

Mặc dù điều trên vẫn đúng về mặt kỹ thuật và sẽ hoạt động, nhưng use Illuminate\Http\Request;câu lệnh này được đưa vào mẫu Controller mới để giúp thúc đẩy các nhà phát triển theo hướng sử dụng phụ thuộc chèn ép thay vì dựa vào Mặt tiền.

Khi đưa đối tượng Request vào phương thức khởi tạo (hoặc các phương thức, như có sẵn trong Laravel 5), nó là Illuminate\Http\Requestđối tượng nên được đưa vào chứ không phải là Requestmặt tiền.

Vì vậy, thay vì thay đổi mẫu Bộ điều khiển để hoạt động với Mặt tiền Yêu cầu, tốt hơn nên làm việc với mẫu Bộ điều khiển đã cho và chuyển sang sử dụng chèn phụ thuộc (thông qua hàm tạo hoặc các phương thức).

Ví dụ qua phương pháp

<?php namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class UserController extends Controller {

    /**
     * Store a newly created resource in storage.
     *
     * @param  Illuminate\Http\Request  $request
     * @return Response
     */
    public function store(Request $request) {
        $name = $request->input('name');
    }
}

Ví dụ thông qua hàm tạo

<?php namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class UserController extends Controller {

    protected $request;

    public function __construct(Request $request) {
        $this->request = $request;
    }

    /**
     * Store a newly created resource in storage.
     *
     * @return Response
     */
    public function store() {
        $name = $this->request->input('name');
    }
}

3
Câu trả lời là đúng, tuy nhiên tôi sẽ sử dụng Illuminate \ Support \ Facades \ Request; bởi vì cá nhân tôi nghĩ rằng thói quen đặt bí danh mọi thứ cho không gian tên gốc của Laravel là đi ngược lại quan điểm của việc có không gian tên ngay từ đầu. Nó cũng làm cho tài liệu API khó tạo hơn vì apigen / phpdoc sẽ không thể tìm thấy lớp "Yêu cầu".
delatbabel

4
Trên thực tế, bạn không cần phải thay đổi Boilerplate của bộ điều khiển: Nếu bạn muốn sử dụng Request mà không cần đưa nó vào phương thức, chỉ cần sử dụng $ input = \ Request :: all () (Lưu ý \). Nếu bạn muốn sử dụng tiêm hơn sử dụng myFunction công cộng (Request $ request () {$ input = $ request-> tất cả ()} Hoặc bơm nó trong các nhà xây dựng và gán nó vào một biến lớp
shock_gone_wild

2
Tại sao tôi không thể sử dụng Request::all();trong khi tôi sử dụng use Illuminate\Http\Request; ?
SA__

@SA__ Request :: all () là một cách mặt tiền. vì vậy bạn phải use Illuminate\Support\Facades\Request; thay vìuse Illuminate\Http\Request;
Thabung

@redA có cách nào để chuyển đổi Request :: all () để sử dụng cách trực tiếp (và không thông qua lớp mặt tiền) không?
cid

6

Đưa đối tượng yêu cầu vào bộ điều khiển bằng cách sử dụng tiêm ma thuật của Laravel và sau đó truy cập hàm không tĩnh. Laravel sẽ tự động đưa các phụ thuộc cụ thể vào các lớp tự động tải

class MyController() 
{

   protected $request;

   public function __construct(\Illuminate\Http\Request $request)
   {
       $this->request = $request;
   }

   public function myFunc()
   {
       $input = $this->request->all();
   }

}

5

sử dụng request()trợ giúp thay thế. Bạn không phải lo lắng về các usecâu lệnh và do đó loại vấn đề này sẽ không xảy ra nữa.

$input = request()->all();

đơn giản


4

Mặt tiền là một lớp Yêu cầu khác, hãy truy cập nó bằng đường dẫn đầy đủ:

$input = \Request::all();

Từ laravel 5, bạn cũng có thể truy cập nó thông qua request()chức năng:

$input = request()->all();

3

Tôi nghĩ sẽ hữu ích cho những khách truy cập trong tương lai nếu cung cấp một chút giải thích về những gì đang xảy ra ở đây.

các Illuminate\Http\Requestlớp học

Lớp của Laravel Illuminate\Http\Requestcó một phương thức được đặt tên all(trên thực tế, allphương thức được định nghĩa trong một đặc điểm mà Requestlớp đó sử dụng, được gọi Illuminate\Http\Concerns\InteractsWithInput). Chữ ký của allphương thức tại thời điểm viết bài trông như sau:

public function all($keys = null)

Phương thức này không được định nghĩa là staticvà vì vậy khi bạn cố gắng gọi phương thức trong ngữ cảnh tĩnh, tức là Illuminate\Http\Request::all()bạn sẽ gặp lỗi hiển thị trong câu hỏi của OP. Các allphương pháp là một phương pháp dụ và những giao dịch với các thông tin được trình bày trong một thể hiện của Requestlớp, cho nên gọi nó theo cách này làm cho không có ý nghĩa.

Mặt tiền

Một mặt tiền trong Laravel cung cấp cho các nhà phát triển một cách thuận tiện để truy cập các đối tượng trong vùng chứa IoC và gọi các phương thức trên các đối tượng đó. Một nhà phát triển có thể gọi một phương thức "statically" trên một mặt tiền giống như Request::all(), nhưng lệnh gọi phương thức thực tế trên đối tượng thực không phảiIlluminate\Http\Request là static.

Một mặt tiền hoạt động giống như một proxy - nó tham chiếu đến một đối tượng trong vùng chứa IoC và chuyển lời gọi phương thức tĩnh lên đối tượng đó (không tĩnh). Ví dụ, hãy lấy Illuminate\Support\Facades\Requestmặt tiền, nó trông như thế này:

class Request extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'request';
    }
}

Dưới mui xe, Illuminate\Support\Facades\Facadelớp cơ sở sử dụng một số phép thuật PHP, cụ thể là __callStaticphương thức để:

  • Nghe lệnh gọi phương thức tĩnh, trong trường hợp này là allkhông có tham số
  • Lấy đối tượng cơ bản từ vùng chứa IoC bằng cách sử dụng khóa được trả về getFacadeAccessor, trong trường hợp này là một Illuminate\Http\Requestđối tượng
  • Tự động gọi phương thức mà nó đã nhận tĩnh trên đối tượng mà nó đã truy xuất, trong trường hợp allnày được gọi là không tĩnh trên một thể hiện của Illuminate\Http\Request.

Đây là lý do tại sao, như @patricus đã chỉ ra trong câu trả lời của anh ấy ở trên, bằng cách thay đổi usecâu lệnh / import để tham chiếu đến mặt tiền, lỗi không còn ở đó nữa, vì theo như PHP có liên quan, allđã được gọi chính xác trên một phiên bản của Illuminate\Http\Request.

Răng cưa

Aliasing là một tính năng khác mà Laravel cung cấp để tạo sự thuận tiện. Nó hoạt động bằng cách tạo hiệu quả các lớp bí danh trỏ đến các mặt tiền trong không gian tên gốc. Nếu bạn xem config/app.phptệp của mình , dưới aliasesphím, bạn sẽ tìm thấy một danh sách dài các ánh xạ của các chuỗi tới các lớp mặt tiền. Ví dụ:

'aliases' => [

    'App' => Illuminate\Support\Facades\App::class,
    'Artisan' => Illuminate\Support\Facades\Artisan::class,
    'Auth' => Illuminate\Support\Facades\Auth::class,
    // ...
    'Request' => Illuminate\Support\Facades\Request::class,

Laravel tạo các lớp bí danh này cho bạn, dựa trên cấu hình của bạn và điều này cho phép bạn sử dụng các lớp có sẵn trong không gian tên gốc (được gọi bằng các khóa chuỗi của aliasescấu hình) như thể bạn đang sử dụng chính mặt tiền:

use Request:

class YourController extends Controller
{
    public function yourMethod()
    {
        $input = Request::all();

        // ...
    }
}

Một lưu ý về tiêm phụ thuộc

Trong khi các mặt tiền và răng cưa vẫn được cung cấp trong Laravel, có thể và thường được khuyến khích đi xuống con đường tiêm phụ thuộc. Ví dụ: sử dụng hàm tạo chèn để đạt được kết quả tương tự:

use Illuminate\Http\Request;

class YourController extends Controller
{
    protected $request;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function yourMethod()
    {
        $input = $this->request->all();

        // ...
    }
}

Có một số lợi ích đối với cách tiếp cận này nhưng theo ý kiến ​​cá nhân của tôi, điểm chuyên nghiệp nhất cho việc tiêm phụ thuộc là nó làm cho cách kiểm tra mã của bạn dễ dàng hơn. Bằng cách khai báo các phụ thuộc của các lớp của bạn dưới dạng đối số phương thức hoặc hàm tạo, sẽ rất dễ dàng để mô phỏng những phụ thuộc đó và kiểm tra đơn vị lớp của bạn một cách riêng biệt.


1
use Illuminate\Http\Request;
public function store(Request $request){
   dd($request->all());
}

giống trong ngữ cảnh nói

use Request;
public function store(){
   dd(Request::all());
}

1

nó cũng xảy ra khi bạn nhập thư viện sau vào tệp api.php. điều này xảy ra bởi một số gợi ý của IDE để nhập nó vì không tìm thấy Lớp lộ trình .

chỉ cần loại bỏ nó và mọi thứ sẽ hoạt động tốt.

use Illuminate\Routing\Route;

cập nhật:

Có vẻ như nếu bạn thêm thư viện này, nó sẽ không dẫn đến lỗi

use Illuminate\Support\Facades\Route;

điều này đã làm việc cho tôi, nhưng tôi vẫn không hiểu tại sao IDE không áp dụng cho tôi, bởi vì cách tôi tạo dự án và tôi sử dụng vscode.
Aldo Okware

0

Tôi đã đối mặt với vấn đề này ngay cả với use Illuminate\Http\Request;dòng ở đầu bộ điều khiển của tôi. Tiếp tục kéo tóc của tôi cho đến khi tôi nhận ra rằng tôi đang làm $request::ip()thay vì $request->ip(). Có thể xảy ra với bạn nếu bạn không ngủ cả đêm và đang nhìn vào mã lúc 6 giờ sáng với đôi mắt khép hờ.

Hy vọng điều này sẽ giúp ai đó trên con đường.


0

tôi làm cho nó hoạt động với một định nghĩa phạm vi

trang chức năng công khai (\ Illuminate \ Http \ Request $ request) {//


2
Vui lòng không chỉ hiển thị mã nào đang hoạt động mà còn giải thích lý do tại sao bạn làm điều này.
creyD
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.