Hiển thị dữ liệu từ MySQL trên Web. Giới thiệu - SitePoint
Một đoạn trích từ PHP & MySQL Novice to Ninja, 7th Edition, một hướng dẫn thực tế để tìm hiểu tất cả các công cụ, nguyên tắc và kỹ thuật cần thiết để tạo một ứng dụng web chất lượng, được cung cấp bên dưới. Bạn sẽ học cách sử dụng dữ liệu từ cơ sở dữ liệu MySQL và hiển thị công khai trên trang web trong hướng dẫn kết thúc của loạt bài này Show
Chương này hướng dẫn bạn cách hiển thị dữ liệu từ cơ sở dữ liệu MySQL trên một trang web cho mọi người xem, đó là những gì bạn đã đăng ký Bạn đã học các nguyên tắc cơ bản của MySQL, một công cụ cơ sở dữ liệu quan hệ và PHP, một ngôn ngữ kịch bản phía máy chủ. Bạn cũng đã viết mã PHP đầu tiên của mình Bây giờ bạn đã sẵn sàng để tìm hiểu cách kết hợp các công cụ này để xây dựng một trang web cho phép khách truy cập xem dữ liệu cơ sở dữ liệu và thậm chí thêm dữ liệu của riêng họ Ghi chú. Tương tự như Chương 3, tôi đang đề cập đến giao thức cơ sở dữ liệu là "MySQL" ở đây. Có rất nhiều tài liệu tham khảo về "MySQL" trong suốt chương này và mã PHP mà bạn viết, mặc dù chúng tôi thực sự đang kết nối với cơ sở dữ liệu MariaDB và các tập lệnh PHP của bạn cũng sẽ làm như vậy Bức tranh lớnChúng tôi có sẵn hai công cụ hiệu quả, nhưng đáng để lùi lại một bước để có được bức tranh rõ ràng về mục tiêu cuối cùng của chúng tôi trước khi tiến lên phía trước. Điều quan trọng là phải hiểu cách công cụ cơ sở dữ liệu MySQL và ngôn ngữ kịch bản PHP sẽ hoạt động cùng nhau Ở một đầu của hệ thống, bạn có một khách truy cập vào trang web của mình bằng trình duyệt web để yêu cầu một trang, trong khi ở đầu kia của hệ thống, MySQL đang được sử dụng để cho phép kéo nội dung động từ cơ sở dữ liệu để tạo trang web. . Mặt khác, bạn có nội dung trang web của mình, được lưu trữ trong một hoặc nhiều bảng trong cơ sở dữ liệu MySQL và chỉ biết cách trả lời các truy vấn (lệnh) SQL mà trình duyệt mong đợi nhận được dưới dạng tài liệu HTML tiêu chuẩn Ngôn ngữ kịch bản PHP xử lý yêu cầu trang và tìm nạp thông tin từ cơ sở dữ liệu MySQL bằng các truy vấn SQL, giống như bạn đã làm trong Chương 3 để tạo một bảng truyện cười, như minh họa trong hình trên. Sau đó, nó sẽ tự động tạo ra trang HTML hấp dẫn mà trình duyệt dự đoán Đây là điều xảy ra khi khách truy cập vào một trang trên trang web của bạn, để nó rõ ràng và cập nhật trong bộ nhớ của bạn
Tạo tài khoản người dùng MySQLPHP sẽ cần tên người dùng và mật khẩu để kết nối với máy chủ cơ sở dữ liệu MySQL của bạn. Hiện tại, tất cả những gì cơ sở dữ liệu trò đùa của bạn chứa là một vài câu nói thông minh, nhưng trong tương lai, nó có thể chứa thông tin nhạy cảm như địa chỉ email và các chi tiết riêng tư khác về khách truy cập vào trang web của bạn. Do đó, MySQL được tạo ra để trở nên rất an toàn, cho phép bạn kiểm soát chặt chẽ các kết nối mà nó chấp nhận và các hoạt động mà các kết nối đó được phép thực hiện Bạn đã đăng nhập vào máy chủ MySQL bằng người dùng MySQL đã có trong môi trường Docker nhờ Chương 3 Cung cấp cho mỗi trang web tài khoản người dùng riêng của nó sẽ cho phép bạn kiểm soát nhiều hơn đối với những người có quyền truy cập vào dữ liệu cho bất kỳ trang web cụ thể nào. Nếu bạn có một máy chủ web, bạn có thể muốn sử dụng nó để lưu trữ nhiều hơn một trang web. Bạn có thể kết nối với cơ sở dữ liệu từ tập lệnh PHP của mình bằng cùng tên người dùng ( 2) và mật khẩu ( 2), nhưng sẽ rất hữu ích nếu bạn tạo một tài khoản mới. Bạn có thể cấp cho các nhà phát triển khác quyền truy cập vào các trang web mà họ đang làm việc nếu bạn đang làm việc với họ, nhưng không còn nữaĐể làm việc trên cơ sở dữ liệu 4 mà trang web của bạn dựa vào, bạn nên tạo một tài khoản người dùng mới chỉ với các đặc quyền cụ thể mà nó cần. Hãy làm điều đó ngay bây giờChạy các truy vấn sau sau khi khởi động MySQL Workbench và kết nối với máy chủ của bạn để tạo người dùng
Truy vấn đầu tiên tạo một người dùng có tên 5 với mật khẩu 6 và khá dễ hiểu. Truy vấn thứ hai cấp cho người dùng toàn quyền truy cập vào lược đồ 4, do đó, người dùng này có thể xem và sửa đổi tất cả các bảng, cột và dữ liệu trong lược đồ 4 nhưng không có quyền truy cập vào bất kỳ thứ gì bên ngoài lược đồ đó. Dấu hiệu 7 sau tên người dùng cho biết cơ sở dữ liệu có thể được kết nối từ bất kỳ vị trí nàoBây giờ người dùng 5 đã được tạo, chúng ta có thể sử dụng nó để kết nối với cơ sở dữ liệu; . Thay vào đó, khi kết nối từ tập lệnh PHP, chúng tôi sẽ sử dụng người dùng mớiKết nối với MySQL bằng PHPCho đến giờ, bạn đã sử dụng một ứng dụng có tên là MySQL Workbench để kết nối với cơ sở dữ liệu của mình; . Các tập lệnh PHP của riêng bạn có thể kết nối trực tiếp với máy chủ MySQL đang hoạt động giống như MySQL Workbench có thể PHP không thể chỉ ra sự khác biệt giữa MariaDB và MySQL vì chúng có thể hoán đổi cho nhau, vì vậy mặc dù chương này hoàn toàn nói về việc kết nối với MySQL từ PHP, nhưng thực ra chúng ta đang kết nối với cơ sở dữ liệu MariaDB đã thảo luận trong chương trước. Bởi vì bất kỳ lệnh nào đã sử dụng đều có thể được sử dụng để kết nối với máy chủ cơ sở dữ liệu MySQL hoặc MariaDB, nên tôi sẽ gọi cơ sở dữ liệu xuyên suốt là MySQL Vì MariaDB đã sao chép phương thức chuẩn hóa của cơ sở dữ liệu MySQL ban đầu cho các máy khách như PHP và MySQL Workbench để giao tiếp với máy chủ và vì tất cả các lệnh của PHP đều sử dụng tên MySQL, nên tôi sẽ gọi cơ sở dữ liệu là MySQL trong suốt chương này để đơn giản hóa mọi thứ Có ba cách để PHP kết nối với máy chủ MySQL
Tất cả đều kết nối với cơ sở dữ liệu và gửi truy vấn đến nó, nhưng chúng làm như vậy bằng cách sử dụng các đoạn mã khác nhau Phương pháp sớm nhất để kết nối với cơ sở dữ liệu là thư viện MySQL, lần đầu tiên được cung cấp trong PHP 2. 0. Nó có ít tính năng và được thay thế bởi MySQLi bằng PHP 5. 0 (được phát hành năm 2004) Các chức năng như 22 và 23 được sử dụng để kết nối và truy vấn cơ sở dữ liệu bằng thư viện MySQL cũ; . 5 và hoàn toàn không còn xuất hiện trong PHP kể từ phiên bản 7Mặc dù thực tế là MySQLi đã trở thành thư viện ưa thích một cách hiệu quả trong mười lăm năm, nhưng vẫn có hàng trăm bài báo và ví dụ mã trên Web sử dụng các hàm 24 hiện không tồn tại này, mặc dù hầu hết các nhà phát triển đã nhận ra nhu cầu thay đổi ngay khi PHP . 0 đã được phát hànhKiểm tra ngày của bài viết nếu một ví dụ mã chứa dòng 22, vì nó có thể là từ đầu những năm 2000 và bạn không bao giờ nên tin bất cứ điều gì từ thời đó trong lập trình. Vì mọi thứ liên tục thay đổi, cuốn sách này hiện đang được tái bản lần thứ bảyThư viện MySQLi, viết tắt của "MySQL Cải tiến", đã có sẵn trong PHP 5. 0 để giải quyết một số thiếu sót trong thư viện MySQL gốc. MySQLi rõ ràng được sử dụng trong mã vì nó sử dụng các chức năng như 26 và 27ngay sau PHP 5. 0's MySQLi được phát hành, PHP 51 được phát hành, với một số thay đổi ảnh hưởng đáng kể đến cách chúng ta viết PHP ngày nay (hầu hết liên quan đến lập trình hướng đối tượng, mà bạn sẽ thấy nhiều hơn ở phần sau của cuốn sách này). 1 là PDO (PHP Data Objects), một thư viện thứ ba để kết nối với cơ sở dữ liệu MySQL, đã được giới thiệu Đối với các nhà phát triển, lợi ích lớn nhất của cách tiếp cận chung này là khi bạn đã học cách sử dụng thư viện để tương tác với cơ sở dữ liệu MySQL, thì việc tương tác với một máy chủ cơ sở dữ liệu khác sẽ rất đơn giản, mặc dù PDO và MySQLi có một số điểm khác biệt. Ưu điểm chính của việc sử dụng các tham số được đặt tên trong các câu lệnh đã chuẩn bị là viết mã PDO đơn giản hơn nhiều và có một số điểm tinh tế có thể làm cho mã PDO dễ đọc hơn. (Đừng lo lắng, tôi sẽ giải thích điều đó có nghĩa là gì sau. )) Vì những lý do này, phần lớn các dự án PHP hiện tại đều sử dụng thư viện PDO và tôi sẽ hướng dẫn bạn cách sử dụng nó trong cuốn sách này Bạn có thể háo hức quay lại viết mã sau bài học lịch sử ngắn gọn đó, vì vậy, đây là cách kết nối với máy chủ MySQL bằng PDO 8Tạm thời coi hàm 28 là hàm tích hợp sẵn, tương tự như hàm 29 mà chúng ta đã sử dụng trong Chương 2. Nếu bạn đang nghĩ, "Này, các hàm không thể có khoảng trắng trong tên của chúng", thì bạn đã đúng. Trong mọi trường hợp, cần có ba lý lẽ để chứng minh ", bạn thông minh hơn con gấu trung bình và tôi sẽ giải thích chính xác điều gì đang xảy ra ở đây trong giây lát
"Hàm" 28 này trả về một giá trị được gọi là đối tượng 804 yêu cầu kết nối đã được thiết lập, như bạn có thể nhớ lại từ Chương 2 Các hàm PHP thường trả về một giá trị khi chúng được gọi. Đây là giao diện của nó, với các giá trị cần thiết được điền vào để kết nối với cơ sở dữ liệu của bạn và chúng ta nên giữ giá trị này bằng cách lưu trữ nó trong một biến vì chúng ta dự định sử dụng kết nối 6Tên người dùng và mật khẩu bạn đã tạo trước đó trong chương này là hai đối số trong hai phần trước, vì vậy bạn có thể thấy điều gì đang xảy ra Phần 805 của đối số đầu tiên hướng dẫn PDO sử dụng cơ sở dữ liệu (còn được gọi là lược đồ) có tên là 4 theo cách phức tạp hơn một chút. Theo mặc định, mọi truy vấn PHP sẽ chọn các bản ghi từ các bảng trong lược đồ đó; Thông thường, đây sẽ là 811 (chỉ máy tính cục bộ, cùng một máy chạy PHP) hoặc trỏ đến một tên miền cụ thể nơi cơ sở dữ liệu được lưu trữ, chẳng hạn như 812 Phần 810 có vẻ khó hiểu ngay cả khi bạn đã quen thuộc với PHP, Nếu bạn xem tệp 815 cấu hình máy chủ, dịch vụ cơ sở dữ liệu được gọi là 814 và trong Docker, một dịch vụ có thể kết nối với dịch vụ khác bằng tên của dịch vụ kia. Tại sao lại là 810 và 814 đề cập đến điều gì ở đây?Bất kể các đối số là gì, điều quan trọng cần lưu ý là giá trị được trả về bởi 28 được giữ trong một biến có tên là 818Chúng tôi phải tính đến khả năng máy chủ có thể không khả dụng hoặc không truy cập được do mất mạng, tổ hợp tên người dùng/mật khẩu bạn cung cấp bị máy chủ từ chối hoặc đơn giản là do bạn quên khởi động máy chủ MySQL của mình . Trong những trường hợp này, 28 sẽ không chạy và sẽ đưa ra một ngoại lệ trong PHPGhi chú. PHP có thể được thiết lập, ít nhất là theo mặc định, để không có ngoại lệ nào được đưa ra và kết nối bị từ chối đơn giản. Nói chung, đây không phải là một hành vi mong muốn vì nó khiến việc tìm ra điều gì đã xảy ra trở nên khó khăn hơn nhiều Hãy sẵn sàng tìm hiểu thêm một số tính năng của ngôn ngữ PHP nếu bạn tò mò về ý nghĩa của việc "ném một ngoại lệ PHP. " Khi bạn hướng dẫn PHP thực hiện một tác vụ và nó không thể thực hiện được, PHP sẽ cố gắng thực hiện các hướng dẫn của bạn nhưng sẽ không thành công; PHP chỉ gặp sự cố với một thông báo lỗi cụ thể khi một ngoại lệ được đưa ra và nó ngừng hoạt động. Sau khi xảy ra lỗi, sẽ không có dòng mã nào được chạy nữa Với tư cách là nhà phát triển có trách nhiệm, bạn có trách nhiệm xác định ngoại lệ đó và giải quyết nó để chương trình có thể tiếp tục Xin lưu ý rằng nếu bạn không xử lý ngoại lệ đúng cách, PHP sẽ chấm dứt tập lệnh của bạn và hiển thị thông báo lỗi khủng khiếp. Việc tránh để người dùng nhìn thấy thông báo lỗi là đặc biệt quan trọng vì nó thậm chí sẽ tiết lộ mã của tập lệnh đã gây ra lỗi, trong trường hợp này có chứa tên người dùng và mật khẩu MySQL của bạn Bạn nên sử dụng câu lệnh 820 để đính kèm mã có thể đưa ra một ngoại lệ để bắt nó 3Câu lệnh 820 tương tự như câu lệnh 822, với điểm khác biệt là khối mã thứ hai sẽ xảy ra nếu khối mã đầu tiên không thực thiBối rối chưa? 6Mã này là một câu lệnh 820, như bạn có thể thấy, và cố gắng kết nối với cơ sở dữ liệu bằng cách sử dụng 28 trong khối 824 ở trên cùng. Nếu kết nối thành công, biến 827 được đặt thành thông báo sẽ được hiển thị sau đó và chúng tôi lưu trữ đối tượng PDO kết quả trong 818 để chúng tôi có thể làm việc với kết nối cơ sở dữ liệu mới của mìnhTrong trường hợp này, nếu kết nối với cơ sở dữ liệu đưa ra một ngoại lệ (có thể mật khẩu không chính xác hoặc máy chủ không phản hồi), biến 827 sẽ không bao giờ được đặt thành "Đã thiết lập kết nối cơ sở dữ liệu. " Điều này rất quan trọng vì bên trong câu lệnh 820, bất kỳ mã nào sau khi ném ngoại lệ sẽ không được thực thiKhối 832 của chúng tôi tuyên bố rằng nó sẽ bắt một PDOException (và lưu trữ nó trong một biến có tên là 833) nếu nỗ lực kết nối cơ sở dữ liệu của chúng tôi không thành công, đó là loại ngoại lệ mà 28 ném ra. Chúng tôi đã tạo biến 827 bên trong khối đó để giữ thông báo lỗiĐiều duy nhất thông báo lỗi này cho chúng tôi biết là PDO không thể kết nối với máy chủ cơ sở dữ liệu, điều này không hữu ích lắm. Sẽ tốt hơn nếu biết lý do tại sao lại như vậy, chẳng hạn như nếu tên người dùng và mật khẩu không hợp lệ Chúng ta có thể thêm phần này vào biến đầu ra bằng cách sử dụng phép nối vì biến 833 chứa thông tin về ngoại lệ đã xảy ra, bao gồm thông báo lỗi phác thảo vấn đề 0Quan sát rằng biến 833 là một đối tượng chứ không phải là một chuỗi. Tuy nhiên, hiện tại, tất cả những gì bạn cần biết là mã 837 nhận thông báo lỗi dựa trên ngoại lệ cụ thể đã xảy ra; Câu lệnh 820, giống như câu lệnh 822, đảm bảo rằng một trong hai nhánh, mã trong khối 824 hoặc mã trong khối 832, sẽ chạy. Biến 827 sẽ chứa một thông báo, thông báo lỗi hoặc thông báo cho biết kết nối thành công, bất kể kết nối cơ sở dữ liệu có thành công hay khôngMẫu 845, là một mẫu chung chỉ hiển thị một số văn bản trên trang, được bao gồm bất kể khối 824 thành công hay khối 832 chạy 1Ví dụ chứa toàn bộ mã. MySQL-Kết nối Thông báo "Đã thiết lập kết nối cơ sở dữ liệu" hoặc thông báo lỗi sẽ hiển thị khi mẫu được đưa vào Vui lòng quay lại phần đầu của phần này và đọc lại tất cả nếu bạn cảm thấy bối rối, vì có một số khái niệm khó trong đó. Tôi hy vọng mã nói trên hiện có ý nghĩa với bạn. Nhưng một khi bạn hiểu rõ về mã, có lẽ bạn sẽ nhận thấy rằng tôi vẫn còn một câu hỏi chưa được trả lời. Chính xác thì 28 là gì và ý tôi là gì khi tôi nói rằng nó trả về một "đối tượng PDO"?Lưu ý rằng bất kể bạn đặt tên cho lược đồ và người dùng của mình là gì, tất cả mã mẫu đã tải xuống bao gồm một lược đồ có tên là 847 và một người dùng có tên là 847, giúp bạn có thể chạy mã đó. Bạn có thể nhập tệp có tên 849 chứa cơ sở dữ liệuCơ sở dữ liệu _11850 sẽ được tạo khi bạn tải một mẫu nếu bạn sử dụng trình xem mã mẫu dựa trên web được cung cấp, nhưng mọi thay đổi bạn thực hiện đối với lược đồ này sẽ bị mất khi bạn xem một mẫu khác (bạn có thể làm hỏng mọi thứ và chuyển sang một mẫu khác . ) Sử dụng MySQL Workbench, nhập 849 từ thư mục 852 bằng cách chọn Nhập/Khôi phục dữ liệu, sau đó chọn Nhập từ tệp độc lập, điều hướng đến 849 và chọn tên lược đồ của bạn trong trường lược đồ đích mặc định. Tất cả các bản ghi trong bất kỳ bảng nào bạn đã tạo có cùng tên sẽ bị mất và bị ghi đèLập trình hướng đối tượng một cách ngắn gọnPDO là phần mở rộng Đối tượng dữ liệu PHP và 28 trả về một đối tượng PDO. Bạn có thể nhận thấy từ "đối tượng" bắt đầu len lỏi vào vốn từ vựng của tôi trong phần trước. Tôi muốn giải thích tất cả các đối tượng trong phần này là gìOOP là một phong cách lập trình nâng cao đặc biệt phù hợp để xây dựng các chương trình thực sự phức tạp với nhiều phần và bạn có thể đã gặp thuật ngữ này trong quá trình khám phá PHP hoặc lập trình nói chung của riêng mình. Phần lớn các ngôn ngữ lập trình hiện đang được sử dụng đều hỗ trợ OOP và một số trong số chúng thậm chí còn bắt buộc bạn phải làm việc theo kiểu OOP. Quyết định viết tập lệnh theo kiểu OOP tùy thuộc vào nhà phát triển trong PHP, điều này hơi lỏng lẻo hơn một chút về điều đó Phong cách thủ tục rất phù hợp với các dự án tương đối đơn giản mà chúng ta đang xử lý vào lúc này, vì vậy chúng ta sẽ tiếp tục viết mã PHP theo cách này trong thời gian hiện tại, với một cái nhìn sâu hơn về các đối tượng sau này. Tuy nhiên, OOP được sử dụng trong hầu hết các dự án phức tạp và tôi sẽ đi vào chi tiết hơn về nó ở phần sau của cuốn sách này Phải nói rằng, tiện ích mở rộng PDO mà chúng ta sẽ sử dụng để kết nối và làm việc với cơ sở dữ liệu MySQL được thiết kế theo kiểu lập trình hướng đối tượng, điều này đòi hỏi trước tiên chúng ta phải tạo một đối tượng PDO sẽ đại diện cho kết nối cơ sở dữ liệu của chúng ta trước khi sử dụng các tính năng của Tương tự như việc gọi một hàm mà bạn đã thấy cách thực hiện, việc tạo một đối tượng cũng rất giống 6Sau khi để lại một khoảng trống và chỉ định tên lớp, thông báo cho PHP về loại đối tượng bạn muốn tạo, từ khóa 855 cho PHP biết rằng bạn muốn tạo một đối tượng mới. Bạn có thể coi một lớp là một công thức, chẳng hạn như một chiếc bánh và một đối tượng là chiếc bánh thực tế được tạo ra từ việc làm theo công thức. Một lớp là một tập hợp các hướng dẫn mà PHP sẽ tuân theo để tạo một đối tượng. Giống như các công thức nấu ăn khác nhau có thể tạo ra các món ăn khác nhau, các lớp khác nhau có thể tạo ra các đối tượng khác nhauDo đó, 28 hướng dẫn PHP tạo một đối tượng 804 mới, nghĩa là một đối tượng mới của lớp 804 được tích hợp sẵn, giống như PHP đi kèm với một thư viện các lớp mà bạn có thể tạo các đối tượng từ đóBạn có thể lưu trữ một đối tượng trong một biến hoặc chuyển nó làm đối số cho một hàm trong PHP giống như bạn làm với bất kỳ giá trị nào khác, chẳng hạn như chuỗi, số hoặc mảng. Tuy nhiên, các đối tượng có một vài đặc điểm bổ sung hữu ích Như chúng ta đã thấy trong Chương 2, bạn có thể truy cập một giá trị bên trong một mảng bằng cách chỉ định chỉ mục của nó (ví dụ: 859) và một đối tượng hoạt động rất giống một mảng ở chỗ nó đóng vai trò là nơi chứa các giá trị khác. Thay vì truy cập giá trị được lưu trữ trong chỉ mục mảng, chúng tôi nói rằng chúng tôi đang truy cập thuộc tính của đối tượng, khác với việc truy cập giá trị được lưu trữ trong chỉ mục mảng khi nói đến đối tượng. Chúng tôi sử dụng ký hiệu mũi tên ( 860) thay vì dấu ngoặc vuông để chỉ định tên của thuộc tính mà chúng tôi muốn truy cập, ví dụ: 861_10Trong khi các đối tượng thường được sử dụng để lưu trữ danh sách các giá trị có liên quan (ví dụ: thuộc tính của kết nối cơ sở dữ liệu), mảng thường được sử dụng để lưu trữ danh sách có thứ tự các giá trị tương tự (ví dụ: danh sách ngày sinh nhật có thứ tự). Bạn có nghĩ rằng chúng ta cũng có thể lưu trữ những giá trị này trong một mảng không? Một hàm được lưu trữ trong một đối tượng được gọi là một phương thức (một trong những cái tên mơ hồ hơn trong thế giới lập trình, nếu bạn hỏi tôi) và có thể bao gồm một nhóm các hàm được thiết kế để mang lại cho chúng ta nhiều tính năng hữu ích hơn ngoài việc lưu trữ một bộ sưu tập các . Rắc rối hơn, các phương thức được định nghĩa bằng cách sử dụng từ khóa 862 khi chúng ta bắt đầu viết các lớp của riêng mình, đây chỉ là một hàm bên trong một lớp. Ngay cả những lập trình viên dày dạn kinh nghiệm cũng thường nhầm lẫn giữa hàm và phương thứcMột lần nữa chúng ta sử dụng ký hiệu mũi tên để gọi một phương thức. 863________thứ mười haiCác phương thức là các hàm độc lập chấp nhận đối số và trả về giá trị Tập hợp các nhóm biến (thuộc tính) và hàm (phương thức) thành các gói nhỏ được gọi là đối tượng dẫn đến mã gọn gàng hơn và dễ đọc hơn cho một số tác vụ nhất định, làm việc với cơ sở dữ liệu chỉ là một trong số đó. Tại thời điểm này, điều này có lẽ nghe hơi phức tạp và vô nghĩa, nhưng hãy tin tôi. Bạn thậm chí có thể muốn tạo các lớp tùy chỉnh trong tương lai để bạn có thể sử dụng chúng để thiết kế các đối tượng của riêng mình Bây giờ chúng ta hãy tiếp tục làm việc với đối tượng 804 mà chúng ta đã tạo và xem chúng ta có thể làm gì bằng cách gọi một trong các phương thức của nó, gắn bó với các lớp có trong PHPĐịnh cấu hình kết nốiTôi đã trình bày cách tạo một đối tượng 804 để kết nối với cơ sở dữ liệu MySQL của bạn và cách hiển thị thông báo lỗi khi có sự cố 80Tuy nhiên, nếu kết nối thành công, bạn phải định cấu hình nó trước khi sử dụng nó bằng cách gọi một vài phương thức trên đối tượng 804 hoàn toàn mới của bạnChúng tôi sẽ cần đặt mã hóa ký tự cho kết nối cơ sở dữ liệu của mình trước khi gửi truy vấn đến cơ sở dữ liệu. Như tôi đã đề cập ngắn gọn trong Chương 2, bạn nên sử dụng văn bản được mã hóa UTF-8 trong trang web của mình để tăng số lượng ký tự mà người dùng có thể sử dụng khi điền biểu mẫu trên trang web của bạn. Nếu chúng tôi để nó như vậy, chúng tôi sẽ không thể dễ dàng chèn các ký tự tiếng Trung, tiếng Ả Rập hoặc hầu hết các ký tự không phải tiếng Anh vì PHP kết nối với MySQL theo mặc định bằng cách sử dụng ISO-8859-1 (hoặc Latin-1) ít phức tạp hơn. Nếu bộ ký tự của trang web của bạn không được đặt thành UTF-8, thì bạn sẽ gặp sự cố khi người dùng nhập các ký tự cụ thể vào hộp văn bản như dấu ngoặc kép 867 vì chúng sẽ xuất hiện trong cơ sở dữ liệu dưới dạng một ký tự khác. Ngay cả khi bạn chắc chắn 100% rằng trang web của bạn sẽ chỉ được sử dụng bởi những người nói tiếng Anh, vẫn có những vấn đề khác do không đặt bộ ký tựBây giờ, đối tượng 804 mới của chúng ta phải được định cấu hình để sử dụng mã hóa UTF-8Không có nhược điểm nào khi làm điều này, miễn là tập lệnh PHP của bạn cũng được gửi tới trình duyệt dưới dạng 870 (là mặc định trong các phiên bản PHP gần đây), để yêu cầu PHP sử dụng UTF-8 khi truy vấn cơ sở dữ liệu 81Bộ mã có thể được đặt theo nhiều cách khác nhau và các phiên bản trước của cuốn sách này đã hướng dẫn bạn sử dụng mã này 82Điều này là do PHP 4. hạn chế của x. Vì điều này đã được khắc phục trong bất kỳ phiên bản PHP nào mà bạn thực sự sẽ sử dụng (tối đa và bao gồm cả phiên bản 6), nên việc đặt bộ ký tự như một phần của chuỗi kết nối là lựa chọn ưu tiên Dưới đây là mã hoàn chỉnh mà chúng tôi sử dụng để kết nối với MySQL và sau đó thiết lập kết nối đó Thí dụ. MySQL-Kết nối-Hoàn thành 83Mở ví dụ này trong trình duyệt của bạn (URL của trang sẽ là 875 nếu mã cơ sở dữ liệu của bạn nằm trong 871 bên trong thư mục 872 và tệp 845 nằm trong thư mục 874. )Nếu mọi thứ hoạt động bình thường và máy chủ của bạn đang hoạt động, bạn sẽ thấy một thông báo cho biết thành công Thay vào đó, bạn sẽ thấy một màn hình tương tự như màn hình bên dưới nếu PHP không thể kết nối với máy chủ MySQL của bạn hoặc nếu tên người dùng và mật khẩu bạn cung cấp không chính xác. Để đảm bảo mã xử lý lỗi của bạn hoạt động bình thường, bạn có thể miễn cưỡng viết sai chính tả mật khẩu của mình để kiểm tra. Thông báo lỗi từ cơ sở dữ liệu đã được hiển thị trên trang do khối 832 của chúng tôi_ 84Các phương thức khác, chẳng hạn như 878 và 879, trả về tên tệp và số dòng mà ngoại lệ đã được ném vào. Phương thức 877 trả về một thông báo mô tả ngoại lệ đã xảy ra. Bạn có thể tạo một thông báo lỗi rất kỹ lưỡng tương tự như thế này_ 85Thông báo lỗi sẽ cho bạn biết cụ thể tệp nào cần xem và lỗi xảy ra ở dòng nào, điều này cực kỳ hữu ích nếu bạn có một trang web lớn với hàng tá tệp bao gồm Khi bạn hoàn tất và kết nối cơ sở dữ liệu của bạn hoạt động bình thường, hãy quay lại thông báo lỗi đơn giản. Nếu bạn tò mò, hãy thử chèn một số lỗi khác vào mã kết nối cơ sở dữ liệu của bạn (ví dụ: tên cơ sở dữ liệu sai chính tả) và quan sát các thông báo lỗi chi tiết dẫn đến. Bằng cách này, nếu xảy ra sự cố thực sự với máy chủ cơ sở dữ liệu của bạn, khách truy cập của bạn sẽ không bị ngập trong các thuật ngữ kỹ thuật Bạn đã sẵn sàng để bắt đầu sử dụng dữ liệu của cơ sở dữ liệu sau khi kết nối được thực hiện và cơ sở dữ liệu đã được chọn Nếu bạn thực sự muốn buộc PHP ngắt kết nối khỏi máy chủ, bạn có thể làm như vậy bằng cách loại bỏ đối tượng 804 đại diện cho kết nối của bạn. Bạn có thể tự hỏi điều gì sẽ xảy ra với kết nối với máy chủ MySQL sau khi tập lệnh chạy xong. Bạn hoàn thành việc này bằng cách thay đổi biến của đối tượng thành 881_ 86Tuy nhiên, khi tập lệnh của bạn chạy xong, PHP sẽ tự động đóng mọi kết nối cơ sở dữ liệu đang mở, vì vậy bạn thường có thể để PHP dọn dẹp sau khi bạn Gửi truy vấn SQL bằng PHPĐối tượng 804 cung cấp một cơ chế tương tự — phương thức exec — để kết nối với máy chủ cơ sở dữ liệu MySQL, cho phép chúng ta nhập các truy vấn SQL (các lệnh) và xem kết quả của các truy vấn đó ngay lập tức trong Chương 3_ 87Ở đây, chuỗi 883 chứa truy vấn SQL mà bạn muốn chạyNhư bạn đã biết, phương pháp này sẽ đưa ra lỗi 830 để bạn nắm bắt nếu có vấn đề với truy vấn đang được thực thi (ví dụ: nếu bạn mắc lỗi đánh máy trong truy vấn SQL của mình)Hãy xem ví dụ dưới đây, nhằm mục đích tạo bảng trò đùa mà chúng tôi đã tạo trong Chương 3 Thí dụ. MySQL-Tạo _ 88Có thể sử dụng nhiều khối 820 để hiển thị các thông báo lỗi khác nhau — một cho kết nối và một cho truy vấn — nhưng điều này có thể dẫn đến một lượng mã bổ sung đáng kể, vì vậy chúng ta sẽ sử dụng cùng một kỹ thuật câu lệnh 820Khối 820 sẽ ngừng thực thi mã sau khi xảy ra lỗi, vì vậy nếu xảy ra lỗi trong quá trình kết nối cơ sở dữ liệu, dòng 889 sẽ không bao giờ chạy, bắt buộc rằng, nếu một truy vấn được gửi đến cơ sở dữ liệu, kết nối phải được thiết lập. Thay vào đó, tôi đã tùy chọn sử dụng cùng một câu lệnh 824 để chứa cả kết nối và truy vấnỞ phần sau của cuốn sách này, chúng ta sẽ chia chúng thành các khối khác nhau, nhưng hiện tại, hãy giữ tất cả các thao tác cơ sở dữ liệu trong cùng một khối 824. Điều này cho phép chúng tôi kiểm soát ít hơn một chút đối với thông báo lỗi được hiển thị, nhưng tiết kiệm được việc nhập câu lệnh 820 cho mỗi thao tác cơ sở dữ liệuVí dụ, hình ảnh sau đây hiển thị lỗi xuất hiện khi bảng trò đùa đã tồn tại. Ví dụ này cũng sử dụng phương pháp 892 để truy xuất thông báo lỗi toàn diện từ máy chủ MySQLXem xét lệnh SQL sau, mà chúng ta đã sử dụng trong Chương 3 để đặt ngày cho tất cả các câu chuyện cười có chứa từ "lập trình viên". 893, 894 và 895. Phương thức 896 trả về số hàng của bảng (mục nhập) bị ảnh hưởng bởi truy vấnThí dụ. Cập nhật MySQL 89Chúng ta có thể sử dụng biến trong biến 827 để in giá trị được trả về bởi phương thức exec bằng cách lưu trữ nó trong 897Kết quả của ví dụ này, giả sử cơ sở dữ liệu của bạn chỉ chứa một trò đùa "lập trình viên", được hiển thị trong hình bên dưới Thông báo cho biết rằng không có hàng nào được cập nhật vì ngày mới được áp dụng cho truyện cười giống với ngày hiện tại và nếu bạn làm mới trang để chạy lại cùng một truy vấn, bạn sẽ thấy thông báo thay đổi Do lượng dữ liệu lớn mà truy vấn 899 có thể truy xuất, PHP cung cấp các phương thức để xử lý dữ liệu đóXử lý Tập kết quả $myObject = new SomeClass(); // create an object $myObject->someProperty = 123; // set a property's value echo $myObject->someProperty; // get a property's value 899Phương thức 896 hoạt động hoàn hảo cho phần lớn các truy vấn SQL; . Tuy nhiên, các truy vấn 899 yêu cầu thứ gì đó phức tạp hơn một chút so với 896. Bạn sẽ nhớ lại rằng truy vấn 899 được sử dụng để xem dữ liệu được lưu trữ trong cơ sở dữ liệu. Chúng tôi cần một phương thức để trả về kết quả của truy vấn 899 vì chúng không chỉ ảnh hưởng đến cơ sở dữ liệuPhương thức truy vấn giống với 896 ở chỗ nó chấp nhận một truy vấn SQL làm đối số để gửi đến máy chủ cơ sở dữ liệu, nhưng thay vì trả về một mảng các hàng (mục nhập) từ truy vấn, cái mà nó thực sự trả về là một đối tượng 607 60Mã này sẽ lưu một tập kết quả (ở dạng đối tượng 607) vào biến 609 với giả định không có lỗi trong khi xử lý truy vấn. Tập hợp kết quả này chứa nội dung của tất cả các câu chuyện cười được lưu giữ trong bảng 808. Vì không có giới hạn thực tế về số lượng truyện cười trong cơ sở dữ liệu, tập hợp kết quả có thể khá lớnChúng ta không thể sử dụng vòng lặp 612 vì chúng ta không biết truy vấn trả về bao nhiêu bản ghi, vì vậy tôi đã đề cập trong Chương 2 rằng vòng lặp 611 là một cấu trúc điều khiển hữu ích khi chúng ta cần lặp nhưng không biết bao nhiêu lần. Thật vậy, bạn có thể sử dụng vòng lặp 611 tại đây để xử lý từng hàng trong tập kết quả 61Vì điều kiện cho vòng lặp 611 có thể khác với điều kiện bạn đã quen, hãy để tôi giải thích cách thức hoạt động của nó 62Hàng tiếp theo trong tập kết quả được trả về dưới dạng một mảng bằng phương thức 615 của đối tượng 607 (mảng đã được trình bày trong Chương 2). Nếu không còn hàng nào trong tập kết quả, _____0615 trả về ____0618. (Đây là một trường hợp khi yêu cầu một đối tượng PDO làm điều gì đó mà nó không thể làm - vì 615 không thể trả về hàng tiếp theo khi không còn hàng nào trong tập kết quả - sẽ không đưa ra kết quả 830. Nếu đúng như vậy, chúng ta sẽ không thể sử dụng phương thức 615 trong điều kiện vòng lặp 611 như cách chúng ta làm ở đây)Điều này cho phép bạn sử dụng câu lệnh làm điều kiện trong vòng lặp 611 vì câu lệnh nói trên gán một giá trị cho biến 623 đồng thời lấy giá trị đó làm giá trị của chính nó. Vì vòng lặp 611 sẽ tiếp tục lặp cho đến khi điều kiện của nó ước tính thành 618, nên vòng lặp này sẽ xảy ra nhiều lần khi có các hàng trong tập kết quả, với ____ ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _. Tất cả những gì còn lại để tìm ra là làm thế nào để lấy các giá trị ra khỏi biến 623 mỗi khi vòng lặp chạyNếu 623 là một hàng trong tập kết quả của chúng ta, thì 631 là giá trị trong cột 632 của hàng đó và nếu 623 là một hàng trong tập kết quả được trả về bởi 615, thì 632 là giá trị trong cột 633 của hàng đóCách tốt nhất để đạt được mục tiêu của chúng ta trong mã này là lưu trữ mỗi trò đùa dưới dạng một mục mới trong một mảng, 633, để chúng ta có thể hiển thị chúng trong một mẫu PHP 63Bây giờ các câu chuyện cười đã được trích xuất từ cơ sở dữ liệu, chúng ta có thể chuyển chúng sang một mẫu PHP Dưới đây là tóm tắt mã hiện tại của bộ điều khiển cho ví dụ này 64Truyện cười được lưu trữ trong một mảng chứa trong biến 633 và nội dung của nó sẽ giống như thế này nếu nó được viết ra bằng PHP 65Thay vì nhập dữ liệu thủ công vào mã, nó đã được lấy từ cơ sở dữ liệu Bạn có thể nhận thấy rằng, tùy thuộc vào việc khối 824 có được thực thi thành công hay không, hai biến riêng biệt, 633 và 637, đang được đặtNội dung của mảng 633 hoặc thông báo lỗi được lưu trữ trong biến 637 phải được hiển thị trong mẫu 634Hàm 642 mà trước đây chúng ta đã sử dụng để kiểm tra xem một biểu mẫu đã được gửi hay chưa có thể được sử dụng để kiểm tra xem một biến đã được gán giá trị hay chưa. Mẫu có thể bao gồm một câu lệnh 643 để quyết định hiển thị lỗi hay danh sách các trò đùa_ 66Mảng 633, không giống như các biến khác mà chúng ta đã sử dụng cho đến thời điểm này, không chỉ chứa một giá trị duy nhất, vì vậy chúng ta phải hiển thị nội dung của nó để hiển thị các câu chuyện cườiChúng ta đã thấy các vòng lặp 611 và vòng lặp 612, đây là cách phổ biến nhất để xử lý một mảng trong PHP. Vòng lặp 648 đặc biệt hữu ích để xử lý mảng_ 67Đầu vòng lặp 648 chứa một mảng, từ khóa 650, tên của một biến mới sẽ được sử dụng để lưu trữ lần lượt từng phần tử của mảng, sau đó đặt dấu ngoặc đơn thay cho điều kiện. Phần thân của vòng lặp sau đó được thực hiện một lần cho mỗi mục trong mảng. Mỗi lần, mục đó được giữ trong biến được chỉ định để mã có quyền truy cập trực tiếp vào mục đóĐể hiển thị tuần tự từng mục của một mảng trong mẫu PHP, vòng lặp 648 thường được sử dụng. Đây là cách điều này có thể tìm kiếm mảng 633 của chúng tôi_ 68Người ta thường sử dụng một cách khác để viết vòng lặp 648 khi nó được sử dụng trong một mẫu vì mã trông khá lộn xộn với hỗn hợp mã PHP này để mô tả vòng lặp và mã HTML để hiển thị nó_ 69Đây là cách dạng mã này xuất hiện trong một mẫu; 30Điều tương tự cũng có thể được thực hiện với câu lệnh 643, làm cho nó đẹp hơn khi xem các mẫu HTML bên trong bằng cách tránh các dấu ngoặc nhọn_ 31Chúng tôi có thể tạo mẫu của mình để hiển thị danh sách các câu chuyện cười bằng các công cụ mới này Thí dụ. Danh sách MySQLTruyện cười _ 32Ngoài ra, mỗi câu chuyện cười được hiển thị trong một đoạn văn ( 656) chứa một trích dẫn khối ( 657), vì chúng tôi đang trích dẫn tác giả của mỗi câu chuyện cười một cách hiệu quảBởi vì truyện cười có thể chứa các ký tự có thể được hiểu là mã HTML (ví dụ: 658, 659 hoặc 660), chúng tôi phải sử dụng 661 để đảm bảo chúng được dịch sang các thực thể ký tự HTML (nghĩa là 662, 663 và 664)Hình ảnh sau đây cho thấy trang này trông như thế nào sau khi bạn đã thêm một vài câu chuyện cười vào cơ sở dữ liệu Hãy nhớ cách chúng tôi đã sử dụng vòng lặp 611 trong bộ điều khiển của mình để tìm nạp từng hàng một trong tập kết quả 607? 33Bạn có thể đơn giản hóa mã xử lý cơ sở dữ liệu của mình bằng cách sử dụng vòng lặp 648 thay vì vòng lặp 611 vì đối tượng 607 hoạt động giống như mảng trong vòng lặp 648_ 34Tôi sẽ sử dụng biểu mẫu 648 gọn gàng hơn này trong phần còn lại của cuốn sách nàyCâu lệnh 1 của chúng tôi trông như thế này. PHP cũng cung cấp một cách viết tắt để gọi lệnh 1 35Thay vào đó, chúng ta có thể sử dụng cái này 36Điều này làm chính xác điều tương tự. 674 có nghĩa là 1 và cung cấp cho bạn cách in biến ngắn hơn một chút. Tuy nhiên, có một hạn chế. nếu bạn sử dụng 674, bạn chỉ có thể sử dụng printConcatenation và có thể theo sau lệnh gọi hàm, nhưng bạn không thể bao gồm các câu lệnh 643, câu lệnh 612, v.v.Đây là một mẫu được cập nhật bằng cách sử dụng tiếng vang tốc ký Thí dụ. MySQL-ListJokes-Viết tắt 37Tôi sẽ sử dụng ký hiệu tốc ký khi nó được áp dụng từ thời điểm này trở đi Ghi chú. trong các phiên bản PHP trước 5. Việc sử dụng ký hiệu tốc ký có thể khiến mã của bạn ngừng hoạt động khi di chuyển từ máy chủ đã bật tính năng này sang máy chủ không bật vì nó yêu cầu bật cài đặt PHP tương đối phổ biến, vì vậy nó không được khuyến khích cho Tiếng vang tốc ký hoạt động bất kể cài đặt PHP (vì vậy bất kỳ phiên bản nào bạn có thể gặp ngày nay), vì vậy bạn có thể sử dụng nó mà không phải lo lắng rằng nó có thể không hoạt động ở mọi nơi suy nghĩ trướcTrong ví dụ chúng ta vừa xem, chúng ta đã tạo một mẫu, 634, chứa tất cả HTML cần thiết để hiển thị trang. Tuy nhiên, khi trang web của chúng tôi phát triển, chúng tôi sẽ thêm nhiều trang hơn. Chúng tôi sẽ cần một trang nơi người dùng có thể thêm các câu chuyện cười vào trang web, cũng như một trang chủ với một số văn bản giới thiệu, một trang có thông tin liên hệ của chủ sở hữu trang web và, như Trong trường hợp này, tôi đang tiến lên phía trước, nhưng luôn luôn nên xem xét tương lai của một dự án. Nếu chúng ta áp dụng phương pháp mà chúng ta vừa sử dụng cho 634 cho các mẫu còn lại — 681, 682, 683, 684, v.v. — chúng ta sẽ có rất nhiều mã lặp lạiMỗi trang trên trang web sẽ yêu cầu một mẫu trông giống như thế này _1438Là một lập trình viên, lặp lại mã là một trong những điều tồi tệ nhất bạn có thể làm. Trên thực tế, các lập trình viên thường đề cập đến nguyên tắc DRY, viết tắt của cụm từ “Don't repeat yourself” (Đừng lặp lại chính mình). Tất cả các lập trình viên giỏi nhất đều lười biếng và lặp lại mã có nghĩa là lặp lại công việc. Sử dụng phương pháp sao chép/dán này cho các mẫu khiến trang web rất khó bảo trì. Các mẫu của chúng tôi bây giờ sẽ xuất hiện như sau, giả sử rằng chúng tôi muốn một phần chân trang và một phần điều hướng xuất hiện trên mỗi trang 39Nếu mã trong cấu trúc trên có trong các mẫu cho mọi trang trên trang web, ví dụ: 634 681, 682, 683 và 684, bạn cần mở từng mẫu để thay đổi năm trong thông báo bản quyền . "Ngày có thể được đọc động từ đồng hồ của máy chủ (______0690 nếu bạn tò mò. ) để tránh sự cố này, nhưng nếu chúng tôi muốn có thẻ 691 trên mỗi trang thì sao?Điều gì sẽ xảy ra nếu trang web mở rộng ra hàng chục hoặc hàng trăm trang? Một loạt các câu lệnh 692 có thể được sử dụng để giải quyết vấn đề này 60Tuy nhiên, cách tiếp cận này đòi hỏi tầm nhìn xa; Chẳng hạn, việc thêm các mục menu mới vào phần tử 694 trong ví dụ trên giúp việc này trở nên đơn giản. Tuy nhiên, việc thêm thẻ 691 vào mỗi trang hoặc thậm chí đơn giản như thêm một lớp CSS vào phần tử 696, vẫn cần phải mở mọi mẫuChiến lược mà tôi đã chỉ cho bạn ở đầu chương này thực sự được ưa chuộng hơn vì không có cách nào để dự đoán chính xác tất cả những thay đổi có thể cần thiết trong quá trình hoạt động của trang web 61Có thể đặt biến 827 thành một số mã HTML và để nó xuất hiện trên trang có điều hướng và chân trang. Ưu điểm của điều này là để thay đổi ngày trên mọi trang của trang web, chúng tôi chỉ cần thay đổi ngày ở một vị trí nếu chúng tôi luôn bao gồm mẫu này, chúng tôi sẽ gọi là 697Tôi cũng đã thêm một số CSS (có tên là 302 trong mã mẫu) để làm cho trang đẹp hơn một chút, cũng như một biến 699 để mỗi bộ điều khiển có thể xác định một giá trị xuất hiện giữa các thẻ 300 và 301 303 hiện có thể được sử dụng bởi bất kỳ bộ điều khiển nào và có thể cung cấp các giá trị cho 827 và 699Mã hóa cho 306 của chúng tôi bằng cách sử dụng 697 được hiển thị bên dướiThí dụ. MySQL-ListJokes-Layout-1 62Nhưng đợi đã. Chuyện gì đang xảy ra với 827 trong khối 824? Biến 827 chứa mã HTML sẽ được chèn vào giữa điều hướng và chân trang trong 697 và tôi nghĩ bạn sẽ đồng ý rằng mã này cực kỳ xấu. Về lý thuyết, đây là những gì chúng ta muốn xảy raGiống như chúng tôi đã làm trước đó, sẽ rất tốt nếu chuyển HTML để hiển thị truyện cười vào tệp riêng của nó — nhưng lần này, chỉ mã HTML dành riêng cho trang danh sách truyện cười. Tôi đã trình bày cách tránh kết hợp mã HTML và PHP thông qua câu lệnh 692Mã này phải được đặt trong thư mục 874 tại 634 63Điều quan trọng cần lưu ý là mã này chỉ hiển thị các câu chuyện cười và không bao gồm điều hướng, chân trang, thẻ 316 hoặc bất kỳ thành phần nào khác cần được lặp lại trên mỗi trang;Hãy thử cách sau nếu bạn muốn sử dụng mẫu này _1464Hoặc nếu bạn rất thông minh _1465Lý luận của bạn sẽ hợp lý nếu bạn thực hiện phương pháp này. Chúng ta cần bao gồm 634. Nếu bạn chạy mã ở trên, đầu ra thực sự sẽ giống như thế này vì câu lệnh 692 chỉ thực thi mã từ tệp được bao gồm tại thời điểm nó được gọi 66Những gì chúng ta cần làm là tải 634, nhưng thay vì gửi kết quả đầu ra thẳng đến trình duyệt, chúng ta cần nắm bắt và lưu trữ nó trong biến 827 để sau này 697 có thể sử dụng nóKhông có câu lệnh thay thế nào trong PHP để đạt được kết quả mong muốn vì câu lệnh 692 không trả về giá trị, nhưng điều đó không có nghĩa là không thể thực hiện đượcMặc dù thuật ngữ "bộ đệm đầu ra" nghe có vẻ khó hiểu, ý tưởng đằng sau nó thực sự khá đơn giản. Đầu ra thường được gửi trực tiếp đến trình duyệt khi bạn sử dụng 1 để in nội dung nào đó hoặc 692 để bao gồm một tệp chứa HTML, nhưng khi bạn sử dụng bộ đệm đầu ra, thay vào đó, mã HTML được lưu trữ trên máy chủ trong một "bộ đệm", đó là Tốt hơn nữa, PHP cho phép bạn kích hoạt bộ đệm và đọc nội dung của nó bất cứ khi nào bạn muốn Chúng tôi yêu cầu hai chức năng
Chữ "ob" trong tên hàm là viết tắt của "bộ đệm đầu ra", như bạn có thể đoán được Hai chức năng này có thể được sử dụng để nắm bắt nội dung của một tệp được bao gồm 67HTML được tạo bởi mẫu 634 sẽ có mặt trong biến 827 khi mã này thực thiPhương pháp này sẽ được sử dụng trong tương lai. Mỗi trang sẽ bao gồm hai mẫu
Đây là cách 306 kết thúc_1468Chúng tôi có thể đặt bất cứ thứ gì trên trang này, vì vậy hãy làm cho liên kết "Trang chủ" hoạt động bằng cách thêm tệp 871. Tuy nhiên, hiện tại, chúng tôi sẽ giữ cho nó đơn giản và chỉ có một thông báo có nội dung "Chào mừng bạn đến với Cơ sở dữ liệu truyện cười trên Internet" Cho dù đó là truyện cười mới nhất, truyện cười hay nhất trong tháng hay bất kỳ thứ gì khác mà chúng tôi thíchTrong thư mục 874, tạo một tệp có tên 682 69Vì 871 của chúng tôi không yêu cầu thông tin từ cơ sở dữ liệu và do đó không yêu cầu kết nối cơ sở dữ liệu hoặc câu lệnh 820, chúng tôi sẽ chỉ cần tải hai mẫu và đặt các biến 699 và 827Thí dụ. MySQL-ListJokes-Layout-3 00Lưu ý rằng chỉ nên kết nối với cơ sở dữ liệu khi cần thiết. Vì cơ sở dữ liệu thường là nút cổ chai hiệu suất trên nhiều trang web, nên tạo càng ít kết nối càng tốt Bạn có thể xem danh sách truyện cười trên 343 và thông báo chào mừng trên 343 khi bạn truy cập cả hai trang, vì vậy hãy đảm bảo cả hai trang đều hoạt động trong trình duyệt của bạn. Điều hướng và chân trang sẽ xuất hiện trên cả hai trangHãy thử chỉnh sửa 697; . Các thay đổi đối với bố cục sẽ ảnh hưởng đến từng trang nếu trang web có nhiều trangChèn dữ liệu vào cơ sở dữ liệuTôi sẽ chỉ cho bạn cách sử dụng các công cụ tùy ý sử dụng trong phần này để cho phép khách truy cập trang web thêm câu chuyện cười của riêng họ vào cơ sở dữ liệu Rõ ràng là bạn sẽ cần một biểu mẫu nếu bạn muốn cho phép khách truy cập trang web gửi câu chuyện cười mới, vì vậy, đây là một biểu mẫu mẫu sẽ thực hiện thủ thuật này 01Lưu cái này với tên 681 trong thư mục của 874Thuộc tính 349 của phần tử 348, hướng dẫn trình duyệt nơi gửi dữ liệu sau khi biểu mẫu được gửi, là thành phần quan trọng nhất của nó. Đây có thể là một tên tệp như 351Dữ liệu do người dùng cung cấp sẽ được gửi trở lại trang bạn hiện đang xem, tuy nhiên, nếu bạn để trống thuộc tính bằng cách đặt thuộc tính thành 352. Nếu URL của trình duyệt hiển thị trang là 353, thì đó là nơi dữ liệu sẽ được gửi khi người dùng nhấn nút ThêmMở 697 và thêm một URL vào liên kết "Thêm một trò đùa mới" trỏ đến 353. Bây giờ, hãy liên kết biểu mẫu này với ví dụ trước, hiển thị danh sách truyện cười trong cơ sở dữ liệu 02Bao gồm biểu định kiểu 357 từ Chương 2 như tôi có ở trên trong khi bạn mở 697 để bất kỳ biểu mẫu nào được hiển thị bên trong bố cục giờ đây sẽ có các kiểu mà chúng ta đã sử dụng trước đâyVăn bản của trò đùa sẽ được nhập vào hộp văn bản và được thêm vào biến 632 của yêu cầu, biến này sau đó sẽ xuất hiện trong mảng 359 của PHP, khi biểu mẫu được gửiTrong thư mục 872, hãy tạo 353. Logic cơ bản cho bộ điều khiển này là
Tạo bộ xương này 353 03Nếu biến 632 được đặt trong mảng 359, câu lệnh mở đầu 643 xác định rằng biểu mẫu đã được gửi. Nếu không, biến 827 sẽ tải biểu mẫu từ 681 để hiển thị trong trình duyệtBạn có thể xem biểu mẫu nếu bạn mở 353 trong trình duyệt của mình ngay bây giờ, nhưng việc thêm một trò đùa sẽ không thêm được gì vì chúng tôi chưa xử lý thông tin trong 370Giá trị được lưu trữ trong 370 phải được sử dụng để thực hiện truy vấn 894 nhằm điền vào cột 632 của bảng 808 với trò đùa đã được gửi. Điều này có thể nhắc bạn tạo một số mã giống như thế này 04Nội dung của _14370 hoàn toàn nằm dưới sự kiểm soát của người dùng đã gửi biểu mẫu, đây là một lỗ hổng nghiêm trọng trong mã này. Kiểu tấn công này, được gọi là tấn công SQL injection, là một trong những lỗ hổng bảo mật phổ biến nhất mà tin tặc đã tìm thấy và khai thác trên các trang web dựa trên PHP trong những ngày đầu của PHP. Nếu một người dùng độc hại nhập một số mã SQL khó chịu vào biểu mẫu, thì tập lệnh này sẽ cung cấp nó cho máy chủ MySQL của bạn mà không cần thắc mắc. Cho rằng các nhà phát triển không lường trước được chúng, các cuộc tấn công SQL injection vẫn có hiệu quả đáng ngạc nhiên trong nhiều ngóc ngách lập trình. Ví dụ: hãy xem nỗ lực tuyệt vời này nhằm làm biến mất cơ sở dữ liệu của camera giao thông. "Biển số SQL Injection hy vọng sẽ chống lại các camera giao thông châu Âu. ") Điều này có thể được nhập bởi người dùng trong trường văn bản 05Sau đây sẽ là truy vấn được gửi đến cơ sở dữ liệu 06Nhưng nếu người dùng nhập tiếp theo thì sao? _ 07Trong trường hợp này, đây sẽ là truy vấn được gửi đến cơ sở dữ liệu 08Ký tự trích dẫn trong trò đùa khiến MySQL trả về lỗi vì nó diễn giải trích dẫn trước "get" ở cuối chuỗi Chúng ta phải xóa tất cả các dấu ngoặc kép khỏi văn bản để đây là một truy vấn hợp lệ và được gửi đến cơ sở dữ liệu dưới dạng này 09Người dùng sẽ mất bất cứ thứ gì họ đã nhập vì dữ liệu chứa dấu ngoặc kép sẽ không được chèn vào, đây là một vấn đề khó chịu. Trong các phiên bản trước của PHP, có thể chạy nhiều truy vấn từ PHP bằng cách tách chúng bằng dấu chấm phẩy ( 376), nhưng những người dùng ác ý có thể lạm dụng điều nàyHãy suy nghĩ về những gì sẽ xảy ra nếu người dùng nhập này 10Kết quả là cơ sở dữ liệu sẽ nhận được các yêu cầu sau 711Người dùng có thể nhập bất kỳ truy vấn nào họ thích vào hộp và truy vấn đó sẽ được chạy trên cơ sở dữ liệu vì 377 là nhận xét một dòng trong MySQL, vì vậy dòng cuối cùng sẽ bị bỏ qua và truy vấn 894 sẽ chạy, sau đó là truy vấn 893Báo giá ma thuậtNhóm đằng sau PHP đã thêm một số biện pháp phòng thủ tích hợp chống lại các cuộc tấn công SQL injection vì chúng rất đáng sợ trong những ngày đầu của ngôn ngữ. Đầu tiên, họ tắt khả năng gửi nhiều truy vấn cùng lúc. Thứ hai, họ đã thêm một thứ được gọi là dấu ngoặc kép ma thuật, một tính năng bảo mật của PHP tự động kiểm tra tất cả các giá trị do trình duyệt gửi và thêm dấu gạch chéo ngược ( 380) trước bất kỳ ký tự "nguy hiểm" nào như dấu nháy đơn có thể gây ra sự cố nếu chúng vô tình được đưa vào Trước hết, các ký tự mà nó phát hiện và phương pháp được sử dụng để làm sạch chúng (đặt trước chúng bằng dấu gạch chéo ngược) chỉ hợp lệ trong một số trường hợp nhất định, đó là vấn đề với tính năng trích dẫn ma thuật. Các biện pháp phòng ngừa này có thể hoàn toàn vô dụng tùy thuộc vào máy chủ cơ sở dữ liệu bạn đang sử dụng và mã hóa ký tự của trang web của bạn Tính năng trích dẫn ma thuật sẽ chèn dấu gạch chéo ngược giả vào họ của người dùng nếu nó chứa dấu nháy đơn, điều này có thể rất khó chịu khi giá trị đã gửi được sử dụng cho mục đích khác ngoài việc tạo truy vấn SQL Nói một cách đơn giản, tính năng trích dẫn ma thuật là một ý tưởng tồi và kết quả là phiên bản PHP 5 đã loại bỏ nó. Tuy nhiên, với độ tuổi của PHP và khối lượng mã hiện có, bạn có thể bắt gặp các tham chiếu đến nó, do đó, đáng để hiểu cơ bản về mục đích của tính năng trích dẫn ma thuật. Tuy nhiên, điều này có nghĩa là có một số máy chủ web bị tắt và những máy chủ khác được bật sau khi các trích dẫn ma thuật được các nhà phát triển PHP xác định là một ý tưởng tồi. Các nhà phát triển phải viết mã bổ sung để giải thích cho nó hoặc đưa ra hướng dẫn cho những người sẽ sử dụng mã của họ để tắt nó, điều này không thể thực hiện được trên một số máy chủ dùng chung Hầu hết các lập trình viên đã chọn cái sau, vì vậy bạn có thể gặp một số mã như thế này 712Nếu bạn bắt gặp câu lệnh 643 như thế này trong mã kế thừa mà bạn đang làm việc, bạn có thể xóa toàn bộ khối một cách an toàn vì trên các phiên bản PHP hiện đại, mã bên trong câu lệnh 643 sẽ không bao giờ được thực thiNếu bạn bắt gặp mã như thế này, điều đó có nghĩa là tác giả ban đầu đã nhận thức được các vấn đề với dấu ngoặc kép ma thuật và cố gắng hết sức để tránh chúng. Kể từ PHP 5. 4 (mà bạn không nên gặp phải vì nó không còn được hỗ trợ), 383 sẽ luôn trả về 618 và mã sẽ không bao giờ được thực thiNếu không có những câu trích dẫn ma thuật, rõ ràng bạn phải nghĩ ra một cách khác để giải quyết vấn đề; . May mắn thay, lớp PDO sử dụng một thứ được gọi là "câu lệnh đã chuẩn bị" để thực hiện tất cả công việc khó khăn cho bạn báo cáo chuẩn bịTương tự như viết một tập lệnh 385, một câu lệnh đã chuẩn bị là một loại truy vấn SQL đặc biệt mà bạn gửi trước đến máy chủ cơ sở dữ liệu của mình để nó có thể sẵn sàng thực thi nhưng không thực sự chạy. Mã SQL trong các câu lệnh đã chuẩn bị có thể chứa các trình giữ chỗ mà bạn sẽ cung cấp các giá trị sau này, khi truy vấn được thực thi, do đó mã vẫn ở đó nhưng không thực sự chạy cho đến khi bạn truy cập trang trong trình duyệt web của mình. PDO đủ thông minh để tự động bảo vệ khỏi các ký tự "nguy hiểm" khi điền vào các phần giữ chỗ nàyDưới đây là cách thiết lập truy vấn 894 và chạy truy vấn đó một cách an toàn bằng cách sử dụng văn bản của trò đùa 370 13Đầu tiên, chúng tôi viết truy vấn SQL của mình dưới dạng chuỗi PHP và lưu trữ nó trong một biến ( 388). Tuy nhiên, điều bất thường về truy vấn 894 này là không có giá trị nào được chỉ định cho cột 632. Thay vào đó, nó chứa một trình giữ chỗ cho giá trị này (______4391)Đừng lo lắng về trường 392 vừa rồi;Bước tiếp theo của chúng tôi là gọi phương thức chuẩn bị trên đối tượng PDO của chúng tôi ( 818), chuyển truy vấn SQL của chúng tôi dưới dạng đối số. Điều này sẽ gửi truy vấn đến máy chủ MySQL, yêu cầu nó chuẩn bị chạy nó. MySQL chưa thể chạy nó, vì không có giá trị cho cột 632. Phương thức 395 trả về một đối tượng 607 (vâng, cùng một loại đối tượng cung cấp cho chúng tôi kết quả từ truy vấn 899), mà chúng tôi lưu trữ trong 398Bây giờ MySQL đã chuẩn bị câu lệnh của chúng ta để thực thi, chúng ta có thể gửi (các) giá trị còn thiếu cho nó bằng cách gọi phương thức 399 của đối tượng 607 ( 398) của chúng ta, chuyển dưới dạng đối số trình giữ chỗ mà chúng ta muốn điền vào ( 602) và giá trị . Trong trường hợp này, chúng ta chỉ cần chuyển vào một giá trị — văn bản trò đùa. Nguy cơ các ký tự trong giá trị được hiểu là mã SQL đơn giản là không xuất hiện khi sử dụng các câu lệnh đã chuẩn bị vì MySQL hiểu rằng chúng tôi đang gửi cho nó một giá trị riêng biệt thay vì mã SQL cần được phân tích cú phápĐể yêu cầu MySQL chạy truy vấn với (các) giá trị mà chúng tôi đã cung cấp, chúng tôi gọi phương thức 605 của đối tượng 607 (vâng, phương thức 607 này được gọi là 605, trái ngược với phương thức của đối tượng 804 được gọi là 896). Tính nhất quán không phải là một trong nhiều điểm mạnh của PHP. )Bạn sẽ nhận thấy rằng mã này không bao giờ đặt dấu ngoặc kép xung quanh văn bản trò đùa. 391 tồn tại bên trong truy vấn mà không có bất kỳ dấu ngoặc kép nào và chúng tôi đã chuyển 399 văn bản trò đùa đơn giản từ 359. Khi sử dụng các câu lệnh đã chuẩn bị, bạn không cần trích dẫn vì cơ sở dữ liệu (trong trường hợp của chúng tôi là MySQL) đủ thông minh để biết rằng văn bản là một chuỗi và nó sẽ được xử lý như vậy khi truy vấn được thực thiChúng ta có thể viết một số mã PHP lạ mắt để tạo ngày hôm nay ở định dạng 614 mà MySQL yêu cầu, nhưng hóa ra chính MySQL cũng có chức năng để làm điều này — 615 — để trả lời câu hỏi còn sót lại trong mã này về cách gán ngày hôm nay cho 714Có hàng chục chức năng này trong MySQL, nhưng tôi sẽ chỉ giới thiệu chúng khi cần thiết. Ở đây, hàm 615 được sử dụng để đặt ngày hiện tại làm giá trị của cột 392Chúng tôi có thể hoàn thành câu lệnh 643 mà chúng tôi đã bắt đầu trước đó để xử lý việc gửi biểu mẫu "Thêm trò đùa" ngay bây giờ khi chúng tôi có truy vấn của mình 715Câu lệnh 643 có thêm một mánh khóe nữa. Khi chúng tôi đã thêm câu chuyện cười mới vào cơ sở dữ liệu, thay vì hiển thị mẫu PHP như trước đây, chúng tôi muốn chuyển hướng trình duyệt của người dùng trở lại danh sách các câu chuyện cười. Bằng cách đó, người dùng có thể thấy trò đùa mới được thêm vào giữa họ. Đó là tác dụng của hai dòng ở cuối câu lệnh 643 ở trênĐể đạt được kết quả mong muốn, bản năng đầu tiên của bạn có thể là cho phép bộ điều khiển chỉ cần tìm nạp danh sách truyện cười từ cơ sở dữ liệu sau khi thêm truyện cười mới và hiển thị danh sách bằng cách sử dụng mẫu 634 như bình thường. Vấn đề khi làm điều này là danh sách truyện cười, theo quan điểm của trình duyệt, sẽ là kết quả của việc gửi biểu mẫu “Thêm truyện cười”. Nếu sau đó người dùng làm mới trang, trình duyệt sẽ gửi lại biểu mẫu đó, khiến một bản sao khác của trò đùa mới được thêm vào cơ sở dữ liệu. Đây hiếm khi là hành vi mong muốnThay vào đó, chúng tôi muốn trình duyệt coi danh sách truyện cười được cập nhật như một trang web bình thường có thể tải lại mà không cần gửi lại biểu mẫu. Cách để thực hiện việc này là trả lời biểu mẫu của trình duyệt bằng chuyển hướng HTTP — một phản hồi đặc biệt yêu cầu trình duyệt điều hướng đến một trang khác. (HTTP là viết tắt của Giao thức truyền tải siêu văn bản và là ngôn ngữ mô tả thông tin liên lạc yêu cầu/phản hồi được trao đổi giữa trình duyệt web của khách truy cập và máy chủ web của bạn. ) Bằng cách cho phép bạn thêm các tiêu đề cụ thể vào phản hồi được gửi tới trình duyệt, hàm PHP 622 cung cấp một cách để gửi các phản hồi máy chủ đặc biệt như thế này. Để biểu thị chuyển hướng, bạn phải gửi tiêu đề 623 với URL của trang bạn muốn chuyển hướng trình duyệt tới 716Đây là hai dòng hướng trình duyệt trở lại bộ điều khiển của chúng tôi sau khi lưu trò đùa mới vào cơ sở dữ liệu. 306 trong trường hợp này 717mã hoàn chỉnh của bộ điều khiển được cung cấp dưới đây Thí dụ. MySQL-AddJoke 718Khi bạn xem xét điều này để đảm bảo rằng tất cả đều hợp lý với bạn, hãy lưu ý rằng mã kết nối với cơ sở dữ liệu bằng cách tạo một đối tượng 28 phải xuất hiện trước bất kỳ mã nào chạy truy vấn cơ sở dữ liệu. Nhưng không cần kết nối cơ sở dữ liệu để hiển thị biểu mẫu “Thêm trò đùa”. Kết nối chỉ được thực hiện khi biểu mẫu đã được gửiMở cái này và sử dụng trình duyệt của bạn để thêm một vài câu chuyện cười mới vào cơ sở dữ liệu Giờ đây, bạn có thể xem các truyện cười đã có trong cơ sở dữ liệu MySQL của mình và thêm các truyện cười mới vào đó Xóa dữ liệu khỏi cơ sở dữ liệuTrong phần này, chúng tôi sẽ thêm một tính năng cuối cùng vào trang web cơ sở dữ liệu trò đùa của chúng tôi. nút Xóa bên cạnh mỗi câu chuyện cười trên trang truyện cười (______4306). Nhấp vào nó sẽ hiển thị danh sách các câu chuyện cười gần đây nhất và xóa câu chuyện cười cụ thể đó khỏi cơ sở dữ liệu Mặc dù chúng tôi đang triển khai một tính năng hoàn toàn mới, nhưng chủ yếu chúng tôi sẽ sử dụng các công cụ giống như trong các ví dụ trước trong chương này. Dưới đây là một vài gợi ý để bạn bắt đầu
Khi bạn đã sẵn sàng để xem giải pháp, hãy tiếp tục đọc. Ít nhất, hãy dành một chút thời gian để xem xét cách bạn tiếp cận vấn đề này Để xác định mỗi câu chuyện cười là duy nhất, trước tiên chúng ta phải sửa đổi truy vấn 899 để truy xuất danh sách các câu chuyện cười từ cơ sở dữ liệu bằng cách truy xuất cột 630 bên cạnh cột 632 719Vòng lặp 611 lưu trữ kết quả cơ sở dữ liệu vào mảng 633 cũng cần được sửa đổi. Thay vì chỉ lưu trữ văn bản của mỗi trò đùa, giờ đây chúng tôi lưu trữ cả ID và văn bản. Một cách để làm điều này là biến mỗi mục trong mảng 633 thành một mảng theo đúng nghĩa của nó 60Hãy nhớ lại rằng nếu bạn đã chuyển sang xử lý các hàng kết quả trong cơ sở dữ liệu của mình bằng vòng lặp 648, điều đó cũng sẽ hoạt động hoàn hảo 61Sau khi vòng lặp này chạy, chúng ta sẽ có mảng 633, trong đó mỗi mục là một mảng kết hợp của hai mục. ID của trò đùa và văn bản của nó. Đối với mỗi trò đùa ( 640), do đó, chúng tôi có thể truy xuất ID của nó ( 641) và văn bản của nó ( 642)Mẫu 634 sẽ được sửa đổi trong bước sau để truy xuất văn bản của từng câu chuyện cười từ cấu trúc mảng mới này và thêm nút Xóa cho mỗi câu chuyện cười 62Những điểm nổi bật của mã cập nhật này được liệt kê dưới đây
Bởi vì chúng không phải là một phần của văn bản được trích dẫn, nên các thẻ biểu mẫu và đầu vào phải nằm ngoài phần tử blockquote, nếu bạn đã quen thuộc với HTML Biểu mẫu và thông tin đầu vào của nó phải thực sự xuất hiện trước hoặc sau blockquote, nói một cách chính xác. Thật không may, làm cho cấu trúc thẻ đó hiển thị rõ ràng cần một chút mã CSS (biểu định kiểu xếp tầng) thực sự nằm ngoài phạm vi của cuốn sách này Nếu bạn có ý định sử dụng mã này trong thế giới thực, bạn nên đầu tư thời gian vào việc học CSS (hoặc ít nhất là bảo mật các dịch vụ của chuyên gia CSS) hơn là dạy bạn các kỹ thuật bố cục CSS trong một cuốn sách về PHP và MySQL. Bằng cách này, bạn hoàn toàn có thể kiểm soát đánh dấu HTML của mình mà không phải lo lắng về CSS cần thiết để làm cho nó trông đẹp mắt. Để biết thêm thông tin về bố cục CSS, hãy xem Tiffany Brown's CSS Master, 3rd Edition Để làm cho các nút xuất hiện ở bên phải của trò đùa và tạo một đường giữa chúng, hãy thêm CSS sau vào 302 63Danh sách trò đùa với các nút Xóa được thêm vào có thể được nhìn thấy trong hình ảnh sau Nhưng chờ đã, chúng ta hãy lùi lại một chút và kiểm tra cẩn thận dòng này trước khi chúng ta tiến hành thực hiện chức năng của nút Xóa 64 607 cung cấp cho chúng tôi một biến 623 chứa các khóa 630 và 632 cùng với các giá trị tương ứng của chúng và chúng tôi đang sử dụng biến đó để tạo một mảng khác có cùng khóa và giá trịChúng tôi có thể hoàn thành mục tiêu tương tự với mã này, như bạn có thể đã nhận ra 65Nhưng như chúng ta đã biết, điều này cũng có thể đạt được với vòng lặp 648_ 66Mẫu này sử dụng 648 để lặp lại các bản ghi cơ sở dữ liệu và tạo một mảng. Sau đó, chúng tôi lặp qua mảng bằng một vòng lặp 648 khác. Chúng ta chỉ có thể viết điều này_ 67Bây giờ, thay vì là một mảng khi 633 được lặp lại trong mẫu, giờ đây, 633 là một đối tượng 607, tiết kiệm cho chúng tôi một số mã trong khi không ảnh hưởng đến đầu ra. Bộ điều khiển 306 hiện đã hoàn thành và trông như thế này. Thực tế chúng ta hoàn toàn có thể lược bỏ biến 609 và nạp trực tiếp đối tượng 607 vào biến 633_ 68Giờ đây, chúng tôi thậm chí không có vòng lặp 611 lặp qua các bản ghi trong bộ điều khiển mà thay vào đó, chúng tôi lặp lại các bản ghi trực tiếp trong mẫu, tiết kiệm một số mã và làm cho trang thực thi nhanh hơn một chútĐể làm cho nút Xóa mới của chúng tôi hoạt động, chúng tôi cần thêm một 628 có liên quan để đưa ra truy vấn 893 cho cơ sở dữ liệu_ 69MySQL-DeleteJoke chứa mã hoàn chỉnh cho bản cập nhật 306 và 628Như chúng ta đã làm trong phần “Thêm trò đùa” ở đầu chương, chúng ta bắt đầu bằng cách chuẩn bị truy vấn 893 với trình giữ chỗ cho ID trò đùa mà chúng tôi muốn xóaID trò đùa được cung cấp bởi một trường biểu mẫu ẩn mà người dùng không nhìn thấy được, vì vậy bạn có thể nghĩ rằng không cần phải có một câu lệnh được chuẩn bị sẵn trong tình huống này để bảo vệ cơ sở dữ liệu của chúng ta trước các cuộc tấn công SQL injection. Chẳng hạn, có những tiện ích bổ sung cho trình duyệt được sử dụng rộng rãi sẽ làm cho các trường biểu mẫu ẩn hiển thị và có sẵn để người dùng chỉnh sửa, vì vậy tất cả các trường biểu mẫu, kể cả những trường ẩn, cuối cùng đều nằm dưới sự kiểm soát của người dùng. Hãy nhớ rằng bất kỳ giá trị nào do trình duyệt cung cấp cuối cùng đều bị nghi ngờ khi nói đến việc duy trì tính bảo mật cho trang web của bạn Sau đó, chúng tôi liên kết giá trị đã gửi của 675 với trình giữ chỗ đó và thực hiện truy vấn. Sau khi hoàn thành truy vấn, chúng tôi sử dụng PHP_______4622 để yêu cầu trình duyệt gửi yêu cầu mới để xem các câu chuyện cười được cập nhậtGhi chú. nếu bạn tự giải quyết ví dụ này, bản năng đầu tiên của bạn có thể là cung cấp siêu liên kết Xóa cho mỗi trò đùa, thay vì gặp rắc rối khi viết toàn bộ biểu mẫu HTML có chứa nút Xóa cho mỗi trò đùa trên trang. Thật vậy, mã cho một liên kết như vậy sẽ đơn giản hơn nhiều 0Nói cách khác, các siêu liên kết chỉ được sử dụng để liên kết đến nội dung liên quan và không bao giờ được thực hiện các hành động (như xóa một trò đùa). Không bao giờ được thực hiện các hành động do một biểu mẫu có 678 được gửi; Điều này là do các trình duyệt và phần mềm liên quan xử lý các biểu mẫu với 678 khác nhau; . Các biện pháp bảo vệ tương tự đối với việc gửi lại không được trình duyệt cung cấp cho các liên kết và biểu mẫu có chứa 677Các trang trên trang web của bạn sẽ xuất hiện trong kết quả tìm kiếm khi các công cụ tìm kiếm và trình thu thập dữ liệu web khác theo tất cả các liên kết trên trang web của bạn Nếu một siêu liên kết trên trang web của bạn đã xóa một trò đùa, thì trò đùa của bạn có thể bị xóa bất cứ khi nào một công cụ tìm kiếm tìm thấy trang web của bạn nhiệm vụ đã hoàn thànhBạn đã học về Đối tượng dữ liệu PHP (PDO) trong chương này, là một tập hợp các lớp PHP dựng sẵn ( 804, 830 và 607) cho phép bạn tương tác với máy chủ cơ sở dữ liệu MySQL bằng cách tạo các đối tượng và sau đó sử dụng các phương thức của chúng. Bạn cũng đã học các nguyên tắc cơ bản của lập trình hướng đối tượng (OOP), đây không phải là nhiệm vụ dễ dàng đối với người mới bắt đầu sử dụng PHPTrang web dựa trên cơ sở dữ liệu đầu tiên của bạn, đã xuất bản cơ sở dữ liệu 4 trực tuyến và cho phép khách truy cập thêm và xóa các câu chuyện cười, được xây dựng bằng cách sử dụng các đối tượng PDOTheo một cách nào đó, bạn có thể nói rằng chương này đã hoàn thành mục tiêu đã nêu của cuốn sách là hướng dẫn người đọc cách tạo các trang web dựa trên cơ sở dữ liệu. Tôi sẽ chỉ cho bạn cách hoàn thiện khung xương mà bạn đã học cách xây dựng trong chương này trong các chương còn lại của cuốn sách, vì ví dụ trong chương này đương nhiên chỉ bao gồm phần tối thiểu. Chương 5 quay lại cửa sổ SQL Query trong MySQL Workbench. Chúng ta sẽ tìm hiểu cách sử dụng các nguyên tắc cơ sở dữ liệu quan hệ cũng như các truy vấn SQL nâng cao để biểu diễn các loại thông tin phức tạp hơn và khen ngợi khách truy cập vì những trò đùa của họ Chúng tôi hy vọng bạn thích đoạn trích này từ PHP & MySQL. Tập làm Ninja, Phiên bản thứ 7. Cuốn sách đầy đủ có sẵn trên SitePoint Premium và từ các nhà bán lẻ sách và sách điện tử yêu thích của bạn Chia sẻ bài viết nàytom quản gia Một nhà phát triển web và giảng viên đại học, Tom Butler có bằng tiến sĩ về các phương pháp hay nhất về công nghệ phần mềm và thích đánh giá các cách tiếp cận khác nhau để lập trình Bài viết sau đây là một đoạn trích từ PHP & MySQL. Novice to Ninja, Phiên bản thứ 7, hướng dẫn thực hành để tìm hiểu tất cả các công cụ, nguyên tắc và kỹ thuật cần thiết để xây dựng một ứng dụng web chuyên nghiệp. Trong hướng dẫn cuối cùng của loạt bài này, bạn sẽ học cách lấy thông tin được lưu trữ trong cơ sở dữ liệu MySQL và hiển thị nó trên một trang web để mọi người cùng xem.
Đây là nó - nội dung bạn đã đăng ký. Trong chương này, bạn sẽ học cách lấy thông tin được lưu trữ trong cơ sở dữ liệu MySQL và hiển thị nó trên một trang web để mọi người cùng xem. Cho đến giờ, bạn đã viết mã PHP đầu tiên của mình và học những kiến thức cơ bản về MySQL, một công cụ cơ sở dữ liệu quan hệ và PHP, một ngôn ngữ kịch bản phía máy chủ Bây giờ bạn đã sẵn sàng tìm hiểu cách sử dụng các công cụ này cùng nhau để tạo trang web nơi người dùng có thể xem dữ liệu từ cơ sở dữ liệu và thậm chí thêm dữ liệu của riêng họ Ghi chú. như trong Chương 3, tôi đang sử dụng “MySQL” ở đây để chỉ giao thức cơ sở dữ liệu. Các tập lệnh PHP của bạn sẽ làm như vậy. Có rất nhiều tài liệu tham khảo trong chương này — và trong mã PHP mà bạn sẽ viết — đến “MySQL”, mặc dù chúng ta thực sự đang kết nối với cơ sở dữ liệu MariaDB Bức tranh lớnTrước khi tiến về phía trước, bạn nên lùi lại một bước để có một bức tranh rõ ràng về mục tiêu cuối cùng của mình. Chúng tôi có hai công cụ mạnh mẽ theo ý của chúng tôi. ngôn ngữ kịch bản PHP và công cụ cơ sở dữ liệu MySQL. Điều quan trọng là phải hiểu những thứ này sẽ khớp với nhau như thế nào Mục đích của việc sử dụng MySQL cho trang web của chúng tôi là cho phép lấy động nội dung từ cơ sở dữ liệu để tạo các trang web để xem trong trình duyệt thông thường. Vì vậy, ở một đầu của hệ thống, bạn có một khách truy cập vào trang web của mình bằng trình duyệt web để yêu cầu một trang. Trình duyệt đó mong muốn nhận lại một tài liệu HTML tiêu chuẩn. Ở đầu bên kia, bạn có nội dung trang web của mình, nằm trong một hoặc nhiều bảng trong cơ sở dữ liệu MySQL chỉ hiểu cách trả lời các truy vấn SQL (lệnh) Như thể hiện trong hình trên, ngôn ngữ kịch bản PHP là ngôn ngữ trung gian nói cả hai ngôn ngữ. Nó xử lý yêu cầu trang và tìm nạp dữ liệu từ cơ sở dữ liệu MySQL bằng cách sử dụng các truy vấn SQL giống như những truy vấn bạn đã sử dụng để tạo một bảng truyện cười trong Chương 3. Sau đó, nó tự động đưa nó ra dưới dạng trang HTML được định dạng đẹp mắt mà trình duyệt mong đợi Để bạn luôn rõ ràng và mới mẻ, đây là điều sẽ xảy ra khi có khách truy cập vào một trang trên trang web của bạn
Tạo tài khoản người dùng MySQLĐể PHP kết nối với máy chủ cơ sở dữ liệu MySQL của bạn, nó sẽ cần sử dụng tên người dùng và mật khẩu. Cho đến nay, tất cả những gì cơ sở dữ liệu trò đùa của bạn chứa là một số điều thú vị, nhưng chẳng bao lâu nó có thể chứa thông tin nhạy cảm như địa chỉ email và các chi tiết riêng tư khác về người dùng trang web của bạn. Vì lý do này, MySQL được thiết kế rất an toàn, cho phép bạn kiểm soát chặt chẽ những kết nối nào nó sẽ chấp nhận và những kết nối đó được phép làm gì Môi trường Docker đã chứa người dùng MySQL trong Chương 3, mà bạn đã sử dụng để đăng nhập vào máy chủ MySQL Bạn có thể kết nối với cơ sở dữ liệu từ tập lệnh PHP của mình bằng cùng tên người dùng ( 2) và mật khẩu ( 2), nhưng sẽ rất hữu ích nếu bạn tạo một tài khoản mới — bởi vì nếu bạn có máy chủ web, bạn có thể muốn sử dụng nó để lưu trữ nhiều hơn . Bằng cách cung cấp cho mỗi trang web tài khoản người dùng của riêng mình, bạn sẽ có nhiều quyền kiểm soát hơn đối với những người có quyền truy cập vào dữ liệu cho bất kỳ trang web cụ thể nào. Nếu bạn đang làm việc với các nhà phát triển khác, bạn có thể cấp cho họ quyền truy cập vào các trang web mà họ đang làm việc, nhưng không còn nữaBạn nên tạo một tài khoản người dùng mới chỉ với các đặc quyền cụ thể mà nó cần để hoạt động trên cơ sở dữ liệu 4 mà trang web của bạn phụ thuộc vào. Hãy làm điều đó ngay bây giờĐể tạo người dùng, hãy mở MySQL Workbench và kết nối với máy chủ của bạn. Sau đó chạy các truy vấn sau
Truy vấn đầu tiên khá dễ hiểu. Nó tạo một người dùng có tên là 5 với mật khẩu 6. Dấu hiệu 7 sau tên người dùng cho biết cơ sở dữ liệu có thể được kết nối từ bất kỳ vị trí nào. Truy vấn thứ hai cung cấp cho người dùng quyền truy cập đầy đủ vào lược đồ 4, kết quả là người dùng này có thể xem và sửa đổi tất cả các bảng, cột và dữ liệu trong lược đồ 4 nhưng không có quyền truy cập vào bất kỳ thứ gì bên ngoài nóBây giờ người dùng 5 đã được tạo, chúng ta có thể sử dụng nó để kết nối với cơ sở dữ liệu. Có thể thiết lập kết nối trong MySQL Workbench với người dùng này, nhưng vì quyền hạn bị hạn chế nên tốt hơn hết là giữ MySQL Workbench bằng tài khoản 2. Thay vào đó, chúng tôi sẽ sử dụng người dùng mới khi kết nối từ tập lệnh PHPKết nối với MySQL bằng PHPTrước khi bạn có thể truy xuất nội dung từ cơ sở dữ liệu MySQL của mình để đưa vào trang web, bạn phải biết cách thiết lập kết nối với MySQL từ bên trong tập lệnh PHP. Cho đến giờ, bạn đã sử dụng một ứng dụng có tên là MySQL Workbench để kết nối với cơ sở dữ liệu của mình. Giống như MySQL Workbench có thể kết nối trực tiếp với máy chủ MySQL đang chạy, các tập lệnh PHP của riêng bạn cũng vậy Mặc dù chương này hoàn toàn nói về việc kết nối với MySQL từ PHP, nhưng chúng tôi thực sự đang kết nối với cơ sở dữ liệu MariaDB đã thảo luận trong chương trước. PHP không thể thấy bất kỳ sự khác biệt nào giữa MySQL và MariaDB, vì chúng có thể hoán đổi cho nhau. Tôi sẽ gọi cơ sở dữ liệu là MySQL xuyên suốt, bởi vì tất cả các lệnh được sử dụng có thể được sử dụng để kết nối với máy chủ cơ sở dữ liệu MySQL hoặc MariaDB Cơ sở dữ liệu MySQL ban đầu đã cung cấp một phương pháp tiêu chuẩn hóa cho các máy khách như MySQL Workbench và PHP để giao tiếp với máy chủ. MariaDB đã sao chép tiêu chuẩn đó và tất cả các lệnh trong PHP đều sử dụng tên MySQL, vì vậy để đơn giản, tôi sẽ sử dụng thuật ngữ MySQL trong suốt chương này để chỉ cơ sở dữ liệu Có ba phương pháp kết nối với máy chủ MySQL từ PHP
Về cơ bản, tất cả đều thực hiện cùng một công việc — kết nối với cơ sở dữ liệu và gửi truy vấn đến nó — nhưng chúng sử dụng mã khác nhau để đạt được điều đó Thư viện MySQL là phương pháp kết nối cơ sở dữ liệu lâu đời nhất và được giới thiệu trong PHP 2. 0. Các tính năng mà nó chứa là tối thiểu và nó đã được thay thế bởi MySQLi kể từ PHP 5. 0 (phát hành năm 2004) Để kết nối và truy vấn cơ sở dữ liệu bằng thư viện MySQL cũ, các chức năng như 782 và 783 được sử dụng. Các chức năng này không được dùng nữa — nghĩa là nên tránh sử dụng chúng — kể từ PHP 5. 5 và đã bị xóa hoàn toàn khỏi PHP kể từ PHP 7. 0Mặc dù hầu hết các nhà phát triển đã thấy lý do của sự thay đổi ngay khi PHP 5. 0 đã được phát hành, vẫn còn hàng trăm bài báo và ví dụ mã trên Web sử dụng các hàm 784 hiện không tồn tại này - mặc dù thực tế là MySQLi đã thực sự là thư viện ưa thích trong mười lăm nămNếu bạn bắt gặp một ví dụ mã có chứa dòng 782, hãy kiểm tra ngày của bài viết. Có thể là từ đầu những năm 2000, và trong lập trình, bạn không bao giờ nên tin bất cứ thứ gì cũ kỹ như vậy. Mọi thứ luôn thay đổi - đó là lý do tại sao cuốn sách này được tái bản lần thứ bảyTrong PHP5. 0, thư viện MySQLi — viết tắt của “MySQL Cải tiến” — đã được phát hành để giải quyết một số hạn chế trong thư viện MySQL gốc. Bạn có thể dễ dàng xác định việc sử dụng MySQLi, vì mã sẽ sử dụng các chức năng như 786 và 787Ngay sau khi phát hành thư viện MySQLi trong PHP 5. 0, PHP5. 1 đã được phát hành, với một số thay đổi đáng kể giúp định hình cách chúng ta viết PHP ngày nay (chủ yếu liên quan đến lập trình hướng đối tượng, mà bạn sẽ thấy nhiều ở phần sau của cuốn sách này). Một trong những thay đổi lớn trong PHP 5. Thứ nhất là nó đã giới thiệu một thư viện thứ ba, PDO (PHP Data Objects), để kết nối với cơ sở dữ liệu MySQL Có một số khác biệt giữa PDO và MySQLi, nhưng điểm chính là bạn có thể sử dụng thư viện PDO để kết nối với hầu hết mọi máy chủ cơ sở dữ liệu — chẳng hạn như máy chủ Oracle hoặc Microsoft SQL Server. Đối với các nhà phát triển, lợi thế lớn nhất của cách tiếp cận chung này là khi bạn đã học cách sử dụng thư viện để tương tác với cơ sở dữ liệu MySQL, thì việc tương tác với một máy chủ cơ sở dữ liệu khác sẽ rất đơn giản. Có thể cho rằng, việc viết mã cho PDO đơn giản hơn và có một số sắc thái có thể làm cho mã PDO dễ đọc hơn — các tham số được đặt tên trong các câu lệnh đã chuẩn bị là lợi ích chính. (Đừng lo lắng, tôi sẽ giải thích điều đó có nghĩa là gì sau. ) Vì những lý do này, hầu hết các dự án PHP gần đây đều sử dụng thư viện PDO và đó là thư viện mà tôi sẽ chỉ cho bạn cách sử dụng trong cuốn sách này. Để biết thêm thông tin về sự khác biệt, hãy xem bài viết của SitePoint “Giới thiệu lại PDO – Cách phù hợp để truy cập cơ sở dữ liệu trong PHP” Sau bài học lịch sử nhỏ đó, có lẽ bạn rất muốn quay lại viết mã. Đây là cách bạn sử dụng PDO để thiết lập kết nối với máy chủ MySQL 84Bây giờ, hãy coi 788 như một hàm tích hợp sẵn, giống như hàm 789 mà chúng ta đã sử dụng trong Chương 2. Nếu bạn đang nghĩ “Này, các hàm không thể có khoảng trắng trong tên của chúng. ”, bạn thông minh hơn con gấu trung bình và tôi sẽ giải thích chính xác điều gì đang xảy ra ở đây trong giây lát. Trong mọi trường hợp, phải mất ba đối số
Bạn có thể nhớ từ Chương 2 rằng các hàm PHP thường trả về một giá trị khi chúng được gọi. “Hàm” 788 này trả về một giá trị được gọi là đối tượng 8404 xác định kết nối đã được thiết lập. Vì chúng tôi dự định sử dụng kết nối, chúng tôi nên giữ giá trị này bằng cách lưu trữ nó trong một biến. Đây là giao diện của nó, với các giá trị cần thiết được điền vào để kết nối với cơ sở dữ liệu của bạn 92Bạn có thể thấy điều gì đang xảy ra với hai đối số cuối cùng. chúng là tên người dùng và mật khẩu bạn đã tạo trước đó trong chương này Đối số đầu tiên phức tạp hơn một chút. Phần 8405 yêu cầu PDO sử dụng cơ sở dữ liệu (còn được gọi là lược đồ) có tên là 4. Mọi truy vấn chạy từ PHP sẽ mặc định là các bảng trong lược đồ đó. 8407 sẽ chọn các bản ghi từ bảng 8408 trong lược đồ 4Ngay cả khi bạn đã quen thuộc với PHP, PDO và MySQL, phần 8410 vẫn có vẻ khó hiểu. Thông thường, đây sẽ là 8411 (chỉ máy tính cục bộ, cùng một máy chạy PHP) hoặc trỏ đến một tên miền cụ thể nơi cơ sở dữ liệu được lưu trữ, chẳng hạn như 8412Tại sao lại là 8410 và 8414 đề cập đến điều gì ở đây? . Nếu bạn kiểm tra tệp 8415 cấu hình máy chủ, dịch vụ cơ sở dữ liệu được gọi là 8414 và trong Docker, một dịch vụ có thể kết nối với dịch vụ khác bằng tên của dịch vụ kiaĐối số sang một bên, điều quan trọng cần thấy ở đây là giá trị được trả về bởi 788 được lưu trữ trong một biến có tên 8418Máy chủ MySQL là một phần mềm hoàn toàn riêng biệt với máy chủ web. Do đó, chúng tôi phải xem xét khả năng máy chủ có thể không khả dụng hoặc không thể truy cập được do mạng ngừng hoạt động hoặc do tổ hợp tên người dùng/mật khẩu bạn cung cấp bị máy chủ từ chối hoặc do bạn quên khởi động máy chủ MySQL của mình. Trong những trường hợp như vậy, 788 sẽ không chạy và sẽ đưa ra một ngoại lệ PHPGhi chú. ít nhất là theo mặc định, PHP có thể được cấu hình sao cho không có ngoại lệ nào được ném ra và đơn giản là nó sẽ không kết nối. Đây không phải là hành vi mong muốn nói chung, vì nó khiến việc tìm ra lỗi sai trở nên khó khăn hơn nhiều Nếu bạn đang thắc mắc "ném một ngoại lệ PHP" có nghĩa là gì, hãy chuẩn bị tinh thần. Bạn sắp khám phá thêm một số tính năng của ngôn ngữ PHP Ngoại lệ PHP là điều xảy ra khi bạn yêu cầu PHP thực hiện một tác vụ và nó không thể thực hiện được. PHP sẽ cố gắng làm những gì nó được yêu cầu, nhưng sẽ thất bại; . Một ngoại lệ ít hơn PHP chỉ bị lỗi với một thông báo lỗi cụ thể. Khi một ngoại lệ được đưa ra, PHP dừng lại. Không có dòng mã nào sau lỗi sẽ được thực thi Là một nhà phát triển có trách nhiệm, công việc của bạn là nắm bắt ngoại lệ đó và làm gì đó để chương trình có thể tiếp tục Ghi chú. nếu bạn không nắm bắt được một ngoại lệ, PHP sẽ ngừng chạy tập lệnh PHP của bạn và hiển thị một thông báo lỗi cực kỳ xấu xí. Thông báo lỗi đó thậm chí sẽ tiết lộ mã của tập lệnh của bạn đã gây ra lỗi. Trong trường hợp này, mã đó chứa tên người dùng và mật khẩu MySQL của bạn, vì vậy điều đặc biệt quan trọng là tránh để người dùng nhìn thấy thông báo lỗi Để bắt ngoại lệ, bạn nên bao quanh mã có thể ném ngoại lệ bằng câu lệnh 8420 09Bạn có thể coi câu lệnh 8420 giống như câu lệnh 8422, ngoại trừ khối mã thứ hai là điều sẽ xảy ra nếu khối mã đầu tiên không chạy đượcBối rối chưa? 12Như bạn có thể thấy, mã này là một câu lệnh 8420. Trong khối 8424 ở trên cùng, chúng tôi cố gắng kết nối với cơ sở dữ liệu bằng cách sử dụng 788. Nếu điều này thành công, chúng tôi lưu trữ đối tượng PDO kết quả trong 8418 để chúng tôi có thể làm việc với kết nối cơ sở dữ liệu mới của mình. Nếu kết nối thành công, biến 8427 được đặt thành thông báo sẽ hiển thị sauĐiều quan trọng, bên trong câu lệnh 8420, bất kỳ mã nào sau khi ném ngoại lệ sẽ không được thực thi. Trong trường hợp này, nếu kết nối với cơ sở dữ liệu đưa ra một ngoại lệ (có thể mật khẩu sai hoặc máy chủ không phản hồi), biến 8427 sẽ không bao giờ được đặt thành “Đã thiết lập kết nối cơ sở dữ liệu”Nếu nỗ lực kết nối cơ sở dữ liệu của chúng tôi không thành công, PHP sẽ đưa ra một 8430, đây là loại ngoại lệ mà 788 ném ra. Do đó, khối 8432 của chúng tôi nói rằng nó sẽ bắt một PDOException (và lưu trữ nó trong một biến có tên là 8433). Bên trong khối đó, chúng tôi đặt biến 8427 để chứa thông báo về những gì đã xảy raTuy nhiên, thông báo lỗi này không đặc biệt hữu ích. Tất cả những gì nó cho chúng tôi biết là PDO không thể kết nối với máy chủ cơ sở dữ liệu. Sẽ tốt hơn nếu có một số thông tin về lý do tại sao lại như vậy — ví dụ: vì tên người dùng và mật khẩu không hợp lệ Biến 8433 chứa thông tin chi tiết về ngoại lệ đã xảy ra, bao gồm thông báo lỗi mô tả sự cố. Chúng ta có thể thêm phần này vào biến đầu ra bằng cách sử dụng phép nối 26Ghi chú. biến 8433 không phải là một chuỗi, mà là một đối tượng. Chúng ta sẽ sớm hiểu điều đó có nghĩa là gì. Tuy nhiên, hiện tại, tất cả những gì bạn cần biết là mã 8437 nhận thông báo lỗi dựa trên ngoại lệ cụ thể đã xảy raGiống như câu lệnh 8422, một trong hai nhánh của câu lệnh 8420 được đảm bảo chạy. Mã trong khối 8424 sẽ thực thi thành công hoặc mã trong khối 8432 sẽ chạy. Bất kể kết nối cơ sở dữ liệu có thành công hay không, sẽ có một thông báo trong biến 8427 — thông báo lỗi hoặc thông báo cho biết kết nối thành côngCuối cùng, bất kể khối 8424 thành công hay khối 8432 chạy, mẫu 8445 đều được bao gồm. Đây là một mẫu chung chỉ hiển thị một số văn bản trên trang 37Mã hoàn chỉnh có thể được tìm thấy trong Ví dụ. MySQL-Kết nối Khi mẫu được bao gồm, nó sẽ hiển thị thông báo lỗi hoặc thông báo “Đã thiết lập kết nối cơ sở dữ liệu” Tôi hy vọng mã nói trên hiện có ý nghĩa với bạn. Vui lòng quay lại phần đầu của phần này và đọc lại tất cả nếu bạn bị lạc, vì có một số khái niệm phức tạp trong đó. Tuy nhiên, khi bạn đã nắm vững mã, có thể bạn sẽ nhận ra rằng tôi vẫn còn để lại một bí ẩn chưa giải thích được. PDO. Chính xác thì 788 là gì, và khi tôi nói nó trả về một “đối tượng PDO”, chính xác thì một đối tượng là gì?Ghi chú. tất cả mã mẫu đã tải xuống bao gồm một lược đồ có tên là 8447 và một người dùng có tên là 8447, do đó bạn có thể chạy nó bất kể bạn gọi lược đồ và người dùng của mình là gì. Tệp chứa cơ sở dữ liệu được cung cấp dưới dạng 8449, bạn có thể nhập tệp nàyNếu bạn sử dụng trình xem mã mẫu dựa trên web được cung cấp, cơ sở dữ liệu 8450 sẽ được tạo khi bạn tải một mẫu nhưng mọi thay đổi đối với giản đồ này sẽ bị mất khi bạn xem một mẫu khác. (Bạn có thể làm mọi thứ rối tung lên và chuyển sang một mẫu khác và quay lại sẽ đặt lại nó, nhưng nếu bạn muốn giữ bất kỳ thay đổi nào bạn đã thực hiện, hãy thực hiện chúng trong lược đồ bạn đã tạo. )Nếu bạn muốn tải dữ liệu mẫu vào lược đồ của mình bằng MySQL Workbench, hãy nhập 8449 từ thư mục 8452 bằng cách chọn Nhập/Khôi phục dữ liệu. Sau đó, chọn Nhập từ tệp độc lập, duyệt đến 8449 và chọn tên lược đồ của bạn trong lược đồ đích mặc định. Nếu bạn đã tạo bất kỳ bảng nào có cùng tên, chúng sẽ bị ghi đè và tất cả các bản ghi sẽ bị mấtKhóa học cấp tốc về lập trình hướng đối tượngBạn có thể nhận thấy từ “đối tượng” bắt đầu len lỏi vào vốn từ vựng của tôi trong phần trước. PDO là phần mở rộng Đối tượng dữ liệu PHP và 788 trả về một đối tượng PDO. Trong phần này, tôi muốn giải thích tất cả các đối tượng là gìCó lẽ bạn đã bắt gặp thuật ngữ lập trình hướng đối tượng (OOP) trong quá trình khám phá PHP hoặc lập trình nói chung của riêng bạn. OOP là một phong cách lập trình tiên tiến đặc biệt phù hợp để xây dựng các chương trình thực sự phức tạp với nhiều phần. Hầu hết các ngôn ngữ lập trình đang sử dụng hiện nay đều hỗ trợ OOP. Một số trong số họ thậm chí yêu cầu bạn làm việc theo kiểu OOP. PHP dễ tính hơn một chút và để nhà phát triển quyết định có viết tập lệnh của họ theo kiểu OOP hay không Cho đến nay, chúng ta đã viết mã PHP của mình theo một phong cách đơn giản hơn được gọi là lập trình thủ tục và hiện tại chúng ta sẽ tiếp tục làm như vậy, với một cái nhìn chi tiết hơn về các đối tượng sau này. Phong cách thủ tục rất phù hợp với các dự án tương đối đơn giản mà chúng tôi đang giải quyết vào lúc này. Tuy nhiên, hầu hết tất cả các dự án phức tạp mà bạn gặp đều sử dụng OOP, và tôi sẽ trình bày chi tiết hơn ở phần sau của cuốn sách này Điều đó nói rằng, phần mở rộng PDO mà chúng ta sẽ sử dụng để kết nối và làm việc với cơ sở dữ liệu MySQL được thiết kế theo phong cách lập trình hướng đối tượng. Điều này có nghĩa là, thay vì chỉ gọi một hàm để kết nối với MySQL và sau đó gọi các hàm khác sử dụng kết nối đó, trước tiên chúng ta phải tạo một đối tượng PDO sẽ đại diện cho kết nối cơ sở dữ liệu của chúng ta, sau đó sử dụng các tính năng của đối tượng đó để làm việc với Tạo một đối tượng cũng giống như gọi một hàm. Trên thực tế, bạn đã thấy cách thực hiện 92Từ khóa 8455 cho PHP biết rằng bạn muốn tạo một đối tượng mới. Sau đó, bạn để lại một khoảng trắng và chỉ định tên lớp, tên này sẽ cho PHP biết loại đối tượng bạn muốn tạo. Một lớp là một tập hợp các hướng dẫn mà PHP sẽ tuân theo để tạo một đối tượng. Bạn có thể coi một lớp là một công thức, chẳng hạn như một chiếc bánh và một đối tượng là chiếc bánh thực tế được tạo ra từ việc làm theo công thức. Các lớp khác nhau có thể tạo ra các đồ vật khác nhau, giống như các công thức nấu ăn khác nhau có thể tạo ra các món ăn khác nhauGiống như PHP đi kèm với một loạt các hàm dựng sẵn mà bạn có thể gọi, PHP đi kèm với một thư viện các lớp mà bạn có thể tạo các đối tượng từ đó. Do đó, 788 yêu cầu PHP tạo một đối tượng 8404 mới — nghĩa là một đối tượng mới của lớp 8404 tích hợpTrong PHP, một đối tượng là một giá trị, giống như một chuỗi, số hoặc mảng. Bạn có thể lưu trữ một đối tượng trong một biến hoặc chuyển đối tượng đó vào một hàm dưới dạng đối số — tất cả những điều tương tự mà bạn có thể thực hiện với các giá trị PHP khác. Tuy nhiên, các đối tượng có một số tính năng bổ sung hữu ích Trước hết, một đối tượng hoạt động rất giống một mảng, ở chỗ nó đóng vai trò là nơi chứa các giá trị khác. Như chúng ta đã thấy trong Chương 2, bạn có thể truy cập một giá trị bên trong một mảng bằng cách chỉ định chỉ mục của nó (ví dụ: 8459). Khi nói đến các đối tượng, các khái niệm tương tự nhau nhưng tên và mã khác nhau. Thay vì truy cập giá trị được lưu trữ trong một chỉ mục mảng, chúng tôi nói rằng chúng tôi đang truy cập một thuộc tính của đối tượng. Thay vì sử dụng dấu ngoặc vuông để chỉ định tên của thuộc tính chúng tôi muốn truy cập, chúng tôi sử dụng ký hiệu mũi tên ( 8460) — ví dụ: 8461
Trong khi mảng thường được sử dụng để lưu trữ danh sách các giá trị tương tự (chẳng hạn như mảng ngày sinh), các đối tượng được sử dụng để lưu trữ danh sách các giá trị có liên quan (ví dụ: thuộc tính của kết nối cơ sở dữ liệu). Tuy nhiên, nếu đó là tất cả các đối tượng đã làm, sẽ không có nhiều điểm cho chúng. chúng ta cũng có thể sử dụng một mảng để lưu trữ các giá trị này, phải không? Ngoài việc lưu trữ một tập hợp các thuộc tính và giá trị của chúng, các đối tượng có thể chứa một nhóm các chức năng được thiết kế để mang lại cho chúng ta nhiều tính năng hữu ích hơn. Một hàm được lưu trữ trong một đối tượng được gọi là một phương thức (một trong những cái tên khó hiểu hơn trong thế giới lập trình, nếu bạn hỏi tôi). Một phương thức chỉ là một chức năng bên trong một lớp. Khó hiểu hơn, khi chúng ta bắt đầu viết các lớp của riêng mình, các phương thức được định nghĩa bằng từ khóa 8462. Ngay cả những nhà phát triển có kinh nghiệm cũng thường sử dụng sai hàm và phương thức thay thế cho nhauĐể gọi một phương thức, chúng ta lại sử dụng ký hiệu mũi tên — 8463 78Cũng giống như các hàm độc lập, các phương thức có thể nhận đối số và trả về giá trị Ở giai đoạn này, điều này có lẽ nghe hơi phức tạp và vô nghĩa, nhưng hãy tin tôi. tập hợp các tập hợp biến (thuộc tính) và hàm (phương thức) lại với nhau thành các gói nhỏ được gọi là đối tượng dẫn đến mã gọn gàng hơn và dễ đọc hơn cho một số tác vụ nhất định - làm việc với cơ sở dữ liệu chỉ là một trong số chúng. Một ngày nào đó, bạn thậm chí có thể muốn phát triển các lớp tùy chỉnh mà bạn có thể sử dụng để tạo các đối tượng do chính bạn nghĩ ra. Tuy nhiên, hiện tại, chúng tôi sẽ gắn bó với các lớp đi kèm với PHP. Hãy tiếp tục làm việc với đối tượng 8404 mà chúng ta đã tạo và xem chúng ta có thể làm gì bằng cách gọi một trong các phương thức của nóĐịnh cấu hình kết nốiCho đến giờ, tôi đã chỉ cho bạn cách tạo đối tượng 8404 để thiết lập kết nối với cơ sở dữ liệu MySQL của bạn và cách hiển thị thông báo lỗi có ý nghĩa khi xảy ra sự cố 840Tuy nhiên, giả sử kết nối thành công, bạn cần định cấu hình trước khi sử dụng. Bạn có thể định cấu hình kết nối của mình bằng cách gọi một số phương thức của đối tượng 8404 mới của bạnTrước khi gửi truy vấn đến cơ sở dữ liệu, chúng tôi sẽ cần định cấu hình mã hóa ký tự của kết nối cơ sở dữ liệu của chúng tôi. Như tôi đã đề cập ngắn gọn trong Chương 2, bạn nên sử dụng văn bản được mã hóa UTF-8 trong trang web của mình để tối đa hóa phạm vi ký tự mà người dùng có thể tùy ý sử dụng khi điền vào biểu mẫu trên trang web của bạn. Theo mặc định, khi PHP kết nối với MySQL, nó sử dụng mã hóa ISO-8859-1 (hoặc Latin-1) đơn giản hơn thay vì UTF-8. Nếu chúng tôi để nó như vậy, chúng tôi sẽ không thể dễ dàng chèn các ký tự tiếng Trung, tiếng Ả Rập hoặc hầu hết các ký tự không phải tiếng Anh Ngay cả khi bạn chắc chắn 100% rằng trang web của bạn sẽ chỉ được sử dụng bởi những người nói tiếng Anh, vẫn có những vấn đề khác do không đặt bộ ký tự. Nếu trang web của bạn không được đặt thành UTF-8, bạn sẽ gặp sự cố khi mọi người viết một số ký tự nhất định, chẳng hạn như dấu ngoặc kép 8467 vào hộp văn bản, vì chúng sẽ xuất hiện trong cơ sở dữ liệu dưới dạng một ký tự khácDo đó, bây giờ chúng ta cần đặt đối tượng 8404 mới của mình để sử dụng mã hóa UTF-8Chúng ta có thể hướng dẫn PHP sử dụng UTF-8 khi truy vấn cơ sở dữ liệu bằng cách thêm 8469 vào chuỗi kết nối. Không có nhược điểm nào khi thực hiện việc này, miễn là tập lệnh PHP của bạn cũng đang được gửi tới trình duyệt dưới dạng 8470 (là mặc định trong các phiên bản PHP gần đây) 841Ghi chú. nếu bạn tìm kiếm, bạn sẽ tìm thấy nhiều cách khác nhau để đặt bộ ký tự và các ấn bản trước của cuốn sách này đã hướng dẫn bạn sử dụng mã này 842Điều này là do, cho đến PHP 5. 3. 6, tùy chọn bộ ký tự không được PHP áp dụng chính xác. Vì điều này đã được khắc phục trong bất kỳ phiên bản PHP nào mà bạn thực sự sẽ sử dụng, nên việc đặt bộ ký tự như một phần của chuỗi kết nối là tùy chọn ưu tiên Mã hoàn chỉnh mà chúng tôi sử dụng để kết nối với MySQL và sau đó định cấu hình kết nối đó, do đó, được hiển thị bên dưới Thí dụ. MySQL-Kết nối-Hoàn thành 843Kích hoạt ví dụ này trong trình duyệt của bạn. (Nếu bạn đã đặt mã cơ sở dữ liệu của mình vào 8471 bên trong thư mục 8472 và tệp 8445 trong thư mục 8474, thì URL của trang sẽ là 8475. )Nếu máy chủ của bạn đang hoạt động và mọi thứ đều hoạt động bình thường, bạn sẽ thấy thông báo cho biết thành công Nếu PHP không thể kết nối với máy chủ MySQL của bạn hoặc nếu tên người dùng và mật khẩu bạn cung cấp không chính xác, thay vào đó, bạn sẽ thấy một màn hình tương tự như hiển thị bên dưới. Để đảm bảo mã xử lý lỗi của bạn hoạt động bình thường, bạn có thể cố ý viết sai chính tả mật khẩu của mình để kiểm tra mật khẩu Nhờ khối 8432 của chúng tôi, thông báo lỗi từ cơ sở dữ liệu đã được đưa vào trang 844Phương thức 8477 trả về một thông báo mô tả ngoại lệ đã xảy ra. Có một số phương thức khác — bao gồm 8478 và 8479 — để trả về tên tệp và số dòng mà ngoại lệ đã được ném vào. Bạn có thể tạo một thông báo lỗi rất chi tiết như thế này 845Điều này cực kỳ hữu ích nếu bạn có một trang web lớn với hàng tá tệp bao gồm. Thông báo lỗi sẽ cho bạn biết chính xác tập tin nào cần xem và lỗi xảy ra trên dòng nào Nếu bạn tò mò, hãy thử chèn một số lỗi khác vào mã kết nối cơ sở dữ liệu của bạn (ví dụ: tên cơ sở dữ liệu sai chính tả) và quan sát các thông báo lỗi chi tiết dẫn đến. Khi bạn hoàn tất và kết nối cơ sở dữ liệu của bạn hoạt động bình thường, hãy quay lại thông báo lỗi đơn giản. Bằng cách này, khách truy cập của bạn sẽ không bị tấn công bởi kỹ thuật gobbledygook nếu có sự cố thực sự xảy ra với máy chủ cơ sở dữ liệu của bạn Với kết nối được thiết lập và cơ sở dữ liệu được chọn, bạn đã sẵn sàng bắt đầu sử dụng dữ liệu được lưu trữ trong cơ sở dữ liệu Bạn có thể thắc mắc điều gì sẽ xảy ra với kết nối với máy chủ MySQL sau khi tập lệnh thực thi xong. Nếu bạn thực sự muốn, bạn có thể buộc PHP ngắt kết nối khỏi máy chủ bằng cách loại bỏ đối tượng 8404 đại diện cho kết nối của bạn. Bạn làm điều này bằng cách đặt biến chứa đối tượng thành 8481 846Điều đó nói rằng, PHP sẽ tự động đóng mọi kết nối cơ sở dữ liệu đang mở khi nó chạy xong tập lệnh của bạn, vì vậy bạn thường có thể để PHP dọn dẹp sau khi bạn Gửi truy vấn SQL bằng PHPTrong Chương 3, chúng tôi đã kết nối với máy chủ cơ sở dữ liệu MySQL bằng MySQL Workbench, cho phép chúng tôi nhập các truy vấn SQL (lệnh) và xem kết quả của các truy vấn đó ngay lập tức. Đối tượng 8404 cung cấp một cơ chế tương tự — phương thức exec 847Ở đây, 8483 là một chuỗi chứa bất kỳ truy vấn SQL nào bạn muốn thực hiệnNhư bạn đã biết, nếu có sự cố khi thực thi truy vấn (ví dụ: nếu bạn mắc lỗi đánh máy trong truy vấn SQL của mình), phương thức này sẽ đưa ra một 8430 để bạn bắtXem xét ví dụ sau, ví dụ này cố gắng tạo ra bảng trò đùa mà chúng ta đã tạo trong Chương 3 Thí dụ. MySQL-Tạo 848Lưu ý rằng chúng tôi sử dụng cùng một kỹ thuật câu lệnh 8420 để xử lý các lỗi có thể do truy vấn tạo ra. Có thể sử dụng nhiều khối 8420 để hiển thị các thông báo lỗi khác nhau — một cho kết nối và một cho truy vấn — nhưng điều này có thể dẫn đến một lượng mã bổ sung đáng kểThay vào đó, tôi đã chọn sử dụng cùng một câu lệnh 8424 để chứa cả kết nối và truy vấn. Khối 8420 sẽ ngừng thực thi mã sau khi xảy ra lỗi, vì vậy nếu xảy ra lỗi trong quá trình kết nối cơ sở dữ liệu, dòng 8489 sẽ không bao giờ chạy, đảm bảo rằng, nếu một truy vấn được gửi đến cơ sở dữ liệu, kết nối phải được thiết lậpCách tiếp cận này giúp chúng tôi kiểm soát ít hơn một chút đối với thông báo lỗi được hiển thị nhưng tiết kiệm được việc nhập câu lệnh 8420 cho mỗi thao tác cơ sở dữ liệu. Ở phần sau của cuốn sách này, chúng ta sẽ chia chúng thành các khối khác nhau, nhưng hiện tại, hãy giữ tất cả các thao tác cơ sở dữ liệu trong cùng một khối 8424Ví dụ này cũng sử dụng phương thức 8492 để truy xuất thông báo lỗi chi tiết từ máy chủ MySQL. Hình ảnh sau đây cho thấy lỗi được hiển thị, chẳng hạn như khi bảng trò đùa đã tồn tạiĐối với các truy vấn 8493, 8494 và 8495 (dùng để sửa đổi dữ liệu được lưu trữ), phương thức 8496 trả về số lượng hàng của bảng (mục nhập) bị ảnh hưởng bởi truy vấn. Hãy xem xét lệnh SQL sau, mà chúng ta đã sử dụng trong Chương 3 để đặt ngày của tất cả các trò đùa có chứa từ “lập trình viên”Thí dụ. Cập nhật MySQL 849Bằng cách lưu trữ giá trị được trả về từ phương thức exec trong 8497, chúng ta có thể sử dụng biến trong biến 8427 để in trong mẫuHình ảnh bên dưới hiển thị đầu ra của ví dụ này, giả sử chỉ có một trò đùa "lập trình viên" trong cơ sở dữ liệu của bạn Nếu bạn làm mới trang để chạy lại cùng một truy vấn, bạn sẽ thấy thông báo thay đổi, như thể hiện trong hình ảnh sau. Nó chỉ ra rằng không có hàng nào được cập nhật, vì ngày mới được áp dụng cho truyện cười giống với ngày hiện tại Các truy vấn 8499 được xử lý hơi khác một chút, vì chúng có thể truy xuất rất nhiều dữ liệu và PHP cung cấp các cách để xử lý thông tin đóXử lý Tập kết quả CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%'; 8499Đối với hầu hết các truy vấn SQL, phương thức 8496 hoạt động tốt. Truy vấn thực hiện điều gì đó với cơ sở dữ liệu của bạn và bạn nhận được số hàng bị ảnh hưởng (nếu có) từ giá trị trả về của phương thức. Tuy nhiên, các truy vấn 8499 yêu cầu thứ gì đó phức tạp hơn một chút so với 8496. Bạn sẽ nhớ lại rằng truy vấn 8499 được sử dụng để xem dữ liệu được lưu trữ trong cơ sở dữ liệu. Thay vì chỉ ảnh hưởng đến cơ sở dữ liệu, truy vấn 8499 có kết quả — và chúng tôi cần một phương thức để trả về chúngPhương thức truy vấn trông giống như 8496, ở chỗ nó chấp nhận truy vấn SQL làm đối số để gửi đến máy chủ cơ sở dữ liệu. Tuy nhiên, những gì nó trả về là một đối tượng 9207, đại diện cho một tập hợp kết quả chứa danh sách tất cả các hàng (mục nhập) được trả về từ truy vấn 920Với điều kiện là không gặp lỗi trong quá trình xử lý truy vấn, mã này sẽ lưu trữ một tập kết quả (ở dạng đối tượng 9207) vào biến 9209. Tập hợp kết quả này chứa văn bản của tất cả các truyện cười được lưu trữ trong bảng 8408. Vì không có giới hạn thực tế về số lượng truyện cười trong cơ sở dữ liệu nên tập hợp kết quả có thể khá lớnTôi đã đề cập ở Chương 2 rằng vòng lặp 9211 là một cấu trúc điều khiển hữu ích khi chúng ta cần lặp nhưng không biết bao nhiêu lần. Chúng tôi không thể sử dụng vòng lặp 9212 vì chúng tôi không biết truy vấn đã trả về bao nhiêu bản ghi. Thật vậy, bạn có thể sử dụng vòng lặp 9211 tại đây để xử lý từng hàng trong tập kết quả 921Điều kiện cho vòng lặp 9211 có thể khác với các điều kiện bạn đã từng sử dụng, vì vậy hãy để tôi giải thích cách thức hoạt động của nó. Hãy coi điều kiện là một tuyên bố của chính nó 922Phương thức 9215 của đối tượng 9207 trả về hàng tiếp theo trong tập kết quả dưới dạng một mảng (chúng ta đã thảo luận về mảng trong Chương 2). Khi không còn hàng nào trong tập kết quả, thay vào đó, 9215 trả về 9218. (Đây là một trường hợp khi yêu cầu một đối tượng PDO làm điều gì đó mà nó không thể làm - như 9215 không thể trả về hàng tiếp theo khi không còn hàng nào trong tập kết quả - sẽ không đưa ra kết quả 8430. Nếu đúng như vậy, chúng ta sẽ không thể sử dụng phương thức 9215 trong điều kiện vòng lặp 9211 như cách chúng ta làm ở đây. )Bây giờ, câu lệnh trên gán một giá trị cho biến 9223, nhưng đồng thời, toàn bộ câu lệnh sẽ nhận cùng giá trị đó. Đây là thứ cho phép bạn sử dụng câu lệnh như một điều kiện trong vòng lặp 9211. Vì vòng lặp 9211 sẽ tiếp tục lặp cho đến khi điều kiện của nó ước tính thành 9218, vòng lặp này sẽ xảy ra nhiều lần khi có các hàng trong tập kết quả, với ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _. Tất cả những gì còn lại để tìm ra là làm thế nào để lấy các giá trị ra khỏi biến 9223 mỗi khi vòng lặp chạyCác hàng của tập kết quả được trả về bởi 9215 được biểu diễn dưới dạng mảng kết hợp, với các chỉ số được đặt tên theo các cột của bảng trong tập kết quả. Nếu 9223 là một hàng trong tập hợp kết quả của chúng tôi, thì 9231 là giá trị trong cột 9232 của hàng đóMục tiêu của chúng tôi trong mã này là lưu trữ văn bản của tất cả các câu chuyện cười để chúng tôi có thể hiển thị chúng trong một mẫu PHP. Cách tốt nhất để làm điều này là lưu trữ mỗi trò đùa dưới dạng một mục mới trong một mảng, 9233 923Với những câu chuyện cười được lấy ra khỏi cơ sở dữ liệu, giờ đây chúng ta có thể chuyển chúng sang một mẫu PHP 9234Tóm lại, đây là mã của bộ điều khiển cho ví dụ này cho đến nay 924Biến 9233 là một mảng lưu trữ danh sách truyện cười. Nếu bạn viết ra nội dung của mảng trong PHP, nó sẽ giống như thế này 925Tuy nhiên, dữ liệu đã được lấy từ cơ sở dữ liệu chứ không phải được nhập thủ công trong mã Bạn sẽ nhận thấy rằng có hai biến khác nhau đang được đặt — 9233 và 9237 — tùy thuộc vào việc khối 8424 có được thực thi thành công hay khôngTrong mẫu 9234, chúng ta cần hiển thị nội dung của mảng 9233 hoặc thông báo lỗi chứa trong biến 9237Để kiểm tra xem một biến đã được gán giá trị hay chưa, chúng ta có thể sử dụng hàm 9242 mà chúng ta đã sử dụng trước đó để kiểm tra xem một biểu mẫu đã được gửi hay chưa. Mẫu có thể bao gồm một câu lệnh 9243 để xác định xem nên hiển thị lỗi hay danh sách truyện cười 926Không có gì mới ở đây, nhưng để hiển thị các câu chuyện cười, chúng ta cần hiển thị nội dung của mảng 9233. Không giống như các biến khác mà chúng ta đã sử dụng cho đến thời điểm này, mảng 9233 không chỉ chứa một giá trị đơn lẻCách phổ biến nhất để xử lý mảng trong PHP là sử dụng vòng lặp. Chúng ta đã thấy các vòng lặp 9211 và vòng lặp 9212. Vòng lặp 9248 đặc biệt hữu ích để xử lý mảng 927Thay vì một điều kiện, các dấu ngoặc đơn ở đầu vòng lặp 9248 chứa một mảng, theo sau là từ khóa 9250, sau đó là tên của một biến mới sẽ lần lượt được sử dụng để lưu trữ từng mục của mảng. Phần thân của vòng lặp sau đó được thực hiện một lần cho mỗi mục trong mảng. Mỗi khi mục đó được lưu trữ trong biến đã chỉ định, để mã có thể truy cập trực tiếp vào mục đóNgười ta thường sử dụng vòng lặp 9248 trong mẫu PHP để hiển thị lần lượt từng mục của một mảng. Đây là cách nó có thể tìm kiếm mảng 9233 của chúng tôi 928Với sự pha trộn giữa mã PHP để mô tả vòng lặp và mã HTML để hiển thị nó, mã trông khá lộn xộn. Do đó, người ta thường sử dụng một cách khác để viết vòng lặp 9248 khi nó được sử dụng trong một mẫu 929Hai đoạn mã giống hệt nhau về mặt chức năng, nhưng phần sau trông thân thiện hơn khi trộn với mã HTML. Đây là hình thức mã này trông như thế nào trong một mẫu 090Điều tương tự có thể được thực hiện với câu lệnh 9243, làm cho nó đẹp hơn khi xem các mẫu HTML bên trong bằng cách tránh các dấu ngoặc nhọn 091Với những công cụ mới này trong tay, chúng ta có thể viết mẫu của mình để hiển thị danh sách truyện cười Thí dụ. Danh sách MySQLTruyện cười 092Văn bản 9237 được hiển thị trên trang hoặc mỗi câu chuyện cười được hiển thị trong một đoạn văn ( 9256) có trong một trích dẫn khối ( 9257), vì chúng tôi đang trích dẫn tác giả của mỗi câu chuyện cười trong trang này một cách hiệu quảBởi vì truyện cười có thể chứa các ký tự có thể được hiểu là mã HTML (ví dụ: 9258, 9259 hoặc 9260), chúng tôi phải sử dụng 9261 để đảm bảo chúng được dịch sang các thực thể ký tự HTML (nghĩa là 9262, 9263 và 9264) Hình ảnh sau đây cho thấy trang này trông như thế nào khi bạn đã thêm một vài câu chuyện cười vào cơ sở dữ liệu Hãy nhớ cách chúng tôi đã sử dụng vòng lặp 9211 trong bộ điều khiển của mình để tìm nạp từng hàng một trong tập kết quả 9207? 093Hóa ra các đối tượng 9207 được thiết kế để hoạt động giống như các mảng khi bạn chuyển chúng vào vòng lặp 9248. Do đó, bạn có thể đơn giản hóa một chút mã xử lý cơ sở dữ liệu của mình bằng cách sử dụng vòng lặp 9248 thay vì vòng lặp 9211 094Tôi sẽ sử dụng biểu mẫu 9248 gọn gàng hơn này trong phần còn lại của cuốn sách nàyMột công cụ gọn gàng khác mà PHP cung cấp là một cách viết tắt để gọi lệnh 1 — như bạn đã thấy, chúng ta cần sử dụng thường xuyên. Câu lệnh 1 của chúng tôi trông như thế này 095Thay vào đó, chúng ta có thể sử dụng cái này 096Điều này làm chính xác điều tương tự. 9274 có nghĩa là 1 và cung cấp cho bạn cách in biến ngắn hơn một chút. Có một hạn chế đối với điều này, mặc dù. nếu bạn sử dụng 9274, bạn chỉ có thể in. Bạn không thể bao gồm các câu lệnh 9243, câu lệnh 9212, v.v., mặc dù bạn có thể sử dụng phép nối và có thể theo sau nó bằng một lệnh gọi hàmĐây là một mẫu được cập nhật bằng cách sử dụng tiếng vang tốc ký Thí dụ. MySQL-ListJokes-Viết tắt 097Tôi sẽ sử dụng ký hiệu tốc ký khi nó được áp dụng từ thời điểm này trở đi Ghi chú. trong các phiên bản PHP trước 5. 4, ký hiệu tốc ký này yêu cầu bật cài đặt PHP khá phổ biến, do đó, nó không được khuyến khích vì lý do tương thích. Việc sử dụng ký hiệu tốc ký có thể khiến mã của bạn ngừng hoạt động khi di chuyển từ máy chủ đã bật tính năng này sang máy chủ không bật Kể từ PHP 5. 4 (vì vậy bất kỳ phiên bản nào bạn thực sự sẽ gặp trong những ngày này), tiếng vang tốc ký hoạt động bất kể cài đặt PHP, vì vậy bạn có thể sử dụng nó một cách an toàn mà không phải lo lắng rằng nó có thể không hoạt động trên tất cả các máy chủ suy nghĩ trướcTrong ví dụ chúng ta vừa xem, chúng ta đã tạo một mẫu, 9234, chứa tất cả HTML cần thiết để hiển thị trang. Tuy nhiên, khi trang web của chúng tôi phát triển, chúng tôi sẽ thêm nhiều trang hơn. Chúng tôi chắc chắn sẽ muốn có một trang để mọi người có thể thêm các câu chuyện cười vào trang web và chúng tôi cũng sẽ cần một trang chủ với một số văn bản giới thiệu, một trang có chi tiết liên hệ của chủ sở hữu và khi trang web phát triển, thậm chí có thể Tôi đang đi trước một chút ở đây, nhưng nó luôn đáng để xem xét một dự án sẽ phát triển như thế nào. Nếu chúng tôi áp dụng cách tiếp cận mà chúng tôi vừa sử dụng cho 9234 cho phần còn lại của các mẫu — 9281, 9282, 9283, 9284, v.v. — chúng tôi sẽ có rất nhiều mã lặp lạiMỗi trang trên trang web sẽ yêu cầu một mẫu trông giống như thế này 098Là một lập trình viên, lặp lại mã là một trong những điều tồi tệ nhất bạn có thể làm. Trên thực tế, các lập trình viên thường nhắc đến nguyên tắc DRY, viết tắt của cụm từ “Don’t repeat yourself”. Nếu bạn thấy mình lặp lại các đoạn mã, gần như chắc chắn có một giải pháp tốt hơn Tất cả các lập trình viên giỏi nhất đều lười biếng và lặp lại mã có nghĩa là lặp lại công việc. Sử dụng phương pháp sao chép/dán này cho các mẫu khiến trang web rất khó duy trì. Hãy tưởng tượng có một phần chân trang và phần điều hướng mà chúng tôi muốn xuất hiện trên mỗi trang. Các mẫu của chúng tôi bây giờ sẽ trông như thế này 099Chúng ta sẽ gặp sự cố vào năm 2022. Nếu các mẫu cho tất cả các trang trên trang web — ví dụ: 9234 9281, 9282, 9283 và 9284 — chứa mã theo cấu trúc trên, thì để cập nhật năm trong thông báo bản quyền thành “2022”, bạn cần mở từng mẫu trong số đó. Chúng tôi có thể thông minh và có ngày được đọc động từ đồng hồ của máy chủ ( 9290 nếu bạn tò mò. ) để tránh sự cố này, nhưng nếu chúng tôi muốn thêm thẻ 9291 vào mỗi trang thì sao? Thay đổi năm hoặc sáu mẫu có thể hơi khó chịu, nhưng nó sẽ không gây ra nhiều vấn đề. Tuy nhiên, nếu website phát triển lên hàng chục, hàng trăm trang thì sao? Vấn đề này có thể được giải quyết bằng một loạt các câu lệnh 9292. Ví dụ 120Nhưng phương pháp này đòi hỏi phải có khả năng thấu thị. chúng tôi cần dự đoán chính xác những thay đổi nào có thể cần thực hiện trong tương lai và sử dụng các câu lệnh 9292 có liên quan ở những nơi chúng tôi thấy trước những thay đổi sẽ xảy raVí dụ, trong ví dụ trên, thật dễ dàng để thêm các mục nhập menu mới bằng cách thêm chúng vào 9294, nhưng thêm thẻ 9291 vào mọi trang hoặc thậm chí là điều gì đó tầm thường như thêm một lớp CSS vào thành phần 9296, vẫn có nghĩa là mở mọi mẫu Không có cách nào để dự đoán chính xác tất cả những thay đổi có thể cần thiết trong suốt thời gian tồn tại của trang web, vì vậy, thay vào đó, phương pháp tôi đã chỉ cho bạn ở đầu chương này thực sự tốt hơn 121Nếu chúng tôi luôn bao gồm mẫu này, mà chúng tôi sẽ gọi là 9297, thì có thể đặt biến 8427 thành một số mã HTML và để nó xuất hiện trên trang có điều hướng và chân trang. Lợi ích của việc này là để thay đổi ngày trên mọi trang của trang web, chúng tôi chỉ cần thay đổi ngày ở một vị tríTôi cũng đã thêm một biến 9299 để mỗi bộ điều khiển có thể xác định một giá trị xuất hiện giữa các thẻ 0900 và 0901 cùng với một số CSS (có sẵn dưới dạng 0902 trong mã mẫu) để làm cho trang đẹp hơn một chútBất kỳ bộ điều khiển nào hiện có thể sử dụng 0903 và cung cấp các giá trị cho 8427 và 9299 0906 của chúng tôi sử dụng 9297 được mã hóa như hình bên dướiThí dụ. MySQL-ListJokes-Layout-1 122Nhưng đợi đã. Điều gì đang xảy ra với 8427 trong khối 8424? . vòng lặp xây dựng một chuỗi chứa mã HTML cho danh sách truyện cườiVề nguyên tắc, đây là những gì chúng tôi muốn xảy ra. biến 8427 chứa mã HTML sẽ được chèn vào giữa phần điều hướng và chân trang trong 9297, nhưng tôi nghĩ bạn sẽ đồng ý rằng mã này cực kỳ xấuTôi đã chỉ cho bạn cách tránh trộn mã HTML và PHP thông qua câu lệnh 9292. Giống như chúng tôi đã làm trước đó, sẽ rất tốt nếu chuyển HTML để hiển thị truyện cười vào tệp riêng của nó — nhưng lần này, chỉ mã HTML duy nhất cho trang danh sách truyện cười 9234 trong thư mục 8474 phải chứa mã này 123Điều quan trọng, đây chỉ là mã để hiển thị các câu chuyện cười. Nó không chứa điều hướng, chân trang, thẻ 0916 hoặc bất kỳ thứ gì chúng tôi muốn lặp lại trên mỗi trang; Để sử dụng mẫu này, bạn có thể thử như sau 124Hoặc nếu bạn rất thông minh 125Với cách tiếp cận này, logic của bạn sẽ hoàn toàn hợp lý. Chúng ta cần bao gồm 9234. Thật không may, câu lệnh 9292 chỉ thực thi mã từ tệp được bao gồm tại điểm được gọi là. Nếu bạn chạy mã ở trên, đầu ra thực sự sẽ giống như thế này 126Vì 9234 được đưa vào trước nên nó được gửi tới trình duyệt trước. Những gì chúng ta cần làm là tải 9234, nhưng thay vì gửi kết quả trực tiếp đến trình duyệt, chúng ta cần chụp và lưu trữ nó trong biến 8427 để sau này 9297 có thể sử dụng nóCâu lệnh 9292 không trả về giá trị, vì vậy, 0924 không có tác dụng mong muốn và PHP không có câu lệnh thay thế để thực hiện điều đó. Tuy nhiên, điều đó không có nghĩa là không thểPHP có một tính năng hữu ích được gọi là “bộ đệm đầu ra”. Nghe có vẻ phức tạp, nhưng khái niệm này thực sự rất đơn giản. khi bạn sử dụng 1 để in nội dung nào đó hoặc 9292 để bao gồm tệp chứa HTML, thông thường tệp đó sẽ được gửi trực tiếp tới trình duyệt. Bằng cách sử dụng bộ đệm đầu ra, thay vì đầu ra được gửi thẳng đến trình duyệt, mã HTML được lưu trữ trên máy chủ trong một “bộ đệm”, về cơ bản chỉ là một chuỗi chứa mọi thứ đã được in cho đến nayThậm chí tốt hơn, PHP cho phép bạn bật bộ đệm và đọc nội dung của nó bất cứ lúc nào Có hai chức năng chúng ta cần
Như bạn có thể đoán, “ob” trong tên hàm là viết tắt của “bộ đệm đầu ra” Để nắm bắt nội dung của một tệp được bao gồm, chúng ta chỉ cần sử dụng hai chức năng này 127Khi mã này chạy, biến 8427 sẽ chứa HTML được tạo trong mẫu 9234Chúng tôi sẽ sử dụng phương pháp này từ bây giờ. Mỗi trang sẽ được tạo thành từ hai mẫu
Toàn bộ 0906 trông như thế này 128Hãy làm cho liên kết “Trang chủ” hoạt động bằng cách thêm tệp 8471. Chúng tôi có thể đặt bất cứ điều gì trên trang này. truyện cười mới nhất, truyện cười hay nhất trong tháng hoặc bất cứ thứ gì chúng tôi thích. Tuy nhiên, hiện tại, chúng tôi sẽ giữ cho nó đơn giản và chỉ có một thông báo có nội dung “Chào mừng bạn đến với Cơ sở dữ liệu trò đùa trên Internet”Tạo một tệp có tên 9282 trong thư mục 8474 129 8471 của chúng tôi đơn giản hơn nhiều so với 9234. Nó không nhận bất kỳ thông tin nào từ cơ sở dữ liệu, vì vậy nó không cần kết nối cơ sở dữ liệu và chúng tôi không cần câu lệnh 8420, vì vậy chúng tôi sẽ chỉ tải hai mẫu và đặt các biến 9299 và 8427Thí dụ. MySQL-ListJokes-Layout-3 260Ghi chú. thực hành tốt là chỉ kết nối với cơ sở dữ liệu nếu bạn cần. Cơ sở dữ liệu là nút cổ chai hiệu suất phổ biến nhất trên nhiều trang web, do đó, ưu tiên tạo càng ít kết nối càng tốt Kiểm tra xem cả hai trang có hoạt động trong trình duyệt của bạn không. Bạn sẽ thấy một danh sách các câu chuyện cười khi truy cập vào 0943 và thông điệp chào mừng trên 0943. Cả hai trang phải chứa điều hướng và chân trangHãy thử sửa đổi 9297. Những thay đổi bạn thực hiện sẽ xuất hiện trên cả hai trang. Nếu trang web có hàng tá trang, những thay đổi đối với bố cục sẽ ảnh hưởng đến mọi trangChèn dữ liệu vào cơ sở dữ liệuTrong phần này, tôi sẽ trình bày cách sử dụng các công cụ theo ý của bạn để cho phép khách truy cập trang web thêm các câu chuyện cười của riêng họ vào cơ sở dữ liệu Nếu bạn muốn cho phép khách truy cập trang web của mình nhập các câu chuyện cười mới, rõ ràng bạn sẽ cần một biểu mẫu. Đây là một mẫu cho một biểu mẫu sẽ phù hợp với hóa đơn 261Lưu cái này với tên 9281 trong thư mục 8474Phần quan trọng nhất của phần tử 0948 là thuộc tính 0949. Thuộc tính 0949 cho trình duyệt biết nơi gửi dữ liệu sau khi biểu mẫu được gửi. Đây có thể là tên của một tệp, chẳng hạn như 0951Tuy nhiên, nếu bạn để trống thuộc tính bằng cách đặt nó thành 0952, thì dữ liệu do người dùng cung cấp sẽ được gửi trở lại trang bạn đang xem. Nếu URL của trình duyệt hiển thị trang là 0953, thì đó là dữ liệu sẽ được gửi khi người dùng nhấn nút ThêmHãy liên kết biểu mẫu này với ví dụ trước, hiển thị danh sách truyện cười trong cơ sở dữ liệu. Mở 9297 và thêm một URL vào liên kết “Thêm một trò đùa mới” dẫn đến 0953 262Trong khi bạn mở 9297, hãy bao gồm biểu định kiểu 0957 từ Chương 2 như tôi có ở trên. Bây giờ, bất kỳ biểu mẫu nào được hiển thị bên trong bố cục sẽ có các kiểu chúng tôi đã sử dụng trước đâyKhi biểu mẫu này được gửi, yêu cầu sẽ bao gồm một biến — 9232 — chứa văn bản của trò đùa được nhập vào vùng văn bản. Biến này sau đó sẽ xuất hiện trong mảng 0959 được tạo bởi PHPHãy tạo 0953 trong thư mục 8472. Logic cơ bản cho bộ điều khiển này là
Tạo bộ xương này 0953 263Câu lệnh mở đầu 9243 này kiểm tra xem mảng 0959 có chứa biến có tên là 9232 không. Nếu nó được đặt, biểu mẫu đã được gửi. Mặt khác, biểu mẫu từ 9281 được tải vào biến 8427 để hiển thị trên trình duyệtNếu bạn mở 0953 trong trình duyệt của mình vào thời điểm này, bạn sẽ thấy biểu mẫu, nhưng nhập một trò đùa và nhấn Thêm sẽ không hoạt động, vì chúng tôi chưa làm gì với dữ liệu có trong 0970Để chèn câu chuyện cười đã gửi vào cơ sở dữ liệu, chúng ta phải thực hiện truy vấn 8494 sử dụng giá trị được lưu trữ trong 0970 để điền vào cột 9232 của bảng 8408. Điều này có thể khiến bạn viết một số mã như thế này 264Tuy nhiên, có một vấn đề nghiêm trọng với mã này. nội dung của 0970 hoàn toàn nằm dưới sự kiểm soát của người dùng đã gửi biểu mẫu. Nếu một người dùng độc hại nhập một số mã SQL khó chịu vào biểu mẫu, thì tập lệnh này sẽ cung cấp nó cho máy chủ MySQL của bạn mà không cần thắc mắc. Kiểu tấn công này được gọi là tấn công SQL injection và trong những ngày đầu của PHP, đây là một trong những lỗ hổng bảo mật phổ biến nhất mà tin tặc tìm thấy và khai thác trong các trang web dựa trên PHP. (Trong nhiều lĩnh vực lập trình, các cuộc tấn công SQL injection vẫn hiệu quả một cách đáng ngạc nhiên, vì các nhà phát triển không mong đợi chúng. Hãy xem xét nỗ lực đáng chú ý này để khiến các camera giao thông loại bỏ cơ sở dữ liệu của chúng. “Biển số SQL injection hy vọng sẽ phá vỡ camera giao thông châu Âu”. )Người dùng có thể nhập nội dung này vào hộp văn bản 265Truy vấn được gửi đến cơ sở dữ liệu sẽ như sau 266Nhưng nếu người dùng gõ như sau 267Trong trường hợp này, truy vấn được gửi đến cơ sở dữ liệu sẽ là 268Bởi vì trò đùa có chứa ký tự trích dẫn, MySQL sẽ trả về lỗi, vì nó sẽ thấy phần trích dẫn trước “get” ở cuối chuỗi Để biến đây thành một truy vấn hợp lệ, chúng ta cần thoát tất cả các trích dẫn trong văn bản để truy vấn được gửi tới cơ sở dữ liệu trở thành truy vấn này 269Dữ liệu không được chèn nếu nó chứa một trích dẫn là một vấn đề gây khó chịu cho người dùng. Họ sẽ mất bất cứ thứ gì họ đã nhập. Nhưng người dùng độc hại có thể lạm dụng điều này. Trong các phiên bản PHP cũ hơn, có thể chạy nhiều truy vấn từ PHP bằng cách tách chúng bằng dấu chấm phẩy ( 0976)Hãy tưởng tượng nếu người dùng nhập cái này vào hộp 370Điều này sẽ gửi các truy vấn sau đến cơ sở dữ liệu 371 0977 là một dòng nhận xét trong MySQL, vì vậy dòng cuối cùng sẽ bị bỏ qua và truy vấn 8494 sẽ chạy, theo sau là truy vấn 8493 mà người dùng đã nhập vào hộp. Trên thực tế, người dùng có thể nhập bất kỳ truy vấn nào họ thích vào hộp và nó sẽ được chạy trên cơ sở dữ liệuBáo giá ma thuậtTrong những ngày đầu của PHP, các cuộc tấn công SQL injection rất đáng sợ đến nỗi nhóm đằng sau PHP đã thêm một số biện pháp bảo vệ tích hợp chống lại việc tiêm SQL vào ngôn ngữ. Thứ nhất, họ đã vô hiệu hóa khả năng gửi nhiều truy vấn cùng một lúc. Thứ hai, họ đã thêm một thứ gọi là trích dẫn ma thuật. Tính năng bảo vệ này của PHP đã tự động phân tích tất cả các giá trị do trình duyệt gửi và chèn dấu gạch chéo ngược ( 0980) trước bất kỳ ký tự “nguy hiểm” nào như dấu nháy đơn — điều này có thể gây ra sự cố nếu chúng vô tình được đưa vào truy vấn SQLVấn đề với tính năng trích dẫn ma thuật là nó gây ra nhiều vấn đề như nó đã ngăn chặn. Trước hết, các ký tự mà nó phát hiện và phương pháp được sử dụng để khử trùng chúng (đặt trước chúng bằng dấu gạch chéo ngược), chỉ hợp lệ trong một số trường hợp. Tùy thuộc vào mã hóa ký tự của trang web của bạn và máy chủ cơ sở dữ liệu bạn đang sử dụng, các biện pháp này có thể hoàn toàn không hiệu quả Thứ hai, khi một giá trị đã gửi được sử dụng cho một số mục đích khác ngoài việc tạo truy vấn SQL, những dấu gạch chéo ngược đó có thể thực sự khó chịu. Tính năng trích dẫn ma thuật sẽ chèn dấu gạch chéo ngược giả vào họ của người dùng nếu nó chứa dấu nháy đơn Nói tóm lại, tính năng trích dẫn ma thuật là một ý tưởng tồi - đến mức nó đã bị xóa khỏi PHP từ phiên bản 5. 4. Tuy nhiên, do tuổi đời của PHP và số lượng mã hiện có, bạn có thể bắt gặp một số tài liệu tham khảo về nó, vì vậy, bạn nên hiểu cơ bản về chức năng của tính năng trích dẫn ma thuật. Khi các trích dẫn ma thuật được xác định là một ý tưởng tồi, lời khuyên từ các nhà phát triển PHP là tắt nó đi. Tuy nhiên, điều này có nghĩa là có một số máy chủ web bị tắt và những máy chủ khác được bật. Đây là một vấn đề đau đầu cho các nhà phát triển. họ hoặc phải hướng dẫn tất cả những người sẽ sử dụng mã của họ để tắt nó đi — điều này không thể thực hiện được trên một số máy chủ dùng chung — hoặc viết thêm mã để giải thích cho việc đó Hầu hết các nhà phát triển đã chọn cái sau và bạn có thể bắt gặp một số mã như thế này 372Nếu bạn thấy câu lệnh 9243 như thế này trong mã kế thừa mà bạn được giao làm việc, bạn có thể xóa toàn bộ khối một cách an toàn, vì sẽ không có mã nào bên trong câu lệnh 9243 được thực thi trên các phiên bản PHP gần đâyNếu bạn thấy mã như thế này, điều đó có nghĩa là nhà phát triển ban đầu đã hiểu vấn đề với dấu ngoặc kép ma thuật và đang cố gắng hết sức để ngăn chặn điều đó. Kể từ PHP 5. 4 (mà bạn sẽ không bao giờ gặp phải, vì nó không còn được hỗ trợ), 0983 sẽ luôn trả về 9218 và mã sẽ không bao giờ được thực thiTất cả những gì bạn thực sự cần biết về trích dẫn ma thuật là nó là một giải pháp tồi cho vấn đề hiện tại. Tất nhiên, không có trích dẫn ma thuật, bạn cần tìm một giải pháp khác cho vấn đề. May mắn thay, lớp PDO có thể làm tất cả công việc khó khăn cho bạn, bằng cách sử dụng thứ gọi là “câu lệnh chuẩn bị sẵn” báo cáo chuẩn bịMột câu lệnh đã chuẩn bị là một loại truy vấn SQL đặc biệt mà bạn đã gửi trước đến máy chủ cơ sở dữ liệu của mình, giúp máy chủ có cơ hội chuẩn bị để thực thi — nhưng không thực sự thực thi nó. Hãy nghĩ về nó giống như viết một kịch bản 0985. Mã ở đó, nhưng nó không thực sự chạy cho đến khi bạn truy cập trang trong trình duyệt web của mình. Mã SQL trong các câu lệnh đã chuẩn bị có thể chứa các trình giữ chỗ mà bạn sẽ cung cấp các giá trị cho sau này, khi truy vấn được thực thi. Khi điền vào các chỗ dành sẵn này, PDO đủ thông minh để tự động bảo vệ chống lại các ký tự “nguy hiểm”Đây là cách chuẩn bị một truy vấn 8494 và sau đó thực hiện truy vấn đó một cách an toàn với 0970 làm văn bản của trò đùa 373Hãy phá vỡ điều này, một tuyên bố tại một thời điểm. Đầu tiên, chúng tôi viết truy vấn SQL của mình dưới dạng chuỗi PHP và lưu trữ nó trong một biến ( 0988) như bình thường. Tuy nhiên, điều bất thường về truy vấn 8494 này là không có giá trị nào được chỉ định cho cột 9232. Thay vào đó, nó chứa một trình giữ chỗ cho giá trị này (______50991). Đừng lo lắng về trường 0992 vừa rồi; Tiếp theo, chúng tôi gọi phương thức chuẩn bị của đối tượng PDO ( 8418), chuyển truy vấn SQL của chúng tôi dưới dạng đối số. Điều này sẽ gửi truy vấn đến máy chủ MySQL, yêu cầu nó chuẩn bị chạy truy vấn. MySQL chưa thể chạy nó, vì không có giá trị cho cột 9232. Phương thức 0995 trả về một đối tượng 9207 (vâng, cùng loại đối tượng cung cấp cho chúng tôi kết quả từ truy vấn 8499), mà chúng tôi lưu trữ trong 0998Bây giờ MySQL đã chuẩn bị câu lệnh của chúng ta để thực thi, chúng ta có thể gửi (các) giá trị còn thiếu cho nó bằng cách gọi phương thức 0999 của đối tượng 9207 ( 0998). Chúng tôi gọi phương thức này một lần cho mỗi giá trị được cung cấp (trong trường hợp này, chúng tôi chỉ cần cung cấp một giá trị - văn bản trò đùa), chuyển dưới dạng đối số trình giữ chỗ mà chúng tôi muốn điền vào ( 1202) và giá trị chúng tôi muốn điền . Vì MySQL biết chúng tôi đang gửi cho nó một giá trị riêng biệt, thay vì mã SQL cần được phân tích cú pháp, nên không có nguy cơ các ký tự trong giá trị được hiểu là mã SQL. Khi sử dụng các câu lệnh đã chuẩn bị, các lỗ hổng SQL injection đơn giản là không thểCuối cùng, chúng tôi gọi phương thức 1205 của đối tượng 9207 để yêu cầu MySQL thực hiện truy vấn với (các) giá trị mà chúng tôi đã cung cấp. (Có, phương thức 9207 này được gọi là 1205, không giống như phương thức tương tự của các đối tượng 8404, được gọi là 8496. PHP có nhiều điểm mạnh, nhưng tính nhất quán không phải là một trong số đó. )Một điều thú vị mà bạn sẽ nhận thấy về mã này là chúng tôi không bao giờ đặt dấu ngoặc kép xung quanh văn bản trò đùa. 0991 tồn tại bên trong truy vấn mà không có bất kỳ dấu ngoặc kép nào và khi chúng tôi gọi 0999, chúng tôi đã chuyển cho nó văn bản trò đùa đơn giản từ mảng 0959. Khi sử dụng các câu lệnh đã chuẩn bị, bạn không cần trích dẫn vì cơ sở dữ liệu (trong trường hợp của chúng tôi là MySQL) đủ thông minh để biết rằng văn bản là một chuỗi và nó sẽ được xử lý như vậy khi truy vấn được thực thiCâu hỏi còn sót lại trong mã này là cách gán ngày hôm nay cho trường 0992. Chúng ta có thể viết một số mã PHP lạ mắt để tạo ngày hôm nay ở định dạng 1214 mà MySQL yêu cầu, nhưng hóa ra chính MySQL cũng có chức năng để làm điều này — 1215 374Hàm MySQL 1215 được sử dụng ở đây để gán ngày hiện tại làm giá trị của cột 0992. MySQL thực sự có hàng chục chức năng này, nhưng tôi sẽ chỉ giới thiệu chúng khi cần thiếtBây giờ chúng tôi đã có truy vấn của mình, chúng tôi có thể hoàn thành câu lệnh 9243 mà chúng tôi đã bắt đầu trước đó để xử lý việc gửi biểu mẫu “Thêm trò đùa” 375Nhưng đợi đã. Tuyên bố 9243 này có thêm một mánh khóe nữa. Khi chúng tôi đã thêm câu chuyện cười mới vào cơ sở dữ liệu, thay vì hiển thị mẫu PHP như trước đây, chúng tôi muốn chuyển hướng trình duyệt của người dùng trở lại danh sách các câu chuyện cười. Bằng cách đó, người dùng có thể thấy trò đùa mới được thêm vào giữa họ. Đó là những gì hai dòng ở cuối câu lệnh 9243 ở trên làmĐể đạt được kết quả mong muốn, bản năng đầu tiên của bạn có thể là cho phép bộ điều khiển chỉ cần tìm nạp danh sách truyện cười từ cơ sở dữ liệu sau khi thêm truyện cười mới và hiển thị danh sách bằng cách sử dụng mẫu 9234 như bình thường. Vấn đề khi làm điều này là danh sách truyện cười, theo quan điểm của trình duyệt, sẽ là kết quả của việc gửi biểu mẫu “Thêm truyện cười”. Nếu sau đó người dùng làm mới trang, trình duyệt sẽ gửi lại biểu mẫu đó, khiến một bản sao khác của trò đùa mới được thêm vào cơ sở dữ liệu. Đây hiếm khi là hành vi mong muốnThay vào đó, chúng tôi muốn trình duyệt coi danh sách truyện cười được cập nhật như một trang web bình thường có thể tải lại mà không cần gửi lại biểu mẫu. Cách để thực hiện việc này là trả lời biểu mẫu gửi của trình duyệt bằng chuyển hướng HTTP — một phản hồi đặc biệt yêu cầu trình duyệt điều hướng đến một trang khác. (HTTP là viết tắt của HyperText Transfer Protocol, và là ngôn ngữ mô tả thông tin liên lạc yêu cầu/phản hồi được trao đổi giữa trình duyệt web của khách truy cập và máy chủ web của bạn. ) Hàm PHP 1222 cung cấp phương tiện gửi các phản hồi của máy chủ đặc biệt như phản hồi này, bằng cách cho phép bạn chèn các tiêu đề cụ thể vào phản hồi được gửi tới trình duyệt. Để báo hiệu chuyển hướng, bạn phải gửi tiêu đề 1223 với URL của trang mà bạn muốn hướng trình duyệt tới 376Trong trường hợp này, chúng tôi muốn gửi trình duyệt tới 0906. Đây là hai dòng chuyển hướng trình duyệt trở lại bộ điều khiển của chúng tôi sau khi thêm trò đùa mới vào cơ sở dữ liệu 377Dưới đây là mã hoàn chỉnh của bộ điều khiển 0953Thí dụ. MySQL-AddJoke 378Khi bạn xem xét điều này để đảm bảo rằng tất cả đều hợp lý với bạn, hãy lưu ý rằng mã kết nối với cơ sở dữ liệu bằng cách tạo một đối tượng 788 phải xuất hiện trước bất kỳ mã nào chạy truy vấn cơ sở dữ liệu. Nhưng không cần kết nối cơ sở dữ liệu để hiển thị biểu mẫu “Thêm trò đùa”. Kết nối chỉ được thực hiện khi biểu mẫu đã được gửiTải cái này lên và thêm một hoặc hai câu chuyện cười mới vào cơ sở dữ liệu thông qua trình duyệt của bạn Ở đó bạn có nó. bạn có thể xem các truyện cười hiện có trong — và thêm các truyện cười mới vào — cơ sở dữ liệu MySQL của bạn Xóa dữ liệu khỏi cơ sở dữ liệuTrong phần này, chúng tôi sẽ thực hiện một cải tiến cuối cùng cho trang web cơ sở dữ liệu trò đùa của chúng tôi. Bên cạnh mỗi trò đùa trên trang chuyện cười ( 0906), chúng tôi sẽ đặt một nút có nhãn Xóa. Khi click vào sẽ xóa truyện cười đó khỏi cơ sở dữ liệu và hiển thị danh sách truyện cười đã cập nhậtNếu bạn thích một thử thách, bạn có thể muốn tự mình viết tính năng này trước khi đọc tiếp để xem giải pháp của tôi. Mặc dù chúng tôi đang triển khai một tính năng hoàn toàn mới, nhưng chủ yếu chúng tôi sẽ sử dụng các công cụ giống như được sử dụng trong các ví dụ trước trong chương này. Dưới đây là một vài gợi ý để bạn bắt đầu
Ít nhất, hãy dành một chút thời gian để suy nghĩ về cách bạn tiếp cận điều này. Khi bạn đã sẵn sàng để xem giải pháp, hãy đọc tiếp Để bắt đầu, chúng ta cần sửa đổi truy vấn 8499 lấy danh sách truyện cười từ cơ sở dữ liệu. Ngoài cột 9232, chúng tôi cũng phải tìm nạp cột 1230 để có thể xác định từng trò đùa một cách độc đáo 379Chúng tôi cũng phải sửa đổi vòng lặp 9211 lưu kết quả cơ sở dữ liệu vào mảng 9233. Thay vì chỉ lưu trữ văn bản của mỗi trò đùa dưới dạng một mục trong mảng, chúng tôi lưu trữ cả ID và văn bản của mỗi trò đùa. Một cách để làm điều này là biến mỗi mục trong mảng 9233 thành một mảng theo đúng nghĩa của nó 920Ghi chú. nếu bạn đã chuyển sang sử dụng vòng lặp 9248 để xử lý các hàng kết quả cơ sở dữ liệu của mình, điều đó cũng sẽ hoạt động tốt 921Khi vòng lặp này chạy hết, chúng ta sẽ có mảng 9233, mỗi mục trong đó là một mảng kết hợp có hai mục. ID của trò đùa và văn bản của nó. Đối với mỗi trò đùa ( 1240), do đó, chúng tôi có thể truy xuất ID của nó ( 1241) và văn bản của nó ( 1242)Bước tiếp theo của chúng tôi là cập nhật mẫu 9234 để truy xuất văn bản của mỗi câu chuyện cười từ cấu trúc mảng mới này, cũng như cung cấp nút Xóa cho mỗi câu chuyện cười 922Dưới đây là những điểm nổi bật của mã cập nhật này
Ghi chú. nếu bạn biết HTML của mình, có lẽ bạn đang nghĩ rằng các thẻ biểu mẫu và đầu vào nằm ngoài phần tử blockquote, vì chúng không phải là một phần của văn bản được trích dẫn (trò đùa) Nói đúng ra, đó là sự thật. biểu mẫu và đầu vào của nó thực sự phải ở trước hoặc sau blockquote. Thật không may, làm cho cấu trúc thẻ đó hiển thị rõ ràng đòi hỏi một chút mã CSS (cascading style sheet) thực sự nằm ngoài phạm vi của cuốn sách này Thay vì dạy bạn các kỹ thuật bố cục CSS trong một cuốn sách về PHP và MySQL, tôi đã quyết định sử dụng cách đánh dấu không hoàn hảo này. Nếu bạn dự định sử dụng mã này trong thế giới thực, bạn nên đầu tư một chút thời gian vào việc học CSS (hoặc ít nhất là bảo mật các dịch vụ của chuyên gia CSS). Bằng cách đó, bạn có thể kiểm soát hoàn toàn đánh dấu HTML của mình mà không phải lo lắng về CSS cần thiết để làm cho nó trông đẹp mắt. Nếu bạn muốn tìm hiểu thêm về bố cục CSS, hãy xem CSS Master, Phiên bản thứ 3, của Tiffany Brown Thêm CSS sau vào 0902 để làm cho các nút xuất hiện ở bên phải của trò đùa và vẽ một đường thẳng giữa chúng 923Hình ảnh sau đây cho thấy danh sách trò đùa trông như thế nào khi thêm các nút Xóa Nhưng đợi đã. Trước khi chúng ta tiếp tục làm cho nút Xóa hoạt động, hãy nhanh chóng lùi lại và xem xét cẩn thận dòng này 924Ở đây, chúng tôi đang lặp qua đối tượng 9207, đối tượng này cung cấp cho chúng tôi một biến 9223 chứa các khóa 1230 và 9232 cùng với các giá trị tương ứng và chúng tôi đang sử dụng biến đó để tạo một mảng khác có cùng khóa và giá trịBạn có thể đã nhận ra điều này cực kỳ kém hiệu quả. Chúng ta có thể đạt được điều tương tự bằng cách sử dụng mã này 925Nhưng như chúng ta đã biết, điều này cũng có thể đạt được với vòng lặp 9248 926Trong trường hợp này, chúng tôi đang sử dụng 9248 để lặp lại các bản ghi từ cơ sở dữ liệu và tạo một mảng. Sau đó, chúng tôi sẽ lặp qua mảng bằng một vòng lặp 9248 khác trong mẫu. Chúng ta chỉ có thể viết điều này 927Bây giờ, khi 9233 được lặp lại trong mẫu, nó không phải là một mảng mà là một đối tượng 9207. Tuy nhiên, điều đó không ảnh hưởng đến đầu ra và giúp chúng tôi tiết kiệm một số mã. Trên thực tế, chúng ta có thể bỏ qua hoàn toàn biến 9209 và tải trực tiếp đối tượng 9207 vào biến 9233. Bộ điều khiển 0906 hoàn chỉnh bây giờ trông như thế này 928Giờ đây, chúng tôi thậm chí không có vòng lặp 9211 lặp qua các bản ghi trong bộ điều khiển mà chỉ lặp lại các bản ghi trực tiếp trong mẫu, tiết kiệm một số mã và làm cho trang thực thi nhanh hơn một chút, vì giờ đây nó chỉ lặp qua các bản ghi một lầnQuay lại nút Xóa mới của chúng tôi. tất cả những gì còn lại để làm cho tính năng mới này hoạt động là thêm một 1228 có liên quan để đưa ra truy vấn 8493 cho cơ sở dữ liệu 929Mã hoàn chỉnh cho 0906 và 1228 được cập nhật có sẵn dưới dạng Ví dụ. MySQL-DeleteTrò đùaĐoạn mã này hoạt động chính xác như đoạn mã chúng tôi đã thêm vào để xử lý mã “Thêm trò đùa” trước đó trong chương. Chúng tôi bắt đầu bằng cách chuẩn bị truy vấn 8493 với trình giữ chỗ cho ID trò đùa mà chúng tôi muốn xóaMẹo. bạn có thể nghĩ rằng một câu lệnh đã chuẩn bị là không cần thiết trong trường hợp này để bảo vệ cơ sở dữ liệu của chúng ta khỏi các cuộc tấn công SQL injection, vì ID trò đùa được cung cấp bởi một trường biểu mẫu ẩn mà người dùng không nhìn thấy được. Trên thực tế, tất cả các trường biểu mẫu - kể cả những trường ẩn - cuối cùng đều nằm dưới sự kiểm soát của người dùng. Chẳng hạn, có các tiện ích bổ sung cho trình duyệt được phân phối rộng rãi sẽ làm cho các trường biểu mẫu ẩn hiển thị và có sẵn để người dùng chỉnh sửa. Nhớ lại. bất kỳ giá trị nào do trình duyệt gửi cuối cùng đều bị nghi ngờ khi nói đến việc bảo vệ an ninh trang web của bạn Sau đó, chúng tôi liên kết giá trị đã gửi của 1275 với trình giữ chỗ đó và thực hiện truy vấn. Khi đạt được truy vấn đó, chúng tôi sử dụng chức năng PHP 1222 để yêu cầu trình duyệt gửi yêu cầu mới để xem danh sách truyện cười được cập nhậtGhi chú. nếu bạn tự giải quyết ví dụ này, bản năng đầu tiên của bạn có thể là cung cấp siêu liên kết Xóa cho mỗi trò đùa, thay vì gặp rắc rối khi viết toàn bộ biểu mẫu HTML có chứa nút Xóa cho mỗi trò đùa trên trang. Thật vậy, mã cho một liên kết như vậy sẽ đơn giản hơn nhiều 0Nói tóm lại, không bao giờ được sử dụng các siêu liên kết để thực hiện các hành động (chẳng hạn như xóa một trò đùa). Chúng chỉ được sử dụng để cung cấp liên kết đến một số nội dung có liên quan. Điều tương tự cũng xảy ra với các biểu mẫu có 1277, biểu mẫu này chỉ nên được sử dụng để thực hiện các truy vấn dữ liệu hiện có. Các hành động chỉ được thực hiện khi một biểu mẫu có 1278 được gửiLý do cho điều này là các biểu mẫu có 1278 được các trình duyệt và phần mềm liên quan xử lý khác nhau. Ví dụ: nếu bạn gửi biểu mẫu bằng 1278 và sau đó nhấp vào nút làm mới trong trình duyệt của mình, trình duyệt sẽ hỏi bạn có chắc chắn muốn gửi lại biểu mẫu không. Các trình duyệt không có biện pháp bảo vệ tương tự đối với việc gửi lại khi nói đến các liên kết và biểu mẫu có 1277Các công cụ tìm kiếm và trình thu thập dữ liệu web khác cũng sẽ theo tất cả các liên kết trên trang web của bạn để tìm ra thời điểm hiển thị các trang của trang web của bạn trong kết quả tìm kiếm Nếu trang web của bạn đã xóa một trò đùa do một siêu liên kết được theo dõi, thì bạn có thể thấy những câu chuyện cười của mình bị xóa bất cứ khi nào một công cụ tìm kiếm tìm thấy trang web của bạn nhiệm vụ đã hoàn thànhTrong chương này, bạn đã tìm hiểu tất cả về Đối tượng dữ liệu PHP (PDO), một tập hợp các lớp PHP dựng sẵn ( 8404, 8430 và 9207) cho phép bạn giao tiếp với máy chủ cơ sở dữ liệu MySQL bằng cách tạo các đối tượng và sau đó gọi các phương thức của chúng. . Trong khi học, bạn cũng đã nắm được kiến thức cơ bản về lập trình hướng đối tượng (OOP) — điều này không có nghĩa là kỳ tích đối với người mới bắt đầu PHPSử dụng các đối tượng PDO, bạn đã xây dựng trang web dựa trên cơ sở dữ liệu đầu tiên của mình, trang này đã xuất bản cơ sở dữ liệu 4 trực tuyến và cho phép khách truy cập thêm và xóa các câu chuyện cườiTheo một cách nào đó, bạn có thể nói chương này đã đạt được sứ mệnh đã nêu của cuốn sách này. để hướng dẫn bạn cách xây dựng một trang web dựa trên cơ sở dữ liệu. Tất nhiên, ví dụ trong chương này chỉ bao gồm những điều cơ bản nhất. Trong phần còn lại của cuốn sách, tôi sẽ chỉ cho bạn cách tạo ra bộ xương mà bạn đã học cách xây dựng trong chương này Trong Chương 5, chúng ta sẽ quay lại cửa sổ Truy vấn SQL trong MySQL Workbench. Chúng ta sẽ tìm hiểu cách sử dụng các nguyên tắc cơ sở dữ liệu quan hệ và các truy vấn SQL nâng cao để biểu diễn các loại thông tin phức tạp hơn và ghi công cho khách truy cập của chúng tôi về những trò đùa mà họ thêm vào Chúng tôi hy vọng bạn thích đoạn trích này từ PHP & MySQL. Tập làm Ninja, Phiên bản thứ 7. Cuốn sách đầy đủ có sẵn trên SitePoint Premium và từ các nhà bán lẻ sách và sách điện tử yêu thích của bạn Chia sẻ bài viết nàytom quản gia Tom Butler là một nhà phát triển web và giảng viên đại học. Anh ấy có bằng tiến sĩ trong lĩnh vực thực hành tốt nhất về công nghệ phần mềm và thích đánh giá các cách tiếp cận khác nhau đối với các vấn đề lập trình Làm cách nào để hiển thị dữ liệu SQL trong trang web?Làm cách nào để liên kết cơ sở dữ liệu với một trang web? . Chuẩn bị chi tiết tài khoản người dùng cơ sở dữ liệu của bạn. Thông tin chi tiết về tài khoản cơ sở dữ liệu của bạn sẽ cần thiết để thiết lập kết nối với trang web. . Kết nối với cơ sở dữ liệu của bạn. . Truy vấn dữ liệu của bạn. . Xuất dữ liệu của bạn. . Kiểm tra tập lệnh của bạn và trình bày dữ liệu Giới thiệu cơ sở dữ liệu MySQL là gì?MySQL là hệ thống quản lý cơ sở dữ liệu quan hệ . MySQL là mã nguồn mở. MySQL là miễn phí. MySQL là lý tưởng cho cả ứng dụng nhỏ và lớn. MySQL rất nhanh, đáng tin cậy, có thể mở rộng và dễ sử dụng.
Làm cách nào để kết nối cơ sở dữ liệu MySQL với trang web của tôi?Tạo nên cơ sở dữ liệu Tạo thư mục trong htdocs Tạo tệp kết nối cơ sở dữ liệu trong PHP Tạo tệp php mới để kiểm tra kết nối cơ sở dữ liệu của bạn chạy nó Làm cách nào để lấy dữ liệu từ MySQL sang HTML?Làm cách nào để lấy dữ liệu từ cơ sở dữ liệu và hiển thị ở dạng HTML? . Kết nối PHP với cơ sở dữ liệu MySQL. Bạn có thể sử dụng truy vấn kết nối cơ sở dữ liệu sau để kết nối PHP với cơ sở dữ liệu MySQL Chèn dữ liệu vào bảng PHPMyAdmin Lấy dữ liệu từ bảng MySQL Hiển thị dữ liệu trong bảng HTML Tự kiểm tra để chèn dữ liệu |