Permintaan Laravel :: all () Tidak Harus Dipanggil Secara Statis

91

Dalam LARAVEL, Saya mencoba untuk memanggil $input = Request::all();pada store()metode di controller saya, tapi aku mendapatkan error berikut:

Metode non-statis Illuminate\Http\Request::all()tidak boleh dipanggil secara statis, dengan asumsi $thisdari konteks yang tidak kompatibel

Adakah bantuan untuk mencari cara terbaik untuk memperbaiki ini? (Saya mengikuti Laracast)

Moose
sumber
@patricus, maaf, saya seharusnya mengatakan 5.
Moose
Sepertinya Anda tidak menggunakan fasad. Apakah Anda memiliki use Illuminate\Http\Request;pernyataan di pengontrol Anda?
patricus
@patricus, saya memiliki `use Illuminate \ Http \ Request; pernyataan di bagian atas pengontrol saya.
Moose
1
@patricus Saya tidak memiliki Illuminate\Http\Requestpaket di / vendor. Apakah saya harus mendownloadnya secara terpisah?
Moose
The Illuminatepaket disertakan sebagai bagian dari paket LARAVEL / framework. Jika Anda ingin melihat salah satu kode sumber Laravel, Anda akan menemukannya di bawah/vendor/laravel/framework/src/Illuminate/...
patricus

Jawaban:

224

Pesan kesalahan ini karena panggilan tidak melalui Requestfasad.

Perubahan

use Illuminate\Http\Request;

Untuk

use Request;

dan itu harus mulai bekerja.

Di file config / app.php, Anda dapat menemukan daftar alias kelas. Di sana, Anda akan melihat bahwa kelas dasar Requesttelah dialiasi dengan Illuminate\Support\Facades\Requestkelas tersebut. Karena itu, untuk menggunakan Requestfasad dalam file namespace, Anda perlu menentukan untuk menggunakan kelas dasar: use Request;.

Edit

Karena pertanyaan ini sepertinya mendapatkan lalu lintas, saya ingin memperbarui jawaban sedikit sejak Laravel 5 secara resmi dirilis.

Meskipun hal di atas masih benar secara teknis dan akan berfungsi, use Illuminate\Http\Request;pernyataan tersebut disertakan dalam template Pengontrol baru untuk membantu mendorong pengembang ke arah penggunaan injeksi ketergantungan versus mengandalkan Facade.

Saat memasukkan objek Request ke dalam konstruktor (atau metode, seperti yang tersedia di Laravel 5), itu adalah Illuminate\Http\Requestobjek yang harus diinjeksikan, dan bukan Requestfasadnya.

Jadi, daripada mengubah template Controller untuk bekerja dengan Request fasad, lebih baik disarankan untuk bekerja dengan template Controller yang diberikan dan beralih menggunakan injeksi ketergantungan (melalui konstruktor atau metode).

Contoh melalui metode

<?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');
    }
}

Contoh melalui konstruktor

<?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');
    }
}
patricus
sumber
3
Jawaban benar, namun di luar preferensi saya akan menggunakan Illuminate \ Support \ Facades \ Request; karena secara pribadi menurut saya kebiasaan Laravel untuk mengaliri semuanya ke root namespace bertentangan dengan tujuan memiliki namespace di tempat pertama. Ini juga membuat dokumentasi API lebih sulit untuk dibuat karena apigen / phpdoc tidak akan dapat menemukan kelas "Request".
delatbabel
4
Nyatanya, Anda tidak perlu mengubah Boilerplate dari artisan make: controller. Jika Anda ingin menggunakan Request tanpa memasukkannya ke metode, cukup gunakan $ input = \ Request :: all () (Perhatikan \). Jika Anda ingin menggunakan injeksi daripada menggunakan public myFunction (Request $ request () {$ input = $ request-> all ()} Atau menyuntikkannya ke konstruktor dan menetapkannya ke variabel kelas
shock_gone_wild
2
Mengapa saya tidak bisa menggunakan Request::all();saat saya menggunakan use Illuminate\Http\Request; ?
SA__
@SA__ Request :: all () adalah cara fasad. jadi Anda harus use Illuminate\Support\Facades\Request; bukannyause Illuminate\Http\Request;
Thabung
@redA apakah ada cara untuk mengonversi Request :: all () menggunakan cara langsung (dan tidak melalui kelas fasad)?
cid
6

Masukkan objek permintaan ke dalam pengontrol menggunakan injeksi ajaib Laravel dan kemudian akses fungsinya secara non-statis. Laravel secara otomatis akan memasukkan dependensi konkret ke dalam kelas yang dimuat otomatis

class MyController() 
{

   protected $request;

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

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

}
Jonathan Crowe
sumber
5

gunakan request()helper sebagai gantinya. Anda tidak perlu khawatir tentang usepernyataan dan dengan demikian masalah semacam ini tidak akan terjadi lagi.

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

sederhana

lucidlogic.dll
sumber
4

Fasad adalah kelas Permintaan lain, akses dengan jalur lengkap:

$input = \Request::all();

Dari laravel 5 Anda juga dapat mengaksesnya melalui request()fungsi:

$input = request()->all();
Luca C.
sumber
3

Saya pikir akan bermanfaat bagi pengunjung selanjutnya untuk memberikan sedikit penjelasan tentang apa yang terjadi di sini.

The Illuminate\Http\Requestkelas

Illuminate\Http\RequestKelas Laravel memiliki metode bernama all(sebenarnya allmetode tersebut didefinisikan dalam sifat yang Requestdigunakan kelas, disebut Illuminate\Http\Concerns\InteractsWithInput). Tanda tangan allmetode pada saat penulisan terlihat seperti ini:

public function all($keys = null)

Metode ini tidak didefinisikan sebagai staticdan jadi ketika Anda mencoba memanggil metode dalam konteks statis, yaitu Illuminate\Http\Request::all()Anda akan mendapatkan kesalahan yang ditampilkan dalam pertanyaan OP. The allmetode adalah metode contoh dan penawaran dengan informasi yang hadir dalam sebuah instance dari Requestkelas, sehingga menyebutnya dengan cara ini tidak masuk akal.

Fasad

Fasad di Laravel memberi pengembang cara yang nyaman untuk mengakses objek dalam wadah IoC, dan memanggil metode pada objek tersebut. Pengembang dapat memanggil metode "secara statis" pada fasad seperti itu Request::all(), tetapi pemanggilan metode aktual pada objek nyata tidak statis.Illuminate\Http\Request

Fasad berfungsi seperti proxy - ia merujuk ke objek dalam wadah IoC dan meneruskan panggilan metode statis ke objek itu (non-statis). Misalnya, ambil Illuminate\Support\Facades\Requestfasadnya, seperti ini:

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

Di bawah tenda, Illuminate\Support\Facades\Facadekelas dasar menggunakan beberapa sihir PHP, yaitu __callStaticmetode untuk:

  • Dengarkan panggilan metode statis, dalam hal ini alltanpa parameter
  • Ambil objek yang mendasari dari kontainer IoC menggunakan kunci yang dikembalikan oleh getFacadeAccessor, dalam hal ini Illuminate\Http\Requestobjek
  • Panggil secara dinamis metode yang diterimanya secara statis pada objek yang diambilnya, dalam hal allini disebut non-statis pada instance Illuminate\Http\Request.

Inilah sebabnya, seperti yang ditunjukkan @patricus dalam jawabannya di atas, dengan mengubah pernyataan use/ import untuk merujuk ke fasad, kesalahan tidak lagi ada, karena sejauh menyangkut PHP, alltelah dipanggil dengan benar pada instance Illuminate\Http\Request.

Aliasing

Aliasing adalah fitur lain yang disediakan Laravel untuk kenyamanan. Ia bekerja dengan secara efektif membuat kelas alias yang mengarah ke fasad di namespace root. Jika Anda melihat config/app.phpfile Anda , di bawah aliaseskunci, Anda akan menemukan daftar panjang pemetaan string untuk kelas fasad. Sebagai contoh:

'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 membuat kelas alias ini untuk Anda, berdasarkan konfigurasi Anda dan ini memungkinkan Anda untuk menggunakan kelas yang tersedia di namespace root (seperti yang dirujuk oleh kunci string dari aliaseskonfigurasi) seolah-olah Anda menggunakan fasad itu sendiri:

use Request:

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

        // ...
    }
}

Catatan tentang injeksi ketergantungan

Meskipun fasad dan aliasing masih tersedia di Laravel, hal ini memungkinkan dan biasanya didorong untuk mengikuti rute injeksi ketergantungan. Misalnya, menggunakan injeksi konstruktor untuk mencapai hasil yang sama:

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();

        // ...
    }
}

Ada sejumlah manfaat dari pendekatan ini, tetapi menurut pendapat pribadi saya pro terbesar untuk injeksi ketergantungan adalah membuat kode Anda lebih mudah untuk diuji. Dengan mendeklarasikan dependensi kelas Anda sebagai konstruktor atau argumen metode, menjadi sangat mudah untuk memalsukan dependensi tersebut dan menguji unit kelas Anda secara terpisah.

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

sama dalam konteks mengatakan

use Request;
public function store(){
   dd(Request::all());
}
Ravi G
sumber
1

juga terjadi ketika Anda mengimpor pustaka berikut ke file api.php. ini terjadi karena beberapa saran IDE untuk mengimpornya karena tidak menemukan Kelas Rute .

hapus saja dan semuanya akan berfungsi dengan baik.

use Illuminate\Routing\Route;

memperbarui:

tampaknya jika Anda menambahkan perpustakaan ini, itu tidak akan menyebabkan kesalahan

use Illuminate\Support\Facades\Route;
ghazyy
sumber
ini berhasil untuk saya, tetapi saya masih tidak mengerti mengapa alasan IDE tidak berlaku untuk saya, karena cara saya membuat proyek dan saya menggunakan vscode.
Aldo Okware
0

Saya menghadapi masalah ini bahkan dengan use Illuminate\Http\Request;garis di bagian atas pengontrol saya. Terus menarik rambut saya sampai saya menyadari bahwa yang saya lakukan, $request::ip()bukan $request->ip(). Bisa terjadi pada Anda jika Anda tidak tidur sepanjang malam dan melihat kode jam 6 pagi dengan mata setengah terbuka.

Semoga ini membantu seseorang di jalan.

dotNET
sumber
0

saya membuatnya bekerja dengan definisi ruang lingkup

pagar fungsi publik (\ Illuminate \ Http \ Request $ request) {//

Julian Lanfranco
sumber
2
Harap tidak hanya menunjukkan kode apa yang berfungsi tetapi juga menjelaskan mengapa Anda melakukan ini.
CreyD