Rumah >pembangunan bahagian belakang >tutorial php >Menyelam mendalam ke sesi di laravel
Artikel ini dengan cepat akan menjelaskan sesi apa, bagaimana mereka bekerja di Laravel, dan bagaimana anda menggunakannya dalam aplikasi Laravel.
Kami kemudian akan melangkah lebih jauh dan menyelam bagaimana untuk berinteraksi dengan sesi menggunakan "kelas sesi" untuk mengelakkan perangkap biasa yang sering saya hadapi ketika berurusan dengan aplikasi Laravel.
Akhirnya, kita akan belajar bagaimana untuk menguji data sesi di Laravel.
Apa itu perbualan?
Singkatnya, sesi adalah cara yang selamat untuk meneruskan data antara pelbagai permintaan.
data sesi boleh digunakan untuk menyimpan kandungan berikut:
Status Pengesahan Pengguna.
cookie
mari kita memecahkan apa yang setiap kunci mungkin mewakili.
<code>[ '_token' => 'bKmSfoegonZLeIe8B6TWvSm1dKwftKsvcT40xaaW' '_previous' => [ 'url' => 'https://my-app.com/users' ] '_flash' => [ 'old' => [ 'success', ], 'new' => [] ] 'success' => 'User created successfully.' 'current_team_id' => 123 ]</code>Kekunci berikut ditambah oleh rangka kerja Laravel itu sendiri:
Nilai
digunakan untuk mencegah serangan CSRF.
_token
digunakan untuk menyimpan URL yang diminta sebelum ini. _previous.url
Nilai digunakan untuk menyimpan kunci data sesi flash dalam permintaan sebelumnya. Dalam kes ini, ini bermakna bahawa nilai _flash.old
success
Nilai digunakan untuk menyimpan kunci data sesi flash dalam permintaan semasa. _flash.new
kekunci berikut ditambah oleh saya: Nilai digunakan untuk menyimpan mesej kejayaan yang mungkin dipaparkan kepada pengguna.
success
digunakan untuk menyimpan ID pasukan semasa yang pengguna lihat. current_team_id
Secara lalai, Laravel menyokong pemandu sesi berikut: cookie
- Data sesi disimpan dalam kuki yang selamat dan disulitkan. database
- Sesi disimpan dalam pangkalan data anda (mis. MySQL, PostgreSQL, SQLite). memcached
/ redis
- Data sesi disimpan dalam penyimpanan cache cepat ini. dynamodb
- Data sesi disimpan dalam AWS DynamoDB. file
- Data sesi disimpan dalam storage/framework/sessions
. array
- Data sesi disimpan dalam tatasusunan PHP dalam ingatan dan tidak berterusan. Beberapa pemandu ini mempunyai keperluan persediaan. Jadi, sebelum menggunakannya, pastikan anda menyemak dokumentasi Laravel untuk mengetahui cara menetapkannya.
Laravel menggunakan sesi yang sangat mudah. Dokumentasi menerangkan cara berinteraksi dengan sesi dengan baik. Tetapi, mari kita lihat dengan cepat asas -asas.
Sebagai contoh, kami akan mengandaikan bahawa kami sedang membina wizard langkah demi langkah yang merangkumi beberapa halaman. Kami akan menyimpan langkah semasa dan data yang dimasukkan dalam setiap langkah ke dalam sesi. Dengan cara ini, apabila pengguna melengkapkan semua langkah, kami dapat membaca semua data yang dikemukakan pada akhir Wizard.
Untuk membuat contoh mudah, kami juga akan menggunakan fungsi penolong session()
. Tetapi kemudian kita akan membincangkan menggunakan fasad atau kelas permintaan untuk mengakses data sesi. Session
seperti berikut: get
<code>[ '_token' => 'bKmSfoegonZLeIe8B6TWvSm1dKwftKsvcT40xaaW' '_previous' => [ 'url' => 'https://my-app.com/users' ] '_flash' => [ 'old' => [ 'success', ], 'new' => [] ] 'success' => 'User created successfully.' 'current_team_id' => 123 ]</code>Menjalankan kod di atas akan mengembalikan nilai yang disimpan dalam sesi sebagai kekunci
. Jika kunci tidak mempunyai nilai yang disimpan dalam sesi, ia akan kembali wizard:current_step
. null
jika kunci tidak wujud:
<code>$currentStep = session()->get(key: 'wizard:current_step');</code>Menjalankan kod di atas akan mengembalikan nilai yang disimpan dalam sesi sebagai kekunci
. Jika kunci tidak mempunyai nilai yang disimpan dalam sesi, ia akan kembali wizard:current_step
. 1
untuk ini: pull
<code>$currentStep = session()->get(key: 'wizard:current_step', default: 1);</code>Menjalankan kod di atas akan mengembalikan nilai yang disimpan dalam sesi sebagai kekunci
dan kemudian memadamnya dari sesi. wizard:current_step
seperti yang ditunjukkan di bawah: put
<code>$currentStep = session()->pull(key: 'wizard:current_step');</code>Menjalankan kod di atas akan menyimpan array (diluluskan dalam parameter kedua) sebagai nilai kekunci
. wizard:step_one:form_data
untuk menolak data ke array dalam sesi: push
<code>session()->put( key: 'wizard:step_one:form_data', value: [ 'name' => 'Ash Allen', 'email' => 'ash@example.com', ], );</code>Katakan kekunci
mempunyai data berikut: wizard:step_one:form_data:languages
<code>session()->push( key: 'wizard:step_one:form_data:languages', value: 'javascript', );</code>kod di atas (memanggil kaedah
) akan mengemas kini nilai sesi: push
<code>[ '_token' => 'bKmSfoegonZLeIe8B6TWvSm1dKwftKsvcT40xaaW' '_previous' => [ 'url' => 'https://my-app.com/users' ] '_flash' => [ 'old' => [ 'success', ], 'new' => [] ] 'success' => 'User created successfully.' 'current_team_id' => 123 ]</code>
Jika nilai wizard:step_one:form_data:languages
tidak wujud dalam sesi lagi, gunakan push
untuk membuat kunci sesi dan menetapkan nilai ke array yang mengandungi nilai yang anda lalui.
Laravel juga menyediakan beberapa kaedah penolong berguna yang membolehkan anda meningkatkan dan mengurangkan nilai dalam sesi:
anda boleh meningkatkan nilai dalam sesi seperti ini:
<code>$currentStep = session()->get(key: 'wizard:current_step');</code>
Apabila kita menjalankan kod di atas, jika nilai sesi wizard:current_step
adalah 3, ia kini akan meningkat kepada 4.
anda juga boleh mengurangkan nilai dalam sesi seperti ini:
<code>$currentStep = session()->get(key: 'wizard:current_step', default: 1);</code>
Jika nilai tidak wujud dalam sesi lagi, mereka dianggap sebagai 0. Oleh itu, panggilan increment
pada nilai sesi kosong menetapkan nilai kepada 1. Panggil decrement
pada nilai sesi kosong Tetapkan nilai kepada -1.
kedua -dua kaedah membolehkan anda menentukan nombor yang akan ditingkatkan atau menurun:
<code>$currentStep = session()->pull(key: 'wizard:current_step');</code>
anda juga boleh memadam data dari sesi menggunakan kaedah forget
:
<code>session()->put( key: 'wizard:step_one:form_data', value: [ 'name' => 'Ash Allen', 'email' => 'ash@example.com', ], );</code>
Menjalankan kod di atas akan memadam data yang dimiliki oleh kekunci wizard:current_step
dari sesi.
Jika anda ingin memadam kekunci berganda sekaligus, anda boleh lulus array utama ke fungsi forget
:
<code>session()->push( key: 'wizard:step_one:form_data:languages', value: 'javascript', );</code>
atau, jika anda ingin memadam semua data dari sesi, anda boleh menggunakan fungsi flush
:
<code>[ `php`, ]</code>
Laravel juga menyediakan beberapa fungsi pembantu yang mudah untuk memeriksa sama ada data wujud dalam sesi.
anda boleh menggunakan kaedah has
untuk memeriksa sama ada terdapat kunci dalam sesi dan sama ada nilainya tidak null
:
<code>[ `php`, `javascript`, ]</code>
Jika nilai wujud dan tidak null
, kod di atas akan kembali true
. Jika nilai itu null
atau kunci tidak wujud, ia akan kembali false
.
Begitu juga, anda juga boleh menggunakan kaedah exists
untuk memeriksa sama ada kunci wujud dalam sesi (tanpa mengira nilai yang menjadi batal):
<code>session()->increment(key: 'wizard:current_step');</code>
anda juga boleh menyemak sama ada sesi tidak wujud sama sekali:
<code>session()->decrement(key: 'wizard:current_step');</code>
Kadang -kadang anda ingin meneruskan beberapa data dalam sesi, tetapi hanya untuk permintaan seterusnya. Sebagai contoh, anda mungkin ingin menunjukkan pemberitahuan kejayaan kepada pengguna selepas pengguna menyerahkan borang tersebut.
untuk melakukan ini, anda boleh menggunakan flash
kaedah:
<code>session()->increment(key: 'wizard:current_step', amount: 2); session()->decrement(key: 'wizard:current_step', amount: 2);</code>
Jika anda ingin menjalankan kod di atas, dalam permintaan seterusnya, anda boleh membaca nilai dari sesi (menggunakan sesuatu seperti session()->get('success')
) untuk paparan. Kemudian padamkannya supaya ia tidak tersedia dalam permintaan seterusnya.
Mungkin kadang -kadang anda mempunyai beberapa data flash (ditambah dalam permintaan sebelumnya) dan anda ingin menyimpannya ke permintaan seterusnya.
anda boleh menyegarkan semua data flash menggunakan kaedah reflash
:
<code>session()->forget(keys: 'wizard:current_step');</code>
atau, jika anda hanya ingin menyimpan beberapa data flash, anda boleh menggunakan keep
kaedah:
<code>[ '_token' => 'bKmSfoegonZLeIe8B6TWvSm1dKwftKsvcT40xaaW' '_previous' => [ 'url' => 'https://my-app.com/users' ] '_flash' => [ 'old' => [ 'success', ], 'new' => [] ] 'success' => 'User created successfully.' 'current_team_id' => 123 ]</code>
Menjalankan kod di atas akan mengekalkan nilai sesi flash success
dan error
, tetapi akan memadamkan sebarang data kilat lain untuk permintaan seterusnya.
Setakat ini, kami hanya menggunakan fungsi penolong session()
dalam contoh kami.
tetapi anda juga boleh menggunakan kelas fasad IlluminateSupportFacadesSession
atau IlluminateHttpRequest
untuk berinteraksi dengan sesi.
Tidak kira kaedah mana yang anda gunakan, anda masih boleh menggunakan kaedah yang sama yang diterangkan sebelum ini dalam artikel ini. Kaedah ini hanyalah cara yang berbeza untuk berinteraksi dengan data sesi.
untuk menggunakan fasad Session
<code>$currentStep = session()->get(key: 'wizard:current_step');</code>Sebagai alternatif, anda boleh mengakses sesi dengan memanggil kaedah
yang disuntik ke dalam kaedah pengawal. Katakan anda mempunyai kaedah pengawal berikut: IlluminateHttpRequest
session
<code>$currentStep = session()->get(key: 'wizard:current_step', default: 1);</code>
pergi lebih jauh
Jadi, kita sekarang akan meliputi beberapa perangkap yang berpotensi dan bagaimana untuk mengelakkannya.
# typo dalam kekunci sesi
Melekat dengan contoh penyihir kami, dengan mengandaikan kami ingin menyimpan langkah semasa dalam sesi. Oleh itu, kod kami mungkin kelihatan seperti ini:
Kemudian, di bahagian yang berlainan dari asas kod, kita mungkin mahu membaca langkah semasa dari sesi:
<code>$currentStep = session()->pull(key: 'wizard:current_step');</code>
Adakah anda melihat kesilapan yang saya buat sekarang? Saya secara tidak sengaja cuba membaca kekunci
<code>session()->put( key: 'wizard:step_one:form_data', value: [ 'name' => 'Ash Allen', 'email' => 'ash@example.com', ], );</code>dan bukannya kekunci
. wizard:step
wizard:current_step
Ini adalah contoh mudah, tetapi dalam pangkalan kod besar, mudah untuk membuat kesilapan sedemikian. Kesilapan -kesilapan yang jelas ini juga mungkin yang paling sukar dicari.
Contohnya, jika kunci sesi statik, anda boleh menentukan yang tetap (mungkin dalam kelas sesi yang akan kami sampaikan kemudian) seperti berikut:
Ini bermakna kita mengurangkan bilangan rentetan mentah yang digunakan dalam asas kod, yang membantu mengurangkan bilangan kesilapan.
Walau bagaimanapun, kadang -kadang anda mungkin perlu menjana kekunci sesi secara dinamik. Sebagai contoh, katakan kami mahu kekunci
<code>session()->push( key: 'wizard:step_one:form_data:languages', value: 'javascript', );</code>kami mengandungi medan ID Team. Kita boleh membuat kaedah untuk menghasilkan kunci seperti berikut:
Seperti yang dapat kita lihat dalam kod di atas, kita secara dinamik menjana kunci sesi supaya ia dapat digunakan dalam kaedah yang berbeza. Sebagai contoh, jika kita cuba mencari langkah semasa pasukan dengan ID 1, kunci akan menjadi wizard:current_step
.
Perangkap lain yang saya lihat ketika berurusan dengan projek yang telah ada untuk seketika adalah konflik utama sesi.
Sebagai contoh, bayangkan bahawa beberapa tahun yang lalu anda membina wizard untuk membuat akaun pengguna baru. Jadi anda boleh menyimpan data sesi seperti ini:
<code>[ '_token' => 'bKmSfoegonZLeIe8B6TWvSm1dKwftKsvcT40xaaW' '_previous' => [ 'url' => 'https://my-app.com/users' ] '_flash' => [ 'old' => [ 'success', ], 'new' => [] ] 'success' => 'User created successfully.' 'current_team_id' => 123 ]</code>
Anda kini telah ditugaskan untuk membina ciri baru yang juga mempunyai wizard, dan anda telah melupakan Wizard lama dan konvensyen penamaan yang anda gunakan. Anda secara tidak sengaja boleh menggunakan kunci yang sama untuk penyihir baru, menyebabkan konflik data dan memperkenalkan kesilapan yang berpotensi.
Untuk mengelakkan ini, saya suka menggunakan nama fungsi sebagai awalan untuk kunci sesi. Jadi untuk menyimpan data wizard untuk membuat pengguna baru, saya mungkin mempunyai kunci berikut:
new_user_wizard:current_step
new_user_wizard:step_one:form_data
new_user_wizard:step_two:form_data
new_team_wizard:current_step
new_team_wizard:step_one:form_data
new_team_wizard:step_two:form_data
Jika anda meneka ia adalah contoh
Hanya bercakap dan bercakap, saya ingin menjelaskan bahawa apabila anda membaca data dari sesi, ia tidak selalu membersihkan jenis data yang anda gunakan. Anda akhirnya perlu melihat kod yang menulis data ke sesi untuk mengetahui apa itu. Ini boleh mengganggu dan memakan masa dan boleh menyebabkan kesilapan.
<code>$currentStep = session()->get(key: 'wizard:current_step');</code>Anda boleh menambah komen atau blok dokumen ke kod yang membaca data sesi. Tetapi ini hanya satu petunjuk. Sekiranya komen tidak dikemas kini (jika jenis data sesi berubah), maka ia tidak membantu dan meningkatkan kemungkinan kesilapan.
AppDataTransferObjectsWizardsFormData
Kaedah lain yang saya suka gunakan ialah membaca data sesi di dalam kaedah dan menambah jenis pulangan ke kaedah. Dengan cara ini, anda boleh memastikan bahawa jenis data yang anda gunakan adalah betul. Ia juga membantu IDE anda dan orang yang membaca kod tersebut.
sekarang kita dapat melihat bahawa kaedah
mengembalikan contoh. Ini jelas menggambarkan jenis data yang kami gunakan. Kita kemudian boleh memanggil kaedah ini dalam pengawal seperti ini:
# data sesi proses dalam kelas sesi
<code>$currentStep = session()->get(key: 'wizard:current_step', default: 1);</code>
Seperti yang telah kita lihat di bahagian sebelumnya, terdapat beberapa perangkap yang mudah (tetapi biasa) ketika menggunakan sesi di Laravel. stepOneFormData
AppDataTransferObjectsWizardsFormData
Dengan menggunakan "kelas sesi", setiap perangkap ini boleh dielakkan (atau sekurang -kurangnya dikurangkan). Saya suka menggunakan kelas sesi untuk merangkum logik pemprosesan data sesi yang berkaitan dengan fungsi tunggal di satu tempat.
Sebagai contoh, katakan kami mempunyai wizard untuk membuat pengguna dan yang lain untuk membuat pasukan. Saya akan membuat kelas sesi untuk setiap penyihir ini:
AppSessionsUsersNewUserWizardSession
AppSessionsTeamsNewTeamWizardSession
Gunakan nama fungsi secara automatik sebagai awalan untuk semua kunci.
Dalam contoh sebelumnya, saya telah mencadangkan menggunakan kelas sesi. Tetapi mari kita lihat lebih mendalam bagaimana saya suka membina kelas -kelas ini.
Katakan kami mempunyai kelas sesi berikut untuk wizard pengguna baru. Pada pandangan pertama, ia mungkin agak menggembirakan, tetapi mari kita lihat kod dan pecahkannya:
Dalam kelas di atas, kita mula -mula menentukan pembina yang menerima contoh
<code>[ '_token' => 'bKmSfoegonZLeIe8B6TWvSm1dKwftKsvcT40xaaW' '_previous' => [ 'url' => 'https://my-app.com/users' ] '_flash' => [ 'old' => [ 'success', ], 'new' => [] ] 'success' => 'User created successfully.' 'current_team_id' => 123 ]</code>. Dengan melakukan ini, Laravel secara automatik akan menyuntik contoh sesi ke dalam kami apabila kami menghuraikan kelas
dari bekas perkhidmatan. Saya akan menunjukkan kepada anda bagaimana untuk melakukan ini di pengawal kemudian. AppSessionsUsersWizardSession
IlluminateContractsSessionSession
Kami kemudian menentukan 5 kaedah awam asas: AppSessionsUsersWizardSession
- Kembali ke langkah semasa dalam wizard. Jika tiada langkah persediaan, lalai ialah
getCurrentStep
1
- Langkah -langkah semasa dalam Wizard Persediaan. setCurrentStep
- Tetapkan data borang untuk langkah yang diberikan dalam wizard. Kaedah ini mengambil nombor langkah dan setFormDataForStep
AppDataTransferObjectsWizardsUsersFormData
- Dapatkan data borang untuk langkah yang diberikan dalam wizard. Kaedah ini mengambil nombor langkah dan mengembalikan contoh getFormDataForStep
AppDataTransferObjectsWizardsUsersFormData
- Padam semua data yang berkaitan dengan wizard dari sesi. Jika wizard telah selesai atau dibatalkan, anda mungkin mahu memanggil kaedah ini. null
flush
.
Sekarang kelas ini ditetapkan, mari kita lihat bagaimana kita berinteraksi dengannya dalam pengawal:
<code>[ '_token' => 'bKmSfoegonZLeIe8B6TWvSm1dKwftKsvcT40xaaW' '_previous' => [ 'url' => 'https://my-app.com/users' ] '_flash' => [ 'old' => [ 'success', ], 'new' => [] ] 'success' => 'User created successfully.' 'current_team_id' => 123 ]</code>
Seperti yang kita lihat, dalam contoh di atas, kami menyuntik kelas AppSessionsUsersWizardSession
ke dalam kaedah pengawal kami. Laravel secara automatik akan menghuraikan contoh sesi untuk kami.
maka kita boleh berinteraksi dengannya seperti kita dengan kelas lain.
Pada mulanya, ini mungkin berasa seperti melebihi abstrak dan memerlukan lebih banyak penyelenggaraan kod. Walau bagaimanapun, apabila projek itu berkembang, jenis arahan, jenis pulangan, kaedah penjanaan utama, dan juga kaedah penamaan (menjadikan operasi anda lebih deskriptif) sangat berguna.
Sama seperti mana -mana bahagian asas kod, anda harus memastikan anda mempunyai liputan data sesi untuk memastikan medan yang betul sedang dibaca dan ditulis.
Salah satu manfaat besar menggunakan kelas sesi ialah anda boleh dengan mudah menulis ujian gaya unit berpusat untuk setiap kaedah di dalam kelas.
Sebagai contoh, kita boleh menulis beberapa ujian untuk kaedah AppSessionsUsersWizardSession
kelas getFormDataForStep
. Sebagai peringatan, inilah kaedah:
<code>$currentStep = session()->get(key: 'wizard:current_step');</code>
kita boleh menguji beberapa senario di sini:
AppDataTransferObjectsWizardsUsersFormData
untuk langkah. null
. kelas ujian kami mungkin kelihatan seperti ini:
<code>$currentStep = session()->get(key: 'wizard:current_step', default: 1);</code>
Dalam kelas ujian di atas, kami mempunyai dua ujian yang meliputi dua kes yang kami sebutkan tadi.
Ujian gaya unit ini sesuai untuk memastikan kelas sesi anda dikonfigurasi dengan betul untuk membaca dan menulis data sesi. Tetapi mereka tidak semestinya membuat anda percaya bahawa mereka digunakan dengan betul di seluruh asas kod. Sebagai contoh, anda mungkin memanggil getFormDataForStep(1)
, dan anda harus memanggil getFormDataForStep(2)
.
Atas sebab ini, anda juga mungkin ingin mempertimbangkan untuk menegaskan data sesi dalam ujian fungsional anda (yang biasanya anda tulis untuk pengawal anda).
Sebagai contoh, katakan anda mempunyai kaedah asas berikut dalam pengawal anda dan ia akan pergi ke langkah seterusnya dalam Wizard:
<code>$currentStep = session()->pull(key: 'wizard:current_step');</code>
Dalam kaedah di atas, kita mula -mula membaca langkah semasa dari sesi. Kami kemudian menyimpan data borang untuk langkah semasa dalam sesi. Akhirnya, kami meningkatkan langkah semasa dan mengarahkan ke langkah seterusnya dalam Wizard.
kami akan mengandaikan bahawa kelas AppHttpRequestsUsersWizardNextStepRequest
kami bertanggungjawab untuk mengesahkan data borang dan mengembalikan contoh toDto
apabila kami memanggil kaedah AppDataTransferObjectsWizardsUsersFormData
.
kami juga akan mengandaikan bahawa kaedah pengawal nextStep
boleh diakses melalui permintaan pos ke laluan /users/wizard/next-step
(dinamakan users.wizard.next-step
).
kami mungkin ingin menulis ujian berikut untuk memastikan data borang disimpan dengan betul dalam sesi:
<code>[ '_token' => 'bKmSfoegonZLeIe8B6TWvSm1dKwftKsvcT40xaaW' '_previous' => [ 'url' => 'https://my-app.com/users' ] '_flash' => [ 'old' => [ 'success', ], 'new' => [] ] 'success' => 'User created successfully.' 'current_team_id' => 123 ]</code>
Dalam ujian di atas, kami menggunakan beberapa data bentuk untuk mengeluarkan permintaan pos ke laluan /users/wizard/next-step
. Anda mungkin melihat bahawa kami menggunakan withSession
. Kaedah ini membolehkan kami menetapkan data sesi supaya kami dapat menegaskan bahawa ia dibaca dengan betul.
Kami kemudian menegaskan bahawa pengguna diarahkan ke langkah seterusnya dalam wizard dan bahawa langkah semasa dalam sesi ditetapkan kepada 3
. Kami juga menegaskan bahawa data borang untuk langkah 2
disimpan dengan betul dalam sesi.
seperti yang kita lihat dalam ujian kami, kami juga membaca dari sesi dalam dua cara:
assertSessionHas
untuk memeriksa sama ada data sesi ditetapkan dengan betul. session()
untuk membaca data sesi secara langsung. Kedua -dua kaedah berfungsi, jadi anda boleh memutuskan mana yang anda suka. Saya menggunakan kedua -dua kaedah dalam ujian di atas untuk menunjukkan kepada anda bahawa anda mempunyai pelbagai pilihan.
Harap artikel ini membantu anda memahami dengan baik apa sesi dan bagaimana mereka bekerja di Laravel. Saya juga berharap mereka memberi anda beberapa idea tentang bagaimana untuk berinteraksi dengan data sesi menggunakan kaedah berasaskan kelas untuk mengelakkan beberapa perangkap biasa.
Atas ialah kandungan terperinci Menyelam mendalam ke sesi di laravel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!