Hướng dẫn dùng assighnment trong PHP
Xin chào các bạn, trong những bài viết trước mình đã chia sẻ với các bạn về Migration và Seeder trong Laravel - nó là các công việc cần thiết khi làm việc với DB, giúp cho việc tạo bảng, quản lý phiên bản, chèn dữ liệu một cách thuận tiện nhất. Như vậy sau những bước migration và seeding, thì chúng ta đã có một cơ sở dữ liệu với đầy đủ các bảng và dữ liệu trong bảng đó. Trở lại với bài viết mình muốn chia sẻ trong series Laravel và những điều thú vị thì hôm nay mình sẽ chia sẻ cho các bạn cách truy vấn và xử lý dữ liệu đang có trong cơ sở dữ liệu. Trước hết chúng ta sẽ tìm hiểu qua mô hình MVC là gì nhé. Show Chắc hẳn ai bắt đầu với sự nghiệp làm web cũng không thể không biết mô hình MVC. Mình sẽ nói sơ lược lại một chút nhé. MVC(Model- View- Controller) là mô hình phân chia application thành 3 thành phần chính và mỗi thành phần lại có nhiệm vụ riêng của nó:
Ví dụLý thuyết trên khó hiểu ghia, mình sẽ lấy một ví dụ để các bạn dễ hiểu hơn nhé. Chắc hẳn các bạn hay đi uống trà sữa đúng không nào ))) Một ngày đẹp trời mình đi đến 157 Xã Đàn để uống Lee Tee, khi vào quán thì mình sẽ order đồ uống. Mình là người dùng, và trà sữa Ô Long Kem Cheese Size L full topping là yêu cầu của người dùng ))). Nhân viên order vui vẻ tươi vui gật đầu(giả sử quán lúc đó có một nhân viên làm việc vừa order vừa pha chế luôn cho khách). Với bạn nhân viên order, trà sữa là cần làm theo qui trình các bước:
Não của nhân viên bán trà sữa đong vai trò là controller. Ngay khi mình đến order trà sữa thì nhân viên bán trà sữa đã hiểu và bắt đầu công việc. Pha trà sữa bản chất cũng giống như giống như pha các loại nước bình thường, có điều nguyên liệu và công cụ hoàn toàn khác nhau. Bạn nhân viên bán hàng có thể sử dụng công cụ của cửa hàng. Những công cụ đó đóng vai trò là Model bao gồm:
Cuối cùng cốc trà sữa sau khi đóng hộp mà mình cầm trên tay đóng vai trò là View được làm nên từ các công cụ trong phần Model, chế biến và giao đồ thông qua phần Controller(não của bạn nhân viên). 2. Eloquent ModelORM(Object Relational Mapping) đây là tên gọi chỉ việc ánh xạ các record dữ liệu trong hệ quản trị cơ sở dữ liệu sang dạng đối tượng mà mã nguồn đang định dạng trong class. Eloquent ORM: Larvel đã sử dụng kỹ thuật ORM giúp lập trình viên thao tác dễ dàng hơn với DB. Trong phần này chúng ta sẽ nói nhiều đến phần kiến thức 6 (Model) - là một phần trong mô hình MVC ở trên. Các Model này sẽ thao tác trực tiếp với DB, xử lý logic nghiệp vụ và trả về dữ liệu cho controller.Định nghĩa Model và các thiết lập cơ bảnChúng ta sẽ định nghĩa ra model bằng câu lệnh 7 trong command Artisan.
Sau khi nhấn lệnh thì trong app/Post.php sẽ sinh ra đoạn code sau:
Để tạo model và migration chúng ta sẽ thêm option 8 hoặc 9
Các bạn chú ý tên model để mapping cho đúng với bảng trong CSDL. Nếu table trong CSDL là 0 thì tên model đặt đúng theo chuẩn là 1.Tên bảngMặc định nếu như bạn đặt tên model là 1 thì laravel sẽ mapping với bảng tên 0. Những nếu bạn muốn đặt tên bảng khác đi nhưng vẫn phải theo đúng quy chuẩn convention đặt tên trong Laravel nhé(snake case). Ví dụ mình không đặt tên 0 nữa mà mình đặt tên là 5 chẳng hạn thì biến 6 trong 7 sẽ mapping đúng model với tên bảng chúng ta khai báo.
Khóa chính của bảngTheo mặc định trong Laravel thì khóa chính của mỗi bảng sẽ là 8. Nhưng đôi lúc chúng ta muốn thay đổi trường khóa chính này với tên khác như là 9 thì chúng ta có thể khai báo qua biến 00.
Các bạn chú ý nhé, kiểu dữ liệu của khóa chính là 01 và nếu các bạn không muốn khóa chính của bạn tự tăng thì 02. Nếu kiểu dữ liệu của khóa chính không phải là kiểu 01 thì bạn nên set biến 04.TimestampsMặc định khi các bạn tạo bảng thì sẽ có 2 trường 05 và 06, những khi bạn thêm các bản ghi vào table thì 2 trường này sẽ tự động cập nhật cho nó. để eloquent không tự cập nhật giá trị cho 2 trường này mỗi khi bạn thêm record thì chúng ta sẽ set trong model như sau:
Nếu bạn không muốn lưu dữ liệu của timestamp như mặc định của nó bạn có thể thay đổi định dạng của nó trong model như sau:
Và nếu bạn muốn custom lại tên cột của 07, bạn cần set trong model như sau:
Kết nối DBTất cả các Eloquent models sẽ sử dụng DB mặc định khai báo trong file .env, nhưng nếu bạn muốn model này kết nối tới một bảng trong CSDL nào đó thì chúng ta sẽ set như sau trong model:
Chú ýĐể chác chắn là model của chúng ta mapping đúng với table trong CSDL hay chưa thì chúng ta sẽ test bằng 08. Ví dụ bảng posts có các trường (id, title, content, created_at, updated_at) Nếu trả về 09 thì chứng tỏ Eloquent đã mapping đúng model với table trong CSDL rồi.Lấy dữ liệu từ DBallKhi chúng ta đã thiết lập những tham số như trên xong, thì chúng ta bắt tay vào lấy dữ liệu từ DB về. Để lấy tất cả các bản ghi trong 1 table chúng ta dùng 10:
Thêm rằng buộc cho câu truy vấnCó những trường hợp mà chúng ta không cần thiết lấy tất cả các record của table ra, nó làm hiệu năng chương trình của chúng ta kém. Nên thêm những rằng buộc cho câu truy vấn là rất quan trọng để giảm bớt query không cần thiết và tăng hiệu năng chương trình. 0CollectionsVì các hàm của Eloquent như 11 và 12 đều trả về nhiều kết quả, hay đó là một instance từ 13 sẽ được trả về. Class 14 cũng cấp các hàm hữu ích để làm việc với các kết quả Eloquent trả về. Các bạn có thể tham khảo các collection ở đây. Mình sẽ lấy một ví dụ về cách sử dụng collections nhé. 1ChunkNếu bạn muỗn xử lý hàng ngán kết quả từ Eloquent, sử dụng 15 sẽ tiết kiệm được memory khi thao tác với tập dữ liệu kết quả lớn. hàm này sẽ lấy từng 15 của Eloquent models, cung cấp chúng thông qua 17 để xử lý. 2CursorsHàm 18 cho phép bạn duyetj qua records bằng cách sử dụng một cursor(con trỏ), nó chỉ thực thi cho một truy vấn. Khi dữ liệu lớn, hàm 18 có thể được sử dụng để giảm memory sử dụng. 3Lấy dữ liệu một Model/AggregatesNgoài việc lấy tất cả các records của table bằng hàm 10, chúng ta có thể lấy model instance bằng hàm 21 hoặc 22 4NotFound ExceptionNhưng có lúc mà bạn muốn bắn ra một exception nếu instance model không tìm thấy. Hàm 23 và 24 sẽ trả kết quả đầu tiên của query, tuy nhiên nếu không có kết quả, thì 25 sẽ được bắn ra cho người dùng. Chúng ta nên đặt trong 26. 5Nếu exception mà không được bắt thì một HTTP response 404 sẽ tự động được gửi lại cho user. Aggregatesbạn cũng có thể sử dụng các 27 như 28. 6Insert và Update ModelsInsertĐể tạo một bản ghi mới trong table, thì chúng ta sẽ tạo một model instance, sau đó chúng ta set giá trị của thuộc tính, sau đó dùng phương thức 29. 7Trong ví dụ trên chúng ta không tạo 2 trường 05 và 06 mà khi 29 sẽ tự động fill dữ liệu hai trường đó trong CSDL.UpdatesHàm 29 cũng được dùng để cập nhật model đã tồn tại trong database, dầu tiên bạn cần lấy model instance ra trước, bạn thay đổi các thuốc tính trong model instance, rồi gọi hàm 29. Giá trị hàm 06 sẽ tự động được cập nhật, bạn không cần thay đổi thủ công giá trị này. 8Mass UpdatesNhiều khi chúng ta cần update nhiều bản ghi một lúc thì chúng ta sẽ làm sau đây. Ví dụ như tất cả các các bài post chưa pulish thì sẽ được pulish hết. 9Hàm 36 sẽ nhận một mảng 37, với key chính là tên trường cần update và value chính là giá trị update.Mass Assignment 38 là tính năng cho phép lập trình một cách tự đọng gán các tham số của một HTTP request vào các biến hoặc đối tượng trong lập trình.Ví dụ chúng ta có một form đang ký sản phẩm của người dùng như sau: 0Sau kh i submit form dữ liệu lên chúng ta có thể ghi dữ liệu này vào CSDL bằng đoạn code như sau(ta bỏ qua vấn đề validate dữ liệu nhập vào): 1Thật ngắn gọn và đơn giản đúng không các bạn, tính năng này gọi là Mass Assignment. Tuy nhiên có một lỗ hổng bảo mật xảy ra nếu một người truy cập cố tính gửi dữ liệu 39 trong bảng users chẳng hạn để người đó có quyền là admin. Để xử lý lỗ hổng trong Mass Assignment, Laravel đưa ra thêm hai thuộc tính cho Model là 40 và 41. Ví dụ 2 40 cho phép thiết lập các cột trong một bảng có thể sử dụng tính năng Mass Assignment, khi đó ta có thể thực hiện 3Khi đó kẻ muốn phá hệ thống của chúng ta khổng thể gửi thêm input 43 là trường không có trong 40. Như vậy lỗ hổng trong Mass Assignment đã được Laravel đã được xử lý. Trái ngược lại với 40 là 41. Chú ý rằng chúng ta không khai báo cả hai thuộc tính nãy đồng thời lần nhau. Và một vấn đề là 40 và 48 chỉ có tác dụng với các phương thức của Eloquent Model, với các phương thức của Query Buider thì nó không có tác dụng.Có hai phương thức tạo bản ghi mới sử dụng Mass Assignment khác là 49 và 50. Như ngay tên phương thức thì các bạn cũng đoán ra chức năng của từng phương thức.
4Một phương thức nữa cũng rất hay dùng đó là : 54 5Deleting ModelĐể xóa bản ghi dữ liệu đơn gainr bằng cách chúng ta gọi đến phương thức 55 6Soft DeletingBây giờ bài toán đặt ra là khi chúng ta lỡ tay đã xóa bản ghi khỏi table, bây giờ chúng ta muốn lấy lại nó(khoc). Nhưng không sao, Laravel có cơ chế hỗ trợ người dùng khi lỡ tay xóa một bản ghi có thể lấy lại được đó chính là soft delete (xóa mềm). Tức là tưởng xóa những thực chất không xóa . Thực chất là chúng ta chỉ thêm một trường 56 để đánh dấu bản ghi này đã được xóa. Để cho phép một Model có thể thực hiện được đánh dấu bản ghi đã xóa, chúng ta sử dụng trait 57 và thêm 56 vào thược tính 59 của nó. 7Trong file migration tạo bảng 0 bạn nhớ thêm 61. Khi đó, nếu bạn thực hiện phương thức 55 thay vì nó sẽ xóa triệt để trong CSDL thì nó sẽ cập nhật thời gian hiện tại vào trường 56, và như vậy bản ghi này coi như là đã xóa khỏi table. Để xem xem bản ghi này đã được đánh dấu là xóa tạm thời hay chưa các bạn sử dụng phương thức 64. 8Để truy vấn những bản ghi đã xóa thì chúng ta sử dụng 65 9Ngược lại nếu bạn muốn truy vấn kết quả từ những bản ghi mà đã xóa mêm thì bạn sử dụng phương thức 66.Đôi lúc bạn sẽ muốn tất cả các bạn ghi đã xóa mềm rồi quay lại như trước. sử dụng phương thức 67. 0Chú ý, để xóa vĩnh viễn bản ghi dùng phương thức 68.Query ScopeVấn đề đặt ra là, nhiều khi một rằng buộc nào đó được sử dụng rất nhiều trong các câu truy vấn ở nhiều controller. Vì thế 69 sinh ra để giải quyết vấn đề này. Có 2 loại Scope: 70 và 71.Global ScopeVới phạm vi biến cục thì định nghĩa scope này sẽ áp dụng cho một Model và những truy vấn liên quan đến nó sẽ được áp dụng thêm rằng buộc. Sau đây mình sẽ lấy một ví dụ cho các bạn xem cách khai báo 72 như thế nào nhé. Đầu tiên ta sẽ tạo thư mục app/Scopes và tạo file PriceScope.php. 1Để đăng ký global scope thì chúng ta sẽ override lại phương thức 73 trong Model. 2Và khi ta sử dụng truy vấn 74 thì chỉ những product nào có price > 200000 mới được lấy ra. Ngoài ra các bạn còn có thể định nghĩa global scope bằng Closure. 3Nếu bạn muốn truy cập mà không bị ảnh hưởng nào từ global scope thì chúng ta có thể sử dụng phương thức 75. Nếu ta không truyền tham số nào vào trong phương thức này thì mặc định Laravel sẽ tự hiểu là bỏ hết tất cả các global scope đi. 4Local Scope 76 định nghĩa ra để phục vụ cho chính Model đó thôi. Các bạn hãy xem ví dụ nhé. 5Khi các bạn dùng chỉ cần gọi đến 77 là nó sẽ tự hiểu. 6EventsEloquent bắn ra một số các events: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored. Các bạn có thể tìm thấy trong 78 có sử dụng 79 trong đó hàm 80 chứa rất nhiều các events mà Eloquent sẽ bắn ra: 7Sử dụng các events của Eloquent này rất tiện dụng, ví dụ như khi bạn tạo ra một chương trình quảng cáo, thi sau khi bạn 29 thì events 82 có thể bắn ra notification cho người dùng biết là có một chương trình quảng cáo mới.ObserversNếu chúng ta cần listen nhiều event trong model thì bạn cần tạo một 83 - nơi chứa tất cả mọi lắng nghe từ event của Eloquent bắn ra. |