Câu lệnh chuẩn bị cập nhật php sql
Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách thực hiện các truy vấn như CHỌN, CẬP NHẬT, XÓA, v.v. với các điều kiện khác nhau với các câu lệnh chuẩn bị MYSQLI trong PHP. Trước khi chúng ta bắt đầu, tôi sẽ giới thiệu ngắn gọn với bạn về các câu lệnh đã chuẩn bị Show
Các câu lệnh chuẩn bị MYSQLI là gì?MYSQL là một hệ thống cơ sở dữ liệu quan hệ phổ biến. MYSQLI là một phần mở rộng PHP mạnh mẽ để kết nối với MYSQL. Các câu lệnh đã chuẩn bị dưới dạng các truy vấn được chuẩn bị trước và thực hiện sau với dữ liệu Tại sao các báo cáo đã chuẩn bị lại quan trọng?Đơn giản, các câu lệnh được chuẩn bị sẵn bảo vệ các trang web khỏi SQL Injection có thể được sử dụng để tấn công một trang web. Ngoài ra, các câu lệnh đã chuẩn bị có thể nhanh hơn các truy vấn thông thường theo một số nguồn (Tuy nhiên, theo kinh nghiệm của tôi, chúng gần như giống nhau khi thực hiện các truy vấn đơn giản. Tuy nhiên, đối với các truy vấn định kỳ, các câu lệnh đã chuẩn bị siêu nhanh hơn các truy vấn thông thường). Điều tốt nhất về báo cáo chuẩn bị là khả năng đọc. Chúng có thể dễ dàng được đọc, hiểu và quản lý Trước khi tôi bắt đầu, nếu bạn muốn xem một cách thậm chí còn dễ dàng hơn để sử dụng các câu lệnh chuẩn bị sẵn của MySQLi, hãy xem lớp trình bao bọc của tôi. Ngoài ra, đây là một tài nguyên tuyệt vời để tìm hiểu các câu lệnh được chuẩn bị sẵn PDO, đây là lựa chọn tốt hơn cho người mới bắt đầu và hầu hết mọi người nói chung Một nỗ lực hack gần đây đã được phát hiện và có vẻ như họ đang cố gắng đánh sập toàn bộ cơ sở dữ liệu. Một cuộc họp nhân viên ngẫu hứng đã được triệu tập vào lúc 2 giờ sáng, và mọi người trong công ty đang vô cùng lo lắng. Trớ trêu thay, với tư cách là người quản lý cơ sở dữ liệu, bạn lại là người bình tĩnh nhất. Tại sao? . Trên thực tế, bạn thấy điều này thật hài hước, vì những tin tặc này có thể sẽ khó chịu vì họ đã lãng phí thời gian vào những nỗ lực vô ích. Hy vọng kịch bản này sẽ không bao giờ xảy ra với trang web của bạn. Tuy nhiên, chắc chắn là một ý tưởng tốt để thực hiện các biện pháp phòng ngừa thích hợp. Nếu được triển khai đúng cách, các câu lệnh đã chuẩn bị (còn gọi là truy vấn được tham số hóa) sẽ cung cấp khả năng bảo vệ vượt trội chống lại việc tiêm nhiễm SQL. Về cơ bản, bạn chỉ cần tạo mẫu truy vấn với các giá trị giữ chỗ, sau đó thay thế các đầu vào giả bằng các giá trị thực. Thoát là không cần thiết, vì nó sẽ coi các giá trị là chữ cái; Những câu nói chuẩn bị ban đầu có vẻ đáng sợ, nhưng một khi bạn đã quen với nó, nó sẽ giống như bản chất thứ hai đối với bạn. Mục tiêu của hướng dẫn này là biến một người có ít hoặc không có kiến thức về các câu chuẩn bị thành một chuyên gia từ chối trách nhiệm. Đừng thực sự thoải mái như trình quản lý cơ sở dữ liệu này. Khi nói đến bảo mật, bạn không bao giờ nên tự mãn, bất kể bạn nghĩ hệ thống của mình an toàn đến mức nào Cách thức hoạt động của SQL injectionTruyện tranh mang tính biểu tượng sau đây, được gọi là Bobby Tables, là một mô tả tuyệt vời về cách thức hoạt động của một cuộc tấn công SQL injection. Tất cả tín dụng cho hình ảnh được chuyển đến trang web này cho phần hùng biện cổ điển này Bây giờ chúng ta đã hoàn thành phần lý thuyết, hãy bắt tay vào thực hành. Trước khi tôi bắt đầu, nếu bạn đang thắc mắc chính xác cách thức hoạt động của "Bobby Table Attack", hãy xem phần giải thích này Trong một cuộc gọi MySQL bình thường, bạn sẽ làm điều gì đó như
Vấn đề với điều này là nếu nó dựa trên đầu vào của người dùng, như trong ví dụ, thì một người dùng ác ý có thể làm 4. Bây giờ, tuyên bố này sẽ luôn được đánh giá là đúng, vì 5. Trong trường hợp này, người dùng độc hại hiện có quyền truy cập vào toàn bộ bảng của bạn. Chỉ cần tưởng tượng điều gì có thể xảy ra nếu thay vào đó là một truy vấn 6. Hãy nhìn vào những gì đang thực sự xảy ra với tuyên bố
Tin tặc có thể gây ra nhiều thiệt hại cho trang web của bạn nếu các truy vấn của bạn được thiết lập như thế này. Một sửa chữa dễ dàng cho điều này sẽ là làm
Lưu ý rằng tương tự như ví dụ đầu tiên, tôi vẫn thêm dấu ngoặc kép vào giá trị cột. Không có dấu ngoặc kép, các chuỗi vẫn dễ bị SQL injection như nhau. Nếu bạn sẽ sử dụng mệnh đề THÍCH, thì bạn cũng nên làm như vậy với 7, vì 8 sẽ không làm điều nàyĐiều này bao gồm các chuỗi, như tên hàm ngụ ý, nhưng còn các số thì sao? . Nếu bạn đang truyền biến thành int, bạn không cần phải thoát khỏi bất kỳ thứ gì. Bạn đã bảo nó về cơ bản đảm bảo rằng giá trị sẽ là một số nguyên. Làm 0 là đủ. Vì nó là một số nguyên nên rõ ràng bạn cũng không cần thêm dấu ngoặc kép vào cột sql 1Trong thực tế, nếu bạn làm theo các hướng dẫn này một cách hoàn hảo, thì chỉ cần sử dụng 8 cho chuỗi và 3 cho số nguyên là đủ. Chỉ cần đừng quên đặt bộ ký tự mặc định. Điều này có thể được thiết lập trong php. ini (phải là giá trị mặc định) như 4 và bằng cách sử dụng 5 trên mỗi trang sử dụng 6. Nhưng chỉ đối với những thứ hợp pháp trong các câu lệnh đã chuẩn bị, đó là các giá trị trong câu lệnh WHERE hoặc các giá trị cột; Bất chấp điều đó, tôi vẫn thực sự khuyên bạn nên sử dụng các câu lệnh đã chuẩn bị sẵn, vì rõ ràng chúng phù hợp hơn để bảo vệ chống lại việc tiêm nhiễm SQL và ít mắc lỗi hơn, vì bạn không phải lo lắng về việc định dạng thủ công — thay vào đó, bạn chỉ cần thay thế các trình giữ chỗ giả bằng các giá trị của mình. Tất nhiên, bạn vẫn muốn lọc và vệ sinh đầu vào của mình để ngăn chặn XSS. Với các câu lệnh chuẩn bị sẵn, có ít khía cạnh cần xem xét hơn, cùng với một số 6 (Không đặt đúng bộ ký tự là một trong những nguyên nhân. ). Tóm lại, hoàn toàn không có lý do chính đáng nào để sử dụng 8 thay cho các câu đã chuẩn bị sẵn. Tôi chỉ trình bày cách định dạng thủ công các truy vấn của bạn với nó, để cho thấy rằng điều đó là có thể. Trong thực tế, sẽ thật ngu ngốc nếu không sử dụng các câu lệnh đã chuẩn bị sẵn để ngăn chặn SQL injectionCác câu lệnh đã chuẩn bị sẵn của MySQLi hoạt động như thế nàoNói một cách dễ hiểu, đây là cách các câu lệnh được chuẩn bị sẵn của MySQLi hoạt động trong PHP
Bốn loại biến được phép
Một câu lệnh chuẩn bị, đúng như tên gọi của nó, là một cách chuẩn bị lệnh gọi MySQL mà không cần lưu trữ các biến. Bạn nói với nó rằng các biến cuối cùng sẽ đến đó - chỉ là chưa. Cách tốt nhất để chứng minh điều đó là bằng ví dụ 8Nếu bạn chưa từng thấy câu lệnh chuẩn bị trước, điều này có thể hơi lạ. Về cơ bản, điều đang xảy ra là bạn đang tạo một mẫu cho câu lệnh SQL sẽ là gì. Trong trường hợp này, chúng tôi đang chọn mọi thứ từ 9, trong đó 1 và 11 bằng 12. Dấu chấm hỏi chỉ là một trình giữ chỗ cho nơi các giá trị sẽ điPhương thức 13 là nơi bạn đính kèm các biến vào các giá trị giả trong mẫu đã chuẩn bị. Lưu ý cách có hai chữ cái trong dấu ngoặc kép trước các biến. Điều này cho cơ sở dữ liệu biết các loại biến. 14 chỉ định tên đó sẽ là một giá trị chuỗi, trong khi 15 buộc tuổi phải là một số nguyên. Đây chính là lý do tại sao tôi không thêm dấu ngoặc kép xung quanh dấu chấm hỏi cho tên, giống như cách tôi thường làm đối với một chuỗi trong lệnh gọi SQL. Bạn có thể nghĩ rằng tôi vừa quên, nhưng thực tế là đơn giản là không cần (Thực tế, nó thực sự sẽ không hoạt động nếu bạn đặt dấu ngoặc kép xung quanh 12, vì nó sẽ được coi là một chuỗi ký tự, thay vì . ). Bạn đã nói với nó rằng nó sẽ là một chuỗi ký tự khi bạn gọi 13, vì vậy ngay cả khi một người dùng độc hại cố gắng chèn SQL vào đầu vào của người dùng của bạn, thì nó vẫn sẽ được coi là một chuỗi. 18 sau đó thực sự chạy mã; . Chúng tôi sẽ đề cập đến việc tìm nạp kết quả trong phần ChọnTạo kết nối MySQLi mớiTạo một MySQLi mới khá đơn giản. Tôi khuyên bạn nên đặt tên tệp có tên là 19 và đặt tệp này trực tiếp bên ngoài thư mục gốc của bạn (html, public_html) để thông tin đăng nhập của bạn được bảo mật. Chúng tôi cũng sẽ sử dụng xử lý ngoại lệ, bằng cách sử dụng 00. Điều này có thể lạ đối với bạn, đặc biệt nếu bạn chưa bao giờ sử dụng toán tử bitwise trước đây. Nhưng tất cả những gì nó đang làm là báo cáo tất cả các lỗi, trong khi chuyển đổi chúng thành ngoại lệ, sử dụng lớp mysqli_sql_Exception
Rất nhiều hướng dẫn, bao gồm cả hướng dẫn sử dụng PHP, chỉ ra cách sử dụng 01 bằng cách in nó bằng 02 hoặc 03. Nhưng điều này không thực sự cần thiết (chưa kể là cực kỳ ngu ngốc, vì bạn sẽ in thông tin này ra thế giới), vì thông báo lỗi sẽ được thêm vào nhật ký lỗi của bạn. Thông báo trong 02 phải là thứ mà người dùng bình thường có thể hiểu được, chẳng hạn như 05Bạn sẽ nghĩ rằng việc đặt bộ ký tự thành 06 trong php của bạn. ini sẽ đủ, cùng với 07 cho toàn bộ cơ sở dữ liệu của bạn, nhưng đôi khi sẽ xảy ra lỗi lạ nếu bạn không đặt nó trong tệp php của mình,Ngoài ra, bạn có thể khởi tạo nó trong khối thử/bắt nếu bạn bật báo cáo nội bộ, điều mà tôi đã đề cập trong phần xử lý lỗi. Vui lòng không bao giờ báo cáo lỗi trực tiếp trên trang web của bạn trong quá trình sản xuất. Bạn sẽ tự chuốc họa vào thân vì một sai lầm ngớ ngẩn như vậy, vì nó sẽ in ra thông tin cơ sở dữ liệu nhạy cảm của bạn (tên người dùng, mật khẩu và tên cơ sở dữ liệu). Đây là những gì php của bạn. ini sẽ giống như trong sản xuất. làm cả 08 và 09. Ngoài ra, không lặp lại lỗi trong quá trình sản xuất
Nếu bạn thích sử dụng set_Exception_handler() thay vì 20, bạn có thể làm như sau để tránh lồng nhau. Nếu bạn đang sử dụng phương pháp này, bạn cần hiểu rằng nó sẽ ảnh hưởng đến mọi trang được bao gồm trong. Do đó, bạn phải sử dụng lại chức năng này với một thông báo tùy chỉnh cho mỗi trang hoặc sử dụng restore_exception_handler() để hoàn nguyên về phiên bản PHP tích hợp. Nếu bạn tạo nhiều cái, nó sẽ chuyển đến cái trước đó bạn đã tạo 1Có một hậu quả rất nghiêm trọng khi sử dụng 21, đó là nó sẽ báo cáo thông tin cơ sở dữ liệu nhạy cảm của bạn. Bạn có ba tùy chọn để vẫn sử dụng nó nhưng không báo cáo mật khẩu của mình
Tôi thực sự khuyên bạn nên thực hiện một trong những phương pháp này. Ngay cả khi bạn siêng năng và đảm bảo rằng tất cả các lỗi của bạn chỉ xuất hiện trong nhật ký lỗi của bạn, cá nhân tôi không hiểu tại sao mọi người cần đăng nhập mật khẩu của họ. Dù sao thì bạn cũng đã biết vấn đề là gì Chèn, cập nhật và xóaChèn, cập nhật và xóa có cú pháp giống nhau nên sẽ được kết hợp với nhau Chèn 0 2Xóa bỏ 6Nhận số hàng bị ảnh hưởngBạn cũng có thể muốn kiểm tra trạng thái của một hàng mà bạn đã chèn, cập nhật hoặc xóa. Đây là cách bạn sẽ làm nếu bạn đang cập nhật một hàng 0Trong trường hợp này, chúng tôi đã kiểm tra xem có hàng nào được cập nhật không. Để tham khảo, đây là cách sử dụng cho các giá trị trả về của 61-1 - truy vấn trả về lỗi; 0 - không có bản ghi nào được cập nhật trên 63, không có hàng nào khớp với mệnh đề 64 hoặc không có truy vấn nào được thực hiệnLớn hơn 0 - trả về số hàng bị ảnh hưởng; Nhận hàng phù hợpMột vấn đề phổ biến với 67 là không thể biết tại sao nó lại trả về 0 khi CẬP NHẬT. Điều này là do nó in số lượng hàng đã thay đổi, do đó, sẽ không rõ ràng nếu bạn cập nhật (các) giá trị của mình với cùng một dữ liệuMột tính năng tuyệt vời chỉ có ở MySQLi và không tồn tại trong PDO, là khả năng nhận thêm thông tin về một truy vấn. Về mặt kỹ thuật, bạn có thể đạt được điều đó trong PDO, nhưng điều đó chỉ có thể được thực hiện trong kết nối, do đó bạn không thể chọn 1Điều này sẽ in 2Tôi thấy đây là một triển khai khá thiếu thận trọng, vì việc sử dụng nó như hiện tại là cực kỳ không phù hợp. May mắn thay, chúng ta có thể thay đổi điều đó, bằng cách chuyển đổi nó thành một mảng kết hợp. Tất cả tín dụng sẽ làm điều này trên các tài liệu PHP. Mặc dù sử dụng 68 để CẬP NHẬT cho đến nay là trường hợp sử dụng phổ biến nhất của nó, nhưng nó cũng có thể được sử dụng cho một số trường hợp 3Bây giờ điều này sẽ xuất ra một mảng 4Nhận khóa chính mới nhất được chèn 5Kiểm tra xem mục trùng lặpĐiều này rất hữu ích nếu bạn tạo một ràng buộc duy nhất trên một bảng, vì vậy không được phép sao chép. Bạn thậm chí có thể làm điều này cho nhiều cột, vì vậy nó sẽ phải là hoán vị chính xác. Nếu tắt chức năng xử lý ngoại lệ, bạn sẽ kiểm tra mã lỗi bằng 69. Với việc xử lý ngoại lệ được bật, bạn có thể chọn giữa phương pháp đó hoặc phương pháp ngoại lệ chung 00. Lưu ý, điều này khác với PDOException, nó sẽ in SQLSTATE, thay vì mã lỗiĐây là một. Mã lỗi cho mục nhập hàng trùng lặp từ bản cập nhật hoặc phần chèn là 1062 và SQLSTATE là 23000. Để kiểm tra cụ thể SQLSTATE, bạn phải sử dụng 01 6Đây là cách bạn sẽ thiết lập một ràng buộc duy nhất 7Lựa chọnTất cả các câu lệnh chọn trong các truy vấn được tham số hóa sẽ bắt đầu giống nhau. Tuy nhiên, có một sự khác biệt chính để thực sự lưu trữ và tìm nạp kết quả. Hai phương pháp tồn tại là 02 và 03get_result()Đây là cách linh hoạt hơn trong cả hai, vì nó có thể được sử dụng cho mọi tình huống. Cần lưu ý rằng điều này yêu cầu mysqlnd, đã được đưa vào PHP từ 5. 3 và là trình điều khiển gốc mặc định kể từ 5. 4, như đã nêu ở đây. Tôi nghi ngờ nhiều người đang sử dụng các phiên bản cũ hơn thế, vì vậy bạn thường nên gắn bó với 02Điều này về cơ bản cho thấy api mysqli_result thông thường, không chuẩn bị. Có nghĩa là một khi bạn thực hiện 05, bạn có thể sử dụng nó chính xác như cách bạn sử dụng 06Giờ đây, bạn có thể sử dụng các phương thức sau để tìm nạp từng hàng một hoặc tất cả cùng một lúc. Đây chỉ là một số trong những cái phổ biến nhất, nhưng bạn có thể xem toàn bộ lớp mysqli_result để biết tất cả các phương thức của nó Một hàng
Tất cả các
8đầu ra 9bind_result()Bạn có thể thắc mắc, tại sao lại sử dụng 03? . Ngoài ra, trước khi 02 tồn tại và mysqlnd được tích hợp vào PHP, đây là lựa chọn duy nhất của bạn, đó là lý do tại sao nhiều mã kế thừa có thể đang sử dụng nóPhần khó chịu nhất khi sử dụng 03 là bạn phải liên kết mọi cột mà bạn chọn và sau đó duyệt qua các giá trị trong một vòng lặp. Điều này rõ ràng là không lý tưởng cho rất nhiều giá trị hoặc để sử dụng với 16. Bộ chọn dấu sao đặc biệt khó sử dụng với 03, vì bạn thậm chí không biết những giá trị đó là gì nếu không tìm trong cơ sở dữ liệu. Ngoài ra, điều này làm cho mã của bạn cực kỳ không thể duy trì được với các thay đổi đối với bảng. Điều này thường không thành vấn đề, vì dù sao thì bạn cũng không nên sử dụng bộ chọn ký tự đại diện trong chế độ sản xuất (nhưng bạn biết đấy) 0đầu ra 1Tìm nạp mảng liên kếtTôi thấy đây là trường hợp sử dụng phổ biến nhất. Tôi cũng sẽ sử dụng chuỗi sau đây, mặc dù điều đó rõ ràng là không cần thiết 2Nếu bạn cần sửa đổi tập kết quả, thì có lẽ bạn nên sử dụng vòng lặp while với 18 và tìm nạp từng hàng một 3đầu ra 4Bạn thực sự có thể làm điều này bằng cách sử dụng 03, mặc dù nó rõ ràng không được thiết kế cho nó. Đây là , mặc dù cá nhân tôi cảm thấy điều đó thật tuyệt khi biết là có thể, nhưng thực tế không nên sử dụngTìm nạp mảng sốĐiều này tuân theo định dạng giống như một mảng kết hợp. Để có được toàn bộ mảng trong một lệnh, không có vòng lặp, bạn sẽ sử dụng 20. Nếu bạn cần tìm nạp kết quả trong một vòng lặp, bạn phải sử dụng 21 5Và tất nhiên, việc điều chỉnh vòng lặp while 6đầu ra 7Tìm nạp một hàngCá nhân tôi thấy việc sử dụng 03 đơn giản hơn khi tôi biết thực tế rằng tôi sẽ chỉ tìm nạp một hàng, vì tôi có thể truy cập các biến theo cách rõ ràng hơn 8Bây giờ bạn có thể sử dụng chỉ đơn giản là sử dụng các biến trong 03, như 24 vì bạn biết chúng sẽ chỉ chứa một giá trị, không phải một mảngĐây là phiên bản 02 9Sau đó, bạn sẽ sử dụng biến như 26 chẳng hạnđầu ra 80Tìm nạp mảng đối tượngĐiều này rất giống với việc tìm nạp một mảng kết hợp. Sự khác biệt chính duy nhất là bạn sẽ truy cập nó như 27. Ngoài ra, trong trường hợp bạn chưa biết, các đối tượng được truyền theo giá trị, trong khi mảng theo tham chiếu 81đầu ra 82Bạn thậm chí có thể thêm các giá trị thuộc tính vào một lớp hiện có. Tuy nhiên, cần lưu ý rằng có một vấn đề tiềm ẩn, theo tài liệu PHP. Vấn đề là nếu bạn có một giá trị mặc định trong hàm tạo của mình với một tên biến trùng lặp, nó sẽ tìm nạp đối tượng trước rồi đặt giá trị của hàm tạo, do đó ghi đè lên kết quả đã tìm nạp. Thật kỳ lạ, có một "lỗi" từ PHP 5. 6. 21 đến 7. 0. 6 nơi điều này sẽ không xảy ra. Mặc dù điều này vi phạm các nguyên tắc của OOP, một số người vẫn thích tính năng này, mặc dù nó có lỗi trong một số phiên bản nhất định. Một cái gì đó như 28 trong PDO nên được triển khai trong MySQLi để cung cấp cho bạn tùy chọn để chọn 83Như nhận xét, đây là cách bạn sẽ làm điều đó một cách chính xác. Tất cả những gì bạn cần là một điều kiện if đơn giản để kiểm tra xem biến có bằng giá trị của hàm tạo hay không — nếu không, chỉ cần không đặt nó trong hàm tạo. Điều này về cơ bản giống như sử dụng 28 trong PDO 84Một hành vi bất ngờ nhưng có khả năng hữu ích khác khi sử dụng 30 là bạn có thể sửa đổi các biến riêng tư. Tôi thực sự không chắc mình cảm thấy thế nào về điều này, vì điều này dường như vi phạm các nguyên tắc đóng góiPhần kết luậnbind_result() - được sử dụng tốt nhất để tìm nạp một hàng mà không có quá nhiều cột hoặc 16; get_result() - là cái được ưu tiên cho hầu hết mọi trường hợp sử dụng ThíchBạn có thể nghĩ rằng bạn có thể làm điều gì đó như 85Nhưng điều này không được phép. Trình giữ chỗ 12 phải là toàn bộ giá trị chuỗi hoặc số nguyên. Đây là cách bạn sẽ làm điều đó một cách chính xác 86Ở đâu trong mảngĐây chắc chắn là điều tôi muốn thấy được cải thiện trong MySQLi. Hiện tại, có thể sử dụng các câu lệnh được chuẩn bị sẵn của MySQLi với 33, nhưng cảm thấy hơi dài dònglưu ý bên lề. Hai ví dụ sau sử dụng giải nén đối số for, yêu cầu PHP 5. 6+. Nếu bạn đang sử dụng phiên bản thấp hơn, thì bạn có thể thay thế nó bằng 34 87Với các trình giữ chỗ khácVí dụ đầu tiên cho thấy cách sử dụng mệnh đề 33 với trình giữ chỗ giả chỉ bên trong nó. Điều gì sẽ xảy ra nếu bạn muốn sử dụng các trình giữ chỗ khác ở những nơi khác nhau? 88Nhiều báo cáo đã chuẩn bị trong giao dịchĐiều này có vẻ kỳ lạ tại sao nó thậm chí sẽ đảm bảo phần riêng của nó, vì theo nghĩa đen, bạn có thể chỉ cần sử dụng lần lượt các câu lệnh đã chuẩn bị. Mặc dù điều này chắc chắn sẽ hoạt động, nhưng điều này không đảm bảo rằng các truy vấn của bạn là nguyên tử. Điều này có nghĩa là nếu bạn chạy mười truy vấn và một truy vấn không thành công thì chín truy vấn còn lại sẽ thành công. Nếu bạn muốn các truy vấn SQL của mình chỉ thực thi nếu tất cả chúng đều thành công, thì bạn phải sử dụng các giao dịch 89Sử dụng lại cùng một mẫu, các giá trị khác nhau 0Xử lý lỗiLỗi nghiêm trọng. Lỗi chưa xử lý. Gọi hàm thành viên bind_param() trên booleanBất kỳ ai đã sử dụng các câu lệnh được chuẩn bị sẵn của MySQLi đều đã thấy thông báo này vào một thời điểm nào đó, nhưng nó có nghĩa là gì? . Vì vậy, làm thế nào để bạn khắc phục điều này, bạn có thể yêu cầu? Xử lý ngoại lệTất cả các chức năng mysqli trả về false khi thất bại, vì vậy bạn có thể dễ dàng kiểm tra tính trung thực của từng chức năng và báo cáo lỗi với 37. Tuy nhiên, điều này rất tẻ nhạt và có một cách hay hơn để thực hiện việc này nếu bạn bật báo cáo nội bộ. Tôi khuyên bạn nên làm theo cách này, vì nó dễ mang theo hơn nhiều từ quá trình phát triển đến sản xuấtĐiều này cũng có thể được sử dụng trong sản xuất, miễn là bạn đã thiết lập nhật ký lỗi cho tất cả các lỗi; . ban đầu. Vui lòng không bao giờ báo cáo lỗi trực tiếp trên trang web của bạn trong quá trình sản xuất. Bạn sẽ tự đá mình vì một sai lầm ngớ ngẩn như vậy. Vị trí của 21 cũng quan trọng. nếu bạn đặt nó trước khi tạo kết nối mới thì nó cũng sẽ xuất mật khẩu của bạn; Đây là những gì php của bạn. ini sẽ giống như trong sản xuất. làm cả 08 và 09. Ngoài ra, hãy nhớ rằng mỗi trang thực sự chỉ nên sử dụng một khối 20 duy nhất, chung, thay vì gói từng truy vấn riêng lẻ. Ngoại lệ duy nhất cho điều này là với các giao dịch, sẽ được lồng vào nhau, nhưng đưa ra ngoại lệ của chính nó, do đó, toàn cầu 20 có thể "bắt" nó 1Trình xử lý ngoại lệ tùy chỉnh, bạn cũng có thể sử dụng 29 trên mỗi trang (hoặc chuyển hướng toàn cầu). Thao tác này sẽ loại bỏ lớp dấu ngoặc nhọn lồng vào nhau. Nếu bạn đang sử dụng các giao dịch, bạn vẫn nên sử dụng thử nắm bắt với điều đó, nhưng sau đó ném ngoại lệ của riêng bạn 2Gotcha với Xử lý ngoại lệBạn muốn tất cả các lỗi MySQLi được chuyển đổi thành ngoại lệ với 00. Thật kỳ lạ, tôi nhận thấy rằng nó vẫn đưa ra một lỗi cảnh báo khi 13 có quá nhiều hoặc quá ít biến hoặc loại bị ràng buộc. Thông báo xuất ra như sau
Giải pháp cho vấn đề này là sử dụng trình xử lý lỗi toàn cầu để kích hoạt ngoại lệ. Một ví dụ về điều này có thể là 3Điều này chỉ xảy ra trên các cảnh báo thời gian chạy, nhưng tôi đã chuyển đổi tất cả các lỗi thành ngoại lệ. Tôi thấy không có vấn đề gì khi làm điều này, nhưng có một số người phản đối mạnh mẽ Tôi có cần $stmt->đóng() không?Câu hỏi tuyệt vời. Cả 46 và 47 về cơ bản đều có tác dụng giống nhau. Cái trước đóng kết nối MySQLi, trong khi cái sau đóng câu lệnh đã chuẩn bị. TLDR; . Ngoài ra còn có một chức năng đơn giản là giải phóng bộ nhớ được liên kết với kết quả MySQLi và câu lệnh đã chuẩn bị, tương ứng. 48 và 49. Bản thân tôi, có thể sẽ không bao giờ sử dụng nó, nhưng nếu bạn quan tâm, đây là cái cho kết quả và cho truy vấn được tham số hóa. Những điều sau đây cũng cần được lưu ý. cả 47 và kết thúc thực thi tập lệnh sẽ giải phóng bộ nhớPhán quyết cuối cùng. Tôi thường chỉ làm 46 và 47, mặc dù có thể lập luận rằng điều đó hơi thừa. Nếu bạn dự định sử dụng lại cùng một biến 53 cho một câu lệnh đã chuẩn bị khác, thì bạn phải đóng biến đó hoặc sử dụng một tên biến khác, chẳng hạn như 54. Cuối cùng, tôi chưa bao giờ thấy cần phải giải phóng chúng mà không cần đóng chúngCác lớp học. mysqli so với. mysqli_stmt so với. mysqli_resultMột điều bạn có thể đã nhận ra trong quá trình này là có một số phương thức nhất định tồn tại trong hai trong số các lớp, chẳng hạn như một bí danh gần như. Cá nhân tôi tin rằng sẽ tốt hơn nếu chỉ có một phiên bản, như trong PDO, để tránh nhầm lẫn
Vì vậy, sử dụng báo cáo đã chuẩn bị có nghĩa là tôi an toàn trước những kẻ tấn công?Mặc dù bạn an toàn trước SQL injection, nhưng bạn vẫn cần xác thực và làm sạch dữ liệu do người dùng nhập của mình. Bạn có thể sử dụng một chức năng như filter_var() để xác thực trước khi chèn nó vào cơ sở dữ liệu và htmlspecialchars() để khử trùng sau khi truy xuất nó Làm cách nào để sử dụng câu lệnh đã chuẩn bị cho truy vấn cập nhật trong PHP?Cách tạo câu lệnh chuẩn bị cho truy vấn CẬP NHẬT . Xác định một mảng với các giá trị được phép Lặp lại mảng nguồn và tự động tạo câu lệnh SET cho SQL, dựa trên danh sách các trường được phép Các giá trị tương ứng phải được thêm vào mảng được chỉ định sẽ được sử dụng trong hàm thực thi () Làm cách nào để cập nhật MySQL bằng câu lệnh đã chuẩn bị?Quy trình . Gọi kết nối. Chuẩn bị phương pháp để tạo một đối tượng PreparedStatement setXXX phương pháp để truyền giá trị cho các biến đầu vào. . execUpdate để cập nhật bảng với các giá trị biến phương thức đóng để đóng đối tượng PreparedStatement khi bạn sử dụng xong đối tượng đó Làm cách nào để cập nhật trong PDO PHP?Để chạy truy vấn CẬP NHẬT với PDO, chỉ cần làm theo các bước bên dưới. . tạo một câu lệnh CẬP NHẬT SQL chính xác thay thế tất cả các giá trị thực tế bằng trình giữ chỗ chuẩn bị truy vấn kết quả thực hiện câu lệnh, gửi tất cả các giá trị thực tế để thực thi() ở dạng mảng Việc sử dụng chuẩn bị () trong PHP là gì?Hàm chuẩn bị() / mysqli_prepare() được sử dụng để chuẩn bị thực thi câu lệnh SQL . |