[BÀI 32] HƯỚNG DẪN VIẾT MỘT TRANG WEB CƠ BẢN BẰNG PHP (PHẦN 1: TẠO CẤU TRÚC FILE)
http://laptrinhphp.vn/bai-32-huong-dan-viet-mot-trang-web-co-ban-bang-php-phan-1-tao-cau-truc-file/
Last updated
http://laptrinhphp.vn/bai-32-huong-dan-viet-mot-trang-web-co-ban-bang-php-phan-1-tao-cau-truc-file/
Last updated
[BÀI 32] HƯỚNG DẪN VIẾT MỘT TRANG WEB CƠ BẢN BẰNG PHP (PHẦN 1: TẠO CẤU TRÚC FILE)
Sau khi đã tìm hiểu sơ qua về PHP, chúng ta đã nắm được phần nào về ngôn ngữ mạnh mẽ này . Để các bạn dễ hình dung, loạt bài hướng dẫn tiếp theo này tôi sẽ hướng dẫn các bạn tạo một trang web hoàn chỉnh bằng mô hình MVC hướng đối tượng.
1: Tạo giao diện của trang web.
2: Viết trang quản trị.
3: Truy vấn và xử lý dữ liệu
4: Kiểm lỗi
5: Upload mã nguồn lên host
Cùng tìm hiểu bước 1 của công đoạn này:
Tùy vào các loại trang web khác nhau mà bạn sẽ tạo nên một giao diện khác nhau:
Để cho nhanh, tôi có một giao diện như sau, bạn chỉ việc tải về và tiến hành làm bước thứ 2 là làm trang quản trị.
Click vào đây để tải giao diện về.
Tải xong và giải nén các bạn sẽ có cấu trúc file như sau:
Trong đó:
Thư mục “assets”: chứa các file về css, js, và hình ảnh
thư mục “bs”: tôi lưu mã nguồn của bootstrap ở đây
….
file “index.php”: là trang chủ
Chạy file index.php và bạn sẽ có giao diện như sau:
Bước 2: Tạo trang quản trị:
Bước đầu tiên cũng là bước quan trọng nhất của một trang quản trị, đó chính là bước đăng nhập. Ở bài số 23 tôi đã hướng dẫn các bạn làm chức năng này, song đó là chức năng đăng nhập viết theo cách thông thường. Với mô hình MVC hướng đối tượng, cách viết của tôi sẽ có sự khác biệt một chút, tuy nhiên bạn cần nhớ, tôi chỉ viết hơi khác biệt vì tôi phải tuân thủ theo cách viết của MVC hướng đối tượng. Song về bản chất không có gì thay đổi cả.
1: Tạo một thư mục chỉ dành riêng cho admin mới có quyền truy cập:
Ngang cấp với file index.php tôi tạo một thư mục có tên là admin, và một file có tên là config.php
Thư mục admin sẽ chứa các mã nguồn của trang quản trị
File config.php là file tôi tạo để kết nối đến cơ sở dữ liệu
Hoàn tất việc tạo folder “admin” và file “config.php” bạn sẽ có cấu trúc file như sau:
Tạo một cơ sở dữ liệu mới:
Tôi tiến hành tạo một cơ sở dữ liệu mới có tên là “devpro_project_mvc” trên xampp.
Trong cơ sở dữ liệu này chứ một bảng tên là “users”, bảng này chứa các trường là id (khóa chính, tự động tăng,kiểu int), email kiểu varchar(100) để lưu tài khoản người dùng, password kiểu varchar(100) để lưu mật khẩu người dùng, và name kiểu varchar(50) để lưu tên người dùng.
Tạo xong tôi có cấu trúc bảng users như sau:
Cấu hình file config.php:
Để thao tác được với cơ sở dữ liệu, tôi cần đến kết nối đến cơ sở dữ liệu, trong file config.php tôi viết như sau:
123456
<?php // kết nối đến database devpro_project_mvc và lưu vào biến $ketnoi: $ketnoi = mysqli_connect("localhost", "root", "", "devpro_project_mvc"); //việc truy vấn sẽ có thể sử dụng dữ liệu tiếng Việt: mysqli_set_charset($ketnoi,"UTF8"); ?>
Tạo mô hình MVC hướng đối tượng:
Như tìm hiểu ở bài trước, tôi đã có nói qua về mô hình MVC và sau đây là cách viết để các bạn dễ hình dung hơn về mô hình MVC:
Trong thư mục admin, tôi tạo 3 thư mục có tên là model,controller,view. Tương ứng model: tạo các hàm thao tác với database, controller: xử lý dữ liệu và các thao tác truy vấn, view: hiển thị giao diện để người dùng tương tác.
Cấu trúc file của các bạn bây giờ sẽ như sau:
Model : viết các hàm thao tác với cơ sở dữ liệu:
Trong thư mục model, tôi tạo một file có tên là model để viết các hàm thao tác với cơ sở dữ liệu, cụ thể trong admin/model/model.php tôi viết các hàm sau:
12345678910111213141516171819202122232425262728293031323334353637383940414243
<?php class model { public $connect; //hàm tạo: public function __construct(){ global $ketnoi; $this->connect=$ketnoi; } //---- start duyệt các bản ghi: ------------ public function fetch_all($query){ //thực hiện truy vấn: $ketqua_truyvan=mysqli_query($this->connect,$query); //lưu vào 1 mảng: $arr=array(); while($rows= mysqli_fetch_array($ketqua_truyvan)) $arr[]=$rows; return $arr; } //---------end duyệt các bản ghi.------------ // -- start duyệt 1 bản ghi: ------------------ public function fetch_one($query){ $ketqua_truyvan=mysqli_query($this->connect,$query); $row=mysqli_fetch_array($ketqua_truyvan); return $row; } // -- end duyệt 1 bản ghi. -------------------- //-- start đếm số lượng bản ghi trong số lượng trả về: public function fetch_count($query) { $ketqua_truyvan=mysqli_query($this->connect,$query); return mysqli_num_rows($ketqua_truyvan); } //-------------------end đếm--------------------------------- //----- start thực thi câu truy vấn:---------------------- public function query($query){ mysqli_query($this->connect,$query); } //------ end thực thi truy vấn -------------------- } ?>
Tôi có các hàm cơ bản như:
Hàm __construct(): là hàm tạo, hàm này luôn được thực thi và được thực thi đầu tiên khi class được khởi tạo mà không cần gọi. Do vậy khi model được khởi tạo -> hàm __construct() sẽ được chạy, hàm này được chạy sẽ tạo kết nối đến CSDL. và gán vào biến $ketnoi.
Hàm fetch_all($query){}: là hàm duyệt và lấy ra nhiều bản ghi thỏa mãn truy vấn được truyền vào, ví dụ như lấy ra các bài viết được viết trong ngày 03/11/2016
Hàm fectch_one($query){}: là hàm duyệt và lấy ra duy nhất một bản ghi thỏa mãn truy vấn được truyền vào, ví dụ như lấy ra tất cả thông tin của sinh viên có mã là 123456 (do mã sinh viên là không trùng nên chỉ lấy ra được 1 bản ghi tương ứng với mã sinh đó)
Hàm fetch_count($query){}: đếm xem có bao nhiêu bản ghi thỏa mãn truy vấn truyền vào.
Hàm query($query){}: sẽ thực thi câu truy vấn bất kỳ.
Tạo controller cha, để các controller khác có thể kế thừa:
Trong thư mục admin/controller/ tôi tạo 1 file có tên là controller.php và file này chứa nội dung sau:
123456789
<?php class controller { public $model; public function __construct(){ //khởi tạo model: $this->model=new model(); } }?>
Tạo view:
Trong thư mục admin/tôi tạo một file tên là index.php (đây là trang chủ của trang quản trị), ở trang index.php tôi viết như sau:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
<!DOCTYPE html> <html> <head> <title>'Trang quản trị'</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <link rel="stylesheet" href="public/style.css"> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> </head> <body><div id="wrapper"> <!-- start avigation --> <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="index.php">'QUẢN TRỊ HỆ THỐNG'</a> </div> <!-- end avigation --> <!-- start top menu --> <ul class="nav navbar-right top-nav"> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-user"></i> 'Xin chào: Hồ Ngọc Trung'<b class="caret"></b></a> <ul class="dropdown-menu"> <li> <a href="#"><i class="glyphicon glyphicon-list-alt"></i> 'Danh sách tài khoản'</a> </li> <li> <a href="#"><i class="glyphicon glyphicon-user"></i> 'Hồ sơ cá nhân'</a> </li> <li> <a href="#"><i class="glyphicon glyphicon-plus-sign"></i> 'Thêm tài khoản'</a> </li> <li class="divider"></li> <li> <a href="#"><i class="glyphicon glyphicon-off"></i> 'Đăng xuất'</a> </li> </ul> </li> </ul> <!-- end top menu --> <!-- start menu left --> <div class="collapse navbar-collapse navbar-ex1-collapse"> <ul class="nav navbar-nav side-nav"> <li style="background:#52bc89;color:#fff;"> <a href="#" style="color:#fff;"><i class="glyphicon glyphicon-folder-open"></i> 'Danh mục'</a> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_dmcc"><i class="glyphicon glyphicon-picture"></i> Banner <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_dmcc" class="collapse"> <li> <a href="#">'Banner hiện tại'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_dm"><i class="glyphicon glyphicon-picture"></i>' Danh sách khóa học '<i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_dm" class="collapse"> <li> <a href="#">'Danh sách'</a> </li> <li> <a href="#">'Thêm mới'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_dmm"><i class="glyphicon glyphicon-sunglasses"></i>' Dịch vụ của chúng tôi '<i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_dmm" class="collapse"> <li> <a href="#">'Danh sách'</a> </li> <li> <a href="#">'Thêm'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_bv"><i class="glyphicon glyphicon-globe"></i> 'Thông tin về Devpro' <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_bv" class="collapse"> <li> <a href="#">'Chi tiết'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_a1"><i class="glyphicon glyphicon-camera"></i> 'Thông tin liên hệ'' <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_a1" class="collapse"> <li> <a href="#"> 'Chi tiết' </a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_a2"><i class="glyphicon glyphicon-tag"></i> 'Tin nhắn học viên' <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_a2" class="collapse"> <li> <a href="#">' Danh sách '</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_a456"><i class="glyphicon glyphicon-star-empty"></i> Design <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_a456" class="collapse"> <li> <a href="#">' Để nâng cấp website, liên hệ: '</a> <a href="http://facebook.com/trung.hongoc">' Hồ Ngọc Trung '</a> <a href="#">0969 540 038</a> </li> </ul> </li> </ul> </div> </nav> <!-- end menu left --> <!-- 'start nội dung' --> <div id="page-wrapper"> <div class="container-fluid"> </div> </div> <!-- 'end nội dung' --> </div></body></html>
Trong thư mục admin/ tôi tạo tiếp 1 folder có tên là public để chứa các css/js dùng cho trang quản trị, trong folder public tôi tạo một file là style.css : (admin/public/style.css), file này có nội dung như sau (mục đích chỉ để trang admin của tôi đẹp hơn thôi):
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
/*! * Start Bootstrap - SB Admin Bootstrap Admin Template (http://startbootstrap.com) * Code licensed under the Apache License v2.0. * For details, see http://www.apache.org/licenses/LICENSE-2.0. */ /* Global Styles */ body { margin-top: 100px; background-color: #222;} @media(min-width:768px) { body { margin-top: 50px; }} #wrapper { padding-left: 0;} #page-wrapper { width: 100%; min-height: 700px !important; padding: 0; background-color: #fff;} .huge { font-size: 50px; line-height: normal;} @media(min-width:768px) { #wrapper { padding-left: 225px; } #page-wrapper { padding: 10px; }} /* Top Navigation */ .top-nav { padding: 0 15px;} .top-nav>li { display: inline-block; float: left;} .top-nav>li>a { padding-top: 15px; padding-bottom: 15px; line-height: 20px; color: #999;} .top-nav>li>a:hover,.top-nav>li>a:focus,.top-nav>.open>a,.top-nav>.open>a:hover,.top-nav>.open>a:focus { color: #fff; background-color: #000;} .top-nav>.open>.dropdown-menu { float: left; position: absolute; margin-top: 0; border: 1px solid rgba(0,0,0,.15); border-top-left-radius: 0; border-top-right-radius: 0; background-color: #fff; -webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175); box-shadow: 0 6px 12px rgba(0,0,0,.175);} .top-nav>.open>.dropdown-menu>li>a { white-space: normal;} ul.message-dropdown { padding: 0; max-height: 250px; overflow-x: hidden; overflow-y: auto;} li.message-preview { width: 275px; border-bottom: 1px solid rgba(0,0,0,.15);} li.message-preview>a { padding-top: 15px; padding-bottom: 15px;} li.message-footer { margin: 5px 0;} ul.alert-dropdown { width: 200px;} /* Side Navigation */ @media(min-width:768px) { .side-nav { position: fixed; top: 51px; left: 225px; width: 225px; margin-left: -225px; border: none; border-radius: 0; overflow-y: auto; background-color: #222; bottom: 0; overflow-x: hidden; padding-bottom: 40px; } .side-nav>li>a { width: 225px; } .side-nav li a:hover, .side-nav li a:focus { outline: none; background-color: #000 !important; }} .side-nav>li>ul { padding: 0;} .side-nav>li>ul>li>a { display: block; padding: 10px 15px 10px 38px; text-decoration: none; color: #999;} .side-nav>li>ul>li>a:hover { color: #fff;} /* Flot Chart Containers */ .flot-chart { display: block; height: 400px;} .flot-chart-content { width: 100%; height: 100%;} /* Custom Colored Panels */ .huge { font-size: 40px;} .panel-green { border-color: #5cb85c;} .panel-green > .panel-heading { border-color: #5cb85c; color: #fff; background-color: #5cb85c;} .panel-green > a { color: #5cb85c;} .panel-green > a:hover { color: #3d8b3d;} .panel-red { border-color: #d9534f;} .panel-red > .panel-heading { border-color: #d9534f; color: #fff; background-color: #d9534f;} .panel-red > a { color: #d9534f;} .panel-red > a:hover { color: #b52b27;} .panel-yellow { border-color: #f0ad4e;} .panel-yellow > .panel-heading { border-color: #f0ad4e; color: #fff; background-color: #f0ad4e;} .panel-yellow > a { color: #f0ad4e;} .panel-yellow > a:hover { color: #df8a13;}#footer{ text-align: center;}#footer p{ font-size:14px; color:#fff; margin-bottom:0; line-height:50px;}
Như tôi viết ở trên: các file config.php, admin/controller/controller.php, admin/model/model.php và admin/index.php đang là các file riêng biệt, không liên quan gì đến với nhau hết. Do vậy, tôi phải kết nối các file này vào làm một. Bản chất của mô hình MVC là tách các phần xử lý các công việc khác nhau ra thành các file khác nhau cho dễ quản lý, sửa chữa, nâng cấp,… mà thôi.
Ở file index.php tôi viết thêm như sau:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
<?php include "../config.php"; session_start(); ob_start(); include "model/model.php"; include "controller/controller.php"; ?> <!DOCTYPE html> <html> <head> <title>Trang quản trị</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <link rel="stylesheet" href="public/style.css"> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> </head> <body><div id="wrapper"> <!-- start avigation --> <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="index.php">'QUẢN TRỊ HỆ THỐNG'</a> </div> <!-- end avigation --> <!-- start top menu --> <ul class="nav navbar-right top-nav"> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-user"></i> 'Xin chào: Hồ Ngọc Trung'<b class="caret"></b></a> <ul class="dropdown-menu"> <li> <a href="#"><i class="glyphicon glyphicon-list-alt"></i> 'Danh sách tài khoản'</a> </li> <li> <a href="#"><i class="glyphicon glyphicon-user"></i> 'Hồ sơ cá nhân'</a> </li> <li> <a href="#"><i class="glyphicon glyphicon-plus-sign"></i> 'Thêm tài khoản'</a> </li> <li class="divider"></li> <li> <a href="#"><i class="glyphicon glyphicon-off"></i> 'Đăng xuất'</a> </li> </ul> </li> </ul> <!-- end top menu --> <!-- start menu left --> <div class="collapse navbar-collapse navbar-ex1-collapse"> <ul class="nav navbar-nav side-nav"> <li style="background:#52bc89;color:#fff;"> <a href="#" style="color:#fff;"><i class="glyphicon glyphicon-folder-open"></i> 'Danh mục'</a> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_dmcc"><i class="glyphicon glyphicon-picture"></i> Banner <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_dmcc" class="collapse"> <li> <a href="#">'Banner hiện tại'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_dm"><i class="glyphicon glyphicon-picture"></i>' Danh sách khóa học '<i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_dm" class="collapse"> <li> <a href="#">'Danh sách'</a> </li> <li> <a href="#">'Thêm mới'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_dmm"><i class="glyphicon glyphicon-sunglasses"></i>' Dịch vụ của chúng tôi '<i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_dmm" class="collapse"> <li> <a href="#">'Danh sách'</a> </li> <li> <a href="#">'Thêm'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_bv"><i class="glyphicon glyphicon-globe"></i> 'Thông tin về Devpro' <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_bv" class="collapse"> <li> <a href="#">'Chi tiết'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_a1"><i class="glyphicon glyphicon-camera"></i> 'Thông tin liên hệ' <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_a1" class="collapse"> <li> <a href="#">'Chi tiết'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_a2"><i class="glyphicon glyphicon-tag"></i> 'Tin nhắn học viên' <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_a2" class="collapse"> <li> <a href="#">'Danh sách'</a> </li> </ul> </li> <li> <a href="javascript:;" data-toggle="collapse" data-target="#demo_a456"><i class="glyphicon glyphicon-star-empty"></i> Design <i class="glyphicon glyphicon-chevron-down"></i></a> <ul id="demo_a456" class="collapse"> <li> <a href="#">'Để nâng cấp website, liên hệ:'</a> <a href="http://facebook.com/trung.hongoc">'Hồ Ngọc Trung'</a> <a href="#">0969 540 038</a> </li> </ul> </li> </ul> </div> </nav> <!-- end menu left --> <!-- start nội dung --> <div id="page-wrapper"> <div class="container-fluid"> </div> </div> <!-- end nội dung --> </div></body></html>
Như vật tôi đã hoàn thành việc tạo cấu trúc file của một dự án viết theo mô hình MVC, bài tiếp theo tôi sẽ hướng dẫn các bạn viết chức năng đăng nhập với mô hình MVC hướng đối tượng.
Download toàn bộ mã nguồn của bài hôm nay tại đây!
Video hướng dẫn tạo cấu trúc file MVC hướng đối tượng: