Cách chèn Fanpage vào website

Khi doanh nghiệp của bạn đã có một trang Fanpage Facebook và bạn cũng đang sở hữu một trang Web thì đều mà bạn quan tâm đến đó là làm sao để chèn Fanpage để tạo nút Like trong trang Web của mình. Việc này sẽ giúp cho Fanpage của bạn có thêm nhiều thành viên hơn đồng thời cũng sẽ có nhiều người biết đến Website của bạn thông qua Facebook. Sự kết hợp giữa Facebook và Website sẽ là phương pháp SEO hiệu quả nhất và đạt kết quả không ngờ.

Nếu như bạn đang băn khoăn về việc làm sao để chèn Fanpage Facebook vào Website của mình thì nội dung dưới đây sẽ hữu ích với bạn. Chỉ với vài thao tác đơn giản thì bạn đã có thể mang Fanpage Facebook vào trang Web của mình.

Sơ lược về lợi ích của Fanpage Facebook

Mạng xã hội Facebook với số lượng hơn 1 tỷ người dùng đã trở thành một kênh bán hàng và quảng bá thương hiệu tuyệt vời mà các công ty, tổ chức không thể bỏ qua.

Việc liên kết giữa website và Facebook, cụ thể là Fanpage Facebook giúp gắn kết khách hàng với thương hiệu chặt chẽ hơn. Tạo thêm hiệu ứng thu hút các khách hàng mới đến với thương hiệu của bạn.

Tạo Code Fanpage Facebook để chèn vào Website.

Trước khi tạo Like Box trên website bạn cần phải lấy được đoạn code fanpage. Bạn cần làm theo các bước sau:

Bước 1: Truy cập và đăng nhập tài khoản Facebook vào trang sau: https://developers.facebook.com/docs/plugins/like-box-for-pages

Bước 2: Tại đây, bạn có thể tùy chỉnh 1 số thông tin trong Like Box như:

fanpage-agitech-phan-mem-an-giang

Chi tiết:

  • Show Friends’ Faces: Hiện hình ảnh thành viên like
  • Show Header: Hiện tên tiêu đề like box phía trên cùng
  • Show Posts: Hiện bài viết của bạn trong fanpage
  • Show Border: Hiện đường viền bao quang Like Box

Bước 3: Sau khi đã thiết lập xong, bạn chọn Get Code và dùng code này để chèn vào Website.

lay-ma-script-fanpage

 

Lưu ý: Để đơn giản việc chèn code vào Website, khi Get Code bạn chọn vào tab Iframe.

chon-nhung-iframe-fanpage

Việc tiếp theo, bạn chỉ cần chèn code này vào bất cứ vị trí nào mà bạn muốn.

Đổi với Website làm CMS như Joomla, WordPress, Drupal

Tạo một module trong Joomla ở dạng Custom hoặc Widget trong WordPress dạng Text. Sau đó chèn đoạn code đã tạo vào và lưu lại. Hoặc có thể tải về các Plugin, phần mở rộng có hổ trợ việc tích hợp Fanpage Facebook vào trang Web.

Đối với Blogger

Bạn vào Bố Cục >> Thêm tiện ích và chọn HTML/Javascript. Sau đó bạn chỉ cần dán đoạn code vào phần Nội dung, đặt tên cho phần Tiêu đề và lưu lại là xong.

Ngụy Kim Hưng

Tìm hiểu một số thẻ meta ( Hải Âu)

Meta tag là thẻ dùng để cung cấp các thông tin về website một cách tóm gọn đối với các trình duyệt lẫn người dùng hay bot từ các search engine. Hiện nay, có không ít người đang hiểu sai ý nghĩa của nó và ứng dụng đôi khi không hợp lý trong nhiều website. Dưới đây là một số thẻ thường dùng

    - Meta Description:

        Thẻ này dùng để mô tả nội dung của một trang web. Nội dung của thẻ này nên được viết ngắn gọn và xúc tích khoảng từ 20 đến 25 từ hoặc ít hơn. Đây là thẻ được hầu hết các SE sử dụng để hiển thị nội dung kết quả tìm kiếm.

        Ví dụ: HTML

             <META NAME=”description” CONTENT=”Website Khoa học kỹ thuật, giải trí và đời sống dành cho cộng đồng người Việt cùng chia sẽ kinh nghiệm và trao đổi học hỏi.”>

        Thẻ này được khuyến khích sử dụng và nên viết một cách xúc tích nhất nhằm thu hút người dùng bấm vào website của bạn từ kết quả tìm kiếm. Thông thường nếu không dùng thẻ này thì các SE như google cũng sẽ tự động tạo khi index nội dung website. Tuy nhiên bạn nên dùng bởi vì đôi khi các mô tả được index tự động sẽ không được như ý của bạn.

   - Meta Abstract:

        Cung cấp nội dung tóm tắt cho phần mô tả của website. Thẻ này chỉ được dùng để mô tả ngắn gọn hơn để bot có thể xác định được chính xác hơn nội dung website của bạn. Nội dung của thẻ này thường khoảng 10 từ trở lại.

         Ví dụ: HTML

              <META NAME=”Abstract” CONTENT="Noi dung mo ta website.">

    - Meta Keywords:

        Thẻ từ khóa được dùng để định dạng nội dung trang web. Từ khóa được sử dụng bởi các SE để index site của bạn có thêm thông tin từ các nội dung của title, body, và các thành phần khác. Từ này thường được dùng để cung cấp các từ khóa liên quan đồng nghĩa hoặc tương tự với các từ khóa của title.

           Ví dụ: Title của trang web cho bài viết này là “Tìm hiểu một số thẻ meta”. Bạn có thể ứng dụng keywords như sau:

             HTML

           <META NAME=”keywords” CONTENT=”khái niệm, quảng bá website, quảng bá web, tag, forum, technical, science, keyword, abstract”>

       Bạn nên sử dụng keywords một cách thận trong và bảo đảm sự tương thích với nội dung. Website của bạn có thể bị phạt hoặc đưa vào blacklist nếu bạn quá lạm dụng nó. Việc sử dụng keywords cũng có thể là một con dao hai lưỡi đối với bạn. Bạn có thể mất vài giờ để nghiên cứu cách viết keywords tốt nhất và đối thủ của bạn chỉ mất vài phút để thừa hưởng từ bạn.

      Trong bài viết tuy rất cần lối viết tự nhiên nhưng làm gì thì cũng cần có quy tắc. vậy nên muốn bài viết lên top, muốn thẻ meta description chuẩn seo thì cần phải tuân thủ một vài quy tắc sau:

  1. Miêu tả nội dung chân thực của bài viết
  2. Viết không quá 140 ký tự (lưu ý là ký tự chứ không phải chữ )
  3. Viết càng câu dẫn, càng lôi kéo càng tốt, có thể nói quá nhưng không được nói sai.
  4. Lưu ý rằng mỗi thẻ meta của một bài viết cần khác biệt với tất cả những thẻ meta khác.
  5. Thẻ meta description cần chứa từ khóa và từ khóa nên in đậm để thu hút sự chú ý.
  6. Viết thẻ meta theo kiểu liệt kê thông tin liên quan và quan trọng chứ không nên nhồi nhét thông tin hay từ khóa.

Giới thiệu về filesystem storage trong Laravel

Laravel Storage

Laravel cung cấp cho ta một lớp abstraction filesystem mạnh mẽ do sử dụng package Flysystem tạo bởi Frank de Jonge. Tích hợp Flysystem vào Laravel với cách sử dụng rất đơn giản để giao tiếp với các local filesystem, Amazon S3, và Rackspace Cloud Storage. Thậm chí còn có thể switch các storage một cách dễ dàng sử dụng chung API.

Lợi ích của Laravel storage:

- Việc lưu trữ các file sẽ tốn rất nhiều tài nguyên và băng thông trên server, giải pháp đưa ra là lưu trữ trên các server bên ngoài nên Laravel Storage được tích hợp hỗ trợ lưu trữ file trên server ngoài như Amazon S3.

- Đơn giản hóa trong việc thiết lập các tùy chon.

Cấu hình (Config):

File cấu hình được đặt tại "config/filesystems.php"  và được thiết lập sẵn như sau.

    /*
    |--------------------------------------------------------------------------
    | Default Filesystem Disk
    |--------------------------------------------------------------------------
    */

    'default' => env('FILESYSTEM_DRIVER', 'local'),

    /*
    |--------------------------------------------------------------------------
    | Default Cloud Filesystem Disk
    |--------------------------------------------------------------------------
    */

    'cloud' => env('FILESYSTEM_CLOUD', 's3'),

    /*
    |--------------------------------------------------------------------------
    | Filesystem Disks
    |--------------------------------------------------------------------------
    */

    'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
        ],

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],

        's3' => [
            'driver' => 's3',
            'key' => env('AWS_KEY'),
            'secret' => env('AWS_SECRET'),
            'region' => env('AWS_REGION'),
            'bucket' => env('AWS_BUCKET'),
        ],

    ],

 

 Với Local Driver

Khi thao tác tới file sẽ tương tác tới thư mục root được khai báo trong file, giá trị mặc định được trỏ tới storage/app. Do đó với đoạn code sau file sẽ được lưu trong storage/app/file.txt:

    Storage::disk('local')->put('file.txt', 'Contents');

Với config driver là S3 hoặc Rackspace cần cài đặt các package như yêu cầu thông qua composer

  • Amazon S3: league/flysystem-aws-s3-v3 ~1.0
  • Rackspace: league/flysystem-rackspace ~1.0

Cấu hình cho FTP Driver

Mặc định FTP driver không được cấu hình mặc định trong filesystems.php. Bạn có thể sử dụng ví dụ cấu hình dưới đây như Laravel Docs:

    'ftp' => [
		'driver'   => 'ftp',
		'host'     => 'ftp.example.com',
		'username' => 'your-username',
		'password' => 'your-password',

		// Optional FTP Settings...
		// 'port'     => 21,
		// 'root'     => '',
		// 'passive'  => true,
		// 'ssl'      => true,
		// 'timeout'  => 30,
	]

Cấu hình cho Rackspace Driver

Cũng giống như FTP, Rackspace driver cũng không được config sẵn trong file filesystems.php.

Các bạn có thể tham khảo cấu hình sau:

    'rackspace' => [
		'driver'    => 'rackspace',
		'username'  => 'your-username',
		'key'       => 'your-key',
		'container' => 'your-container',
		'endpoint'  => 'https://identity.api.rackspacecloud.com/v2.0/',
		'region'    => 'IAD',
		'url_type'  => 'publicURL',
	]

Để sử dụng thư việc Storage các bạn đừng quên khai báo thư viện:

use Illuminate\Support\Facades\Storage;

Sau khi khai báo thư viện các bạn có thể tương tác với các disk đã được cấu hình.

	$disk = Storage::disk('local');
	// or
	$disk2 = Storage::disk('s3');

 

Giới thiệu các hàm cơ bản:

  • get(): Được dùng để lấy nội dung của một file:
$contents = Storage::get('file.txt');
  • exists(): Kiểm tra sự tồn tại của 1 file:
$exists = Storage::disk('local')->exists('file.txt');
  • url(): Để lấy URL của file. Nếu bạn sử dụng local driver, nó sẽ tự động thêm vào "/storage" cho path và trả về một relative URL của file. Nếu bạn sử dụng s3 driver, URL đầy đủ sẽ được trả về.

Chú ý: Khi sử dụng local driver, hãy chắc chắn tạo một symbolic link tại public/storage trỏ tới thư mục storage/app/public.

$url = Storage::url('file.txt');
  • size(): Trả về kích thước của file, đơn vị là bytes:
$size = Storage::size('file.txt');
  • lastModified(): Trả về giá trị UNIX timestamp của lần cuối cùng file bị thay đổi:
$time = Storage::lastModified('file.txt');
  • put(): Có thể được dùng để lưu file lên disk. Ta cũng có thể truyền một PHP resource cho hàm put, nó sẽ sử dụng stream của Flysystem. Bạn nên sử dụng stream khi phải làm việc với file lớn:
Storage::put('file.txt', $contents);
Storage::put('file.txt', $resource);
  • copy(): Dùng để copy một file đang tồn tại sang một vị trí mới trên disk:
Storage::copy('old/file.txt', 'new/file.txt');
  • move(): Dùng để đổi tên hay di chuyển một file đang tồn tại tới vị trí mới:
Storage::move('old/file.txt', 'new/file.txt');
  • prepend(): Thêm nội dung vào đầu 1 file:
Storage::prepend('file.txt', 'Prepended Text');
  • append(): Chèn thêm nội dung vào cuối file:
Storage::append('file.txt', 'Appended Text');
  • delete(): Xoá file khỏi disk, bạn có thể xóa 1 file hoặc 1 mảng các file:
Storage::delete('file.txt');
Storage::delete(['file1.txt', 'file2.txt']);
  • files(): Trả về một mảng các files trong một thư mục.
$files = Storage::files($directory);
  • allFiles(): Sẽ lấy danh sách tất cả các file trong một thư mục bao gồm các thư mục con:
$files = Storage::allFiles($directory);
  • directories(): Sẽ trả về một mảng gồm tất cả các thư mục bên trong một thư mục.
$directories = Storage::directories($directory);
  • allDirectories(): Hàm này lấy về danh sách tất cả các thư mục trong một thư mục và các thư mục con của nó:
$directories = Storage::allDirectories($directory);
  • makeDirectory(): Sẽ tạo một thư mục mới, bao gồm các thư mục con cần thiết:
Storage::makeDirectory($directory);
  • deleteDirectory(): Xoá một thư mục, bao gồm tất cả các file của nó:
Storage::deleteDirectory($directory);
  • download(): Tải file về máy tính.
return Storage::download('file.jpg');

Mong rằng qua bài này sẽ giúp các bạn hiểu hơn về Storage trong Laravel. Các bạn có thể xây dựng một hệ thống quản lý các media của mình trên server một cách dễ dàng hơn. Chúc các bạn thành công trong lập trình Laravel.

Ngụy Kim Hưng

Bài 3 - Laravel xử lý đăng nhập và phân quyền

Chức năng đăng nhập trong laravel

Chào các bạn, hôm này mình sẽ giới thiệu với các bạn cách tạo trang đăng ký, đăng nhập và phần quyền với Laravel.

Nếu các bạn thực hiện tạo bảng dữ liệu trong mysql bằng cách sử dụng lệnh command "php artisan migrate" thì trong cơ sở dữ liệu của các bạn đã có bảng "users". Nếu trong cơ sở dữ liệu của các bạn chưa có bảng "users" thì các bạn gõ lệnh command trên để laravel sẽ tự động tạo bảng cho các bạn.

Lavarel đã tạo sẵn các file controller cho bảng "users"  trong thư mục "app/Http/Controllers/Auth" nên chúng ta có thể sử dụng các file này để xây dựng chức năng đang nhập.

Trước tiên chúng ta định hướng đường dẫn website mặc định sẽ vào trang đăng nhập cho file web.php trong thư mục routes như sau:

// Sửa đường dẫn trang chủ mặc định
Route::get('/', 'HocsinhController@index');
Route::get('/home', 'HocsinhController@index');

// Đăng ký thành viên
Route::get('register', 'Auth\RegisterController@getRegister');
Route::post('register', 'Auth\RegisterController@postRegister');

// Đăng nhập và xử lý đăng nhập
Route::get('login', [ 'as' => 'login', 'uses' => 'Auth\LoginController@getLogin']);
Route::post('login', [ 'as' => 'login', 'uses' => 'Auth\LoginController@postLogin']);

// Đăng xuất
Route::get('logout', [ 'as' => 'logout', 'uses' => 'Auth\LogoutController@getLogout']);

Tiếp theo, để vào trang học sinh kiểm tra nếu chưa đăng nhập vào hệ thống thì sẽ tự động chuyển ra trang đăng nhập chúng ta thêm đoạn code sau trong file "HocSinhController.php":

public function __construct() {
	$this->middleware('auth');
}

 

Chúng ta sẽ tạo một trang form đăng nhập trong thư mục "resource/views/auth/" file "login.blade.php" với nội dung đoạn code sau:

@extends('templates.master')
@section('title','Trang quản lý')
@section('content')
<?php //Hiển thị thông báo thành công?>
@if ( Session::has('success') )
<div class="alert alert-success alert-dismissible" role="alert">
<strong>{{ Session::get('success') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<?php //Hiển thị thông báo lỗi?>
@if ( Session::has('error') )
<div class="alert alert-danger alert-dismissible" role="alert">
<strong>{{ Session::get('error') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger alert-dismissible" role="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<div class="container" style="margin-top: 10%">
<div class="row">
<div class="col-sm-6 col-md-4 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-body">
<form role="form" action="{{ url('/login') }}" method="POST">
{!! csrf_field() !!}
<fieldset>
<div class="row">
<div class="center-block">
<img class="profile-img" src="/public/images/user-icon.png" alt="User">
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-10 col-md-offset-1 ">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input class="form-control" placeholder="Email" name="email" type="text" value="{{ old('email') }}" autofocus>
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input class="form-control" placeholder="Mật khẩu" name="password" type="password" value="">
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-lg btn-primary btn-block" value="Đăng nhập">
</div>
<div class="login-help">
<a href="/{{ url('/register') }}" >Đăng ký</a> - <a href="#" >Quên mật khẩu</a>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
<style>
body{
background: #17568C;
}
.panel{
border-radius: 5px;
}
.panel-heading {
padding: 10px 15px;
}
.panel-title{
text-align: center;
font-size: 15px;
font-weight: bold;
color: #17568C;
}
.panel-footer {
padding: 1px 15px;
color: #A0A0A0;
}
.profile-img {
width: 120px;
height: 120px;
margin: 0 auto 10px;
display: block;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
</style>
@endsection

 

Trong file web.php chúng ta đã định trang đang nhập bằng cách gọi hàm "getLogin()" trong file "LoginController.php".

Vậy nên chúng ta sẽ viết hàm hiển thị form đăng nhập trong "LoginController.php" của thư mục "app/Http/Controllers/Auth" để gọi đến file form chúng ta đã tạo.

public function getLogin() {
	return view('auth/login');
}

Tiếp theo chúng ta sẽ viết thêm hàm xử lý đăng nhập trong "LoginController.php" của thư mục "app/Http/Controllers/Auth". Chúng ta cần khai báo một số thư viện được sử dụng trong hàm xử lý.

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Session;

Nội dung hàm xử lý đăng nhập:

public function postLogin(Request $request) {
	// Kiểm tra dữ liệu nhập vào
	$rules = [
		'email' =>'required|email',
		'password' => 'required|min:6'
	];
	$messages = [
		'email.required' => 'Email là trường bắt buộc',
		'email.email' => 'Email không đúng định dạng',
		'password.required' => 'Mật khẩu là trường bắt buộc',
		'password.min' => 'Mật khẩu phải chứa ít nhất 8 ký tự',
	];
	$validator = Validator::make($request->all(), $rules, $messages);
	
	
	if ($validator->fails()) {
		// Điều kiện dữ liệu không hợp lệ sẽ chuyển về trang đăng nhập và thông báo lỗi
		return redirect('login')->withErrors($validator)->withInput();
	} else {
		// Nếu dữ liệu hợp lệ sẽ kiểm tra trong csdl
		$email = $request->input('email');
		$password = $request->input('password');

		if( Auth::attempt(['email' => $email, 'password' =>$password])) {
			// Kiểm tra đúng email và mật khẩu sẽ chuyển trang
			return redirect('hocsinh');
		} else {
			// Kiểm tra không đúng sẽ hiển thị thông báo lỗi
			Session::flash('error', 'Email hoặc mật khẩu không đúng!');
			return redirect('login');
		}
	}
}

Đến đây chức năng đăng nhập đã hoàn thành. Vì cơ sở dữ liệu được tạo không có tài khoản nào nên chúng ta sẽ viết tiếp form đăng ký thành viên.

Chúng ta sẽ viết form đăng ký thành viên trong thư mục "resources/views/auth" tên file là "register.blade.php" với nội dung đoạn code như sau:

@extends('templates.master')
@section('title','Trang quản lý')
@section('content')
<?php //Hiển thị thông báo thành công?>
@if ( Session::has('success') )
<div class="alert alert-success alert-dismissible" role="alert">
<strong>{{ Session::get('success') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<?php //Hiển thị thông báo lỗi?>
@if ( Session::has('error') )
<div class="alert alert-danger alert-dismissible" role="alert">
<strong>{{ Session::get('error') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger alert-dismissible" role="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<div class="container" style="margin-top: 10%">
<div class="row">
<div class="col-sm-6 col-md-4 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">ĐĂNG KÝ THÀNH VIÊN</h4>
</div>
<div class="panel-body">
<form role="form" method="POST" action="{{ url('/register') }}">
{!! csrf_field() !!}
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input class="form-control" placeholder="Họ và tên" name="name" type="text" value="{{ old('name') }}" autofocus>
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-envelope"></i></span>
<input class="form-control" placeholder="Email" name="email" type="text" value="{{ old('email') }}">
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input class="form-control" placeholder="Mật khẩu" name="password" type="password">
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input class="form-control" placeholder="Xác nhận mật khẩu" name="password_confirmation" type="password">
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-lg btn-primary btn-block">Đăng ký</button>
</div>
<center><a href="/{{ url('/login') }}">Quay về đăng nhập</a></center>
</form>
</div>
</div>
</div>
</div>
</div>
<style>
body{
background: #17568C;
}
.panel{
border-radius: 5px;
}
.panel-heading {
padding: 10px 15px;
}
.panel-title{
text-align: center;
font-size: 15px;
font-weight: bold;
color: #17568C;
}
.panel-footer {
padding: 1px 15px;
color: #A0A0A0;
}
.profile-img {
width: 120px;
height: 120px;
margin: 0 auto 10px;
display: block;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
</style>
@endsection

Trong file web.php chúng ta đã viết chức năng gọi đến đường dẫn đăng ký thành viên bằng cách gọi đến hàm getRegister() trong file "RegisterController.php" của thư mục "app/Http/Controllers/Auth" nên chúng ta sẽ viết hàm này gọi đến form đăng ký như sau:

public function getRegister() {
	return view('auth/register');
}

Tiếp theo chúng ta sẽ khai báo một số thư viện sau cho hàm hàm xử lý đăng ký như sau:

use Illuminate\Http\Request;
use Session;

Nội dung code hàm xử lý đăng ký trong file "RegisterController.php" sẽ được viết như sau:

public function postRegister(Request $request) {
    // Kiểm tra dữ liệu vào
	$allRequest  = $request->all();	
	$validator = $this->validator($allRequest);

	if ($validator->fails()) {
		// Dữ liệu vào không thỏa điều kiện sẽ thông báo lỗi
		return redirect('register')->withErrors($validator)->withInput();
	} else {   
		// Dữ liệu vào hợp lệ sẽ thực hiện tạo người dùng dưới csdl
		if( $this->create($allRequest)) {
			// Insert thành công sẽ hiển thị thông báo
			Session::flash('success', 'Đăng ký thành viên thành công!');
			return redirect('register');
		} else {
			// Insert thất bại sẽ hiển thị thông báo lỗi
			Session::flash('error', 'Đăng ký thành viên thất bại!');
			return redirect('register');
		}
	}
}

Trong đoạn code trên chúng ta sử dụng hàm kiểm tra dữ liệu nhập vào validator(), các bạn có thể chỉnh nội dung thông báo thành tiếng việt bằng cách thay đổi thành đoạn code sau:

protected function validator(array $data)
{
	return Validator::make($data,
		[
			'name' => 'required|string|max:255',
			'email' => 'required|string|email|max:255|unique:users',
			'password' => 'required|string|min:6|confirmed',
		],
		[
			'name.required' => 'Họ và tên là trường bắt buộc',
			'name.max' => 'Họ và tên không quá 255 ký tự',
			'email.required' => 'Email là trường bắt buộc',
			'email.email' => 'Email không đúng định dạng',
			'email.max' => 'Email không quá 255 ký tự',
			'email.unique' => 'Email đã tồn tại',
			'password.required' => 'Mật khẩu là trường bắt buộc',
			'password.min' => 'Mật khẩu phải chứa ít nhất 8 ký tự',
			'password.confirmed' => 'Xác nhận mật khẩu không đúng',
		]
	);
}

 

Đên đây các bạn có thể tạo một tài khoản và đăng nhập vào hệ thống. Nếu các bạn muốn phân quyền người dụng các bạn có thể thực hiện như sau:

+ Thêm một trường dữ liệu vào bảng "user" có tên là "level" miền giá trị kiểu int(10): Trường này chúng ta quy định 1 là SuperAdmin, 2 là Admin, 3 là thành viên.

+ Sửa lại hàm create() trong file "RegisterController.php" chúng ta thêm giá trị cho trường level như đoạn code sau:

protected function create(array $data)
{
	return User::create([
		'name' => $data['name'],
		'email' => $data['email'],
		'level' => '3',
		'password' => bcrypt($data['password']),
	]);
}

+  Chúng ta thêm level cho "protected $fillable " trong file "User.php" của thư mục "app" như sau:

protected $fillable = [
	'name', 'email', 'password', 'level',
];

Khi đăng ký thành viên thì level sẽ là 3 (thành viên). Chúng ta có thể hiển thị kết quả phân quyền bằng các thêm đoạn code sau trong thẻ <div class="container"></div> của file master.blade.php

@if (Auth::check())
<div>
Bạn đang đăng nhập với quyền 
@if( Auth::user()->level == 1)
	{{ "SuperAdmin" }}
@elseif( Auth::user()->level == 2)
	{{ "Admin" }}
@elseif( Auth::user()->level == 3)
	{{ "Thành viên" }}
@endif
</div>
<div class="pull-right" style="margin-top: 3px;"><a class="btn btn-primary" href="/{{ url('/logout') }}">Đăng xuất</a></div>
@endif

Trong đoạn code trên tôi có thêm nút đăng xuất và trong file web.php cũng đã tạo link đăng xuất gọi đến hàm getLogout() trong file "LogoutController.php".

Chúng ta sẽ tạo file "LogoutController.php" bằng cách gõ lệnh command sau:

php artisan make:controller Auth/LogoutController --resource

Sau khi tạo xong chúng ta vào thư mục mở file "LogoutController.php" và viết nội dung file với nội dung như sau:

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;

class LogoutController extends Controller
{
    public function __construct() {
    	$this->middleware('auth');
    }
		
	public function getLogout() {
		Auth::logout();
		return redirect('login');
	}
}

 

Vậy là chúng ta đã hoàn thành các chức năng đăng ký, đăng nhập, phân quyền và đăng xuất.

Qua bài này, mong là có thể giúp ích cho các bạn trong lập trình php với laravel.

Ngụy kim Hưng

Bài 2 - Laravel quản lý tập tin và hình ảnh

Học lập trình Laravel căn bản - Bài 2

Chào các bạn, hôm nay mình sẽ tiếp tục chia sẻ với các bạn một số chức năng thường xuyên sử dụng trong lập trình php với Laravel:

- Kiểm tra dữ liệu trước khi lưu xuống cơ sở dữ liệu (sử dụng hàm validate()).

- Upload hình ảnh hoặc file lên website và xóa file cũ khi sửa.

- Chọn giá trị từ một bảng dữ liệu khác.

Yêu cầu bài tập: 

1. Tạo một bảng dữ liệu học sinh gồm 2 thông tin (tên học sinh, số điện thoại) và viết chức năng thêm, sửa, xóa, hiển thị danh sách (Lập trình Laravel căn bản - Bài 1).

2. Thêm trường dữ liệu (hình thẻ, lý lịch, khối) cho bảng học sinh. Trong đó, trường hình thẻ là đường dẫn hình thẻ của học sinh được upload lên và lý lịch là đường dẫn file word lý lịch của của học sinh được upload lên, khối là trường dữ liệu được kết từ bảng khối (id, tenkhoi).

Sau khi chúng ta thực hiện xong yêu cầu đầu tiên từ bài tập trước, chúng ta sẽ tiếp tục với yêu cầu thứ 2.

Chúng ta thêm 3 trường dữ liệu trên như sau:

+ hinhthe: varchar(255)

+ lylich: varchar(255)

+ khoi: int (10)

Và tạo bảng dữ liệu tên "tbl_khoi" với 2 trường dữ liệu sau:

+ id: int(10)

+ tenkhoi: varchar(255)

Sau khi tạo bảng dữ liệu "tbl_khoi" xong các bạn có thể viết quản lý thêm, sửa, xóa như đã được hướng dẫn từ bài trước và thêm vào các khối như KHỐI 6, KHỐI 7, KHỐI 8, KHỐI 9.

Tiếp theo chúng ta sẽ chỉnh sửa lại một số function và form.

- Function create(): hàm hiển thị trang thêm học sinh của file "HocSinhController.php"

Chúng ta sẽ chỉnh sửa lại hàm này lại như sau:

public function create()
{
	//Lấy danh sách bảng khối
	$dskhoi = DB::table('tbl_khoi')->select('id','tenkhoi')->get();
	//Hiển thị trang thêm học sinh
	return view('hocsinh.create')->with('dskhoi',$dskhoi);
}

- Trong file "create.blade.php" các bạn thêm dòng code sau để hiển thị kết quả kiểm tra dữ liệu không thỏa điều kiện validate() được viết trong function store(Request $request) của file "HocSinhController.php".

@if ($errors->any())
<div class="alert alert-danger alert-dismissible" role="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif

Sửa lại form thêm mới học sinh:

+ Thêm đoạn code sau để có thể upload file trong thẻ form thêm học sinh: enctype="multipart/form-data"

+ Thêm 3 trường dữ liệu nhập vào trong form thêm học sinh:

<div class="form-group">
<label for="hinhthe">Chọn hình thẻ</label>
<input type="file" class="form-control" id="hinhthe" name="hinhthe"/>
</div>
<div class="form-group">
<label for="lylich">Chọn file lý lịch</label>
<input type="file" class="form-control" id="lylich" name="lylich"/>
</div>
<div class="form-group">
<label for="khoi">Chọn khối</label>
<select class="form-control" id="khoi" name="khoi" required>
<option value="">-- Chọn khối --</option>
@foreach($dskhoi as $khoi)
<option value="{!! $khoi->id !!}">{!! $khoi->tenkhoi !!}</option>
@endforeach
</select>
</div>

- Trong file "HocSinhController.php" chúng ta chỉnh sửa nội dung function store() như sau:

public function store(Request $request)
{		
	//Kiểm tra giá trị tenhocsinh, sodienthoai, khoi
	$this->validate($request, 
		[
			//Kiểm tra giá trị rỗng
			'tenhocsinh' => 'required',
			'sodienthoai' => 'required',
			'khoi' => 'required',
		],			
		[
			//Tùy chỉnh hiển thị thông báo
			'tenhocsinh.required' => 'Bạn chưa nhập tên học sinh!',
			'sodienthoai.required' => 'Bạn chưa nhập số điện thoại!',
			'khoi.required' => 'Bạn chưa chọn khối!',
		]
	);
	
	//Lưu hình thẻ khi có file hình
	$gethinhthe = '';
	if($request->hasFile('hinhthe')){
		//Hàm kiểm tra dữ liệu
		$this->validate($request, 
			[
				//Kiểm tra đúng file đuôi .jpg,.jpeg,.png.gif và dung lượng không quá 2M
				'hinhthe' => 'mimes:jpg,jpeg,png,gif|max:2048',
			],			
			[
				//Tùy chỉnh hiển thị thông báo không thõa điều kiện
				'hinhthe.mimes' => 'Chỉ chấp nhận hình thẻ với đuôi .jpg .jpeg .png .gif',
				'hinhthe.max' => 'Hình thẻ giới hạn dung lượng không quá 2M',
			]
		);
		
		//Lưu hình ảnh vào thư mục public/upload/hinhthe
		$hinhthe = $request->file('hinhthe');
		$gethinhthe = time().'_'.$hinhthe->getClientOriginalName();
		$destinationPath = public_path('upload/hinhthe');
		$hinhthe->move($destinationPath, $gethinhthe);
	}
	
	//Lưu file lý lịch khi có file
	$getlylich = '';
	if($request->hasFile('lylich')){
		$this->validate($request, 
			[
				//Kiểm tra đúng file đuôi .doc hay .docx và dung lượng không quá 5M
				'lylich' => 'mimes:doc,docx|max:5120',
			],			
			[
				//Tùy chỉnh hiển thị thông báo không thõa điều kiện
				'lylich.mimes' => 'Chỉ chấp nhận lý lịch với đuôi .doc .docx',
				'lylich.max' => 'Lý lịch giới hạn dung lượng không quá 5M',
			]
		);
		
		//Lưu file vào thư mục public/upload/lylich
		$lylich = $request->file('lylich');
		$getlylich = time().'_'.$lylich->getClientOriginalName();
		$destinationPath = public_path('/upload/lylich');
		$lylich->move($destinationPath, $getlylich); 
	}
	
	//Lấy giá trị học sinh đã nhập
	date_default_timezone_set("Asia/Ho_Chi_Minh");
	$allRequest  = $request->all();
	$tenhocsinh  = $allRequest['tenhocsinh'];
	$sodienthoai = $allRequest['sodienthoai'];
	$khoi = $allRequest['khoi'];
	
	//Gán giá trị vào array
	$dataInsertToDatabase = array(
		'tenhocsinh'  => $tenhocsinh,
		'sodienthoai' => $sodienthoai,
		'hinhthe' => $gethinhthe,
		'lylich' => $getlylich,
		'khoi' => $khoi,
		'created_at' => date('Y-m-d H:i:s'),
		'updated_at' => date('Y-m-d H:i:s'),
	);
	
	//Insert vào bảng tbl_hocsinh
	$insertData = DB::table('tbl_hocsinh')->insert($dataInsertToDatabase);
	if ($insertData) {
		Session::flash('success', 'Thêm mới học sinh thành công!');
	}else {                        
		Session::flash('error', 'Thêm thất bại!');
	}
	
	//Thực hiện chuyển trang
	return redirect('hocsinh/create');
}

- Sửa chức năng hiển thị danh sách học sinh:

+ Sửa function index() trong file "HocSinhController.php"

public function index()
{
	//Lấy danh sách học sinh từ database
	$getData = DB::table('tbl_hocsinh as hs')
				->leftJoin('tbl_khoi as khoi', 'hs.khoi', '=', 'khoi.id')
				->select('hs.id','hs.tenhocsinh','hs.sodienthoai','hs.hinhthe','hs.lylich','khoi.tenkhoi')->get();
				
	//Gọi đến file list.blade.php trong thư mục "resources/views/hocsinh" với giá trị gửi đi tên listhocsinh = $getData
	return view('hocsinh.list')->with('listhocsinh',$getData);
}

+ Chỉnh sửa nội dung file "list.blade.php" như đoạn code sau:

@extends('templates.master')
@section('title','Quản lý học sinh')
@section('content')
<?php //Hiển thị thông báo thành công?>
<div class="page-header"><h4>Quản lý học sinh</h4></div>
@if ( Session::has('success') )
<div class="alert alert-success alert-dismissible" role="alert">
<strong>{{ Session::get('success') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<?php //Hiển thị thông báo lỗi?>
@if ( Session::has('error') )
<div class="alert alert-danger alert-dismissible" role="alert">
<strong>{{ Session::get('error') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<?php //Hiển thị danh sách học sinh?>
<style>
#myImg { border-radius: 5px; cursor: pointer; transition: 0.3s; }
#myImg:hover {opacity: 0.7;}
/* The Modal (background) */
.modal { display: none; position: fixed; z-index: 9999; padding-top: 50px; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgb(0,0,0); background-color: rgba(0,0,0,0.9);}
/* Modal Content (image) */
.modal-content { margin: auto; display: block; width: 50%; max-width: 400px; }
/* Caption of Modal Image */
#caption { margin: auto; display: block; width: 80%; max-width: 700px; text-align: center; color: #ccc; padding: 10px 0; height: 50px; }
/* Add Animation */
.modal-content, #caption { -webkit-animation-name: zoom; -webkit-animation-duration: 0.6s; animation-name: zoom; animation-duration: 0.6s; }
@-webkit-keyframes zoom { from {-webkit-transform:scale(0)} to {-webkit-transform:scale(1)} }
@keyframes zoom { from {transform:scale(0)} to {transform:scale(1)} }
/* The Close Button */
.close { position: absolute; top: 15px; right: 35px; color: #f1f1f1; font-size: 40px; font-weight: bold; transition: 0.3s; }
.close:hover, .close:focus { color: #bbb; text-decoration: none; cursor: pointer; }
/* 100% Image Width on Smaller Screens */
@media only screen and (max-width: 700px){
.modal-content {
width: 100%;
}
}
</style>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="table-responsive">
<p><a class="btn btn-primary" href="/{{ url('/hocsinh/create') }}">Thêm mới</a></p>
<table id="DataList" class="table table-bordered table-hover">
<thead>
<tr>
<th>STT</th>
<th>Tên học sinh</th>
<th>Số điện thoại</th>
<th>Hình thẻ</th>
<th>File lý lịch</th>
<th>Khối</th>
<th>Sửa</th>
<th>Xóa</th>
</tr>
</thead>
<tbody>
<?php //Vòng lập foreach lấy giá vào bảng?>
@foreach($listhocsinh as $key => $hocsinh)
<tr>
<td style="text-align: center; vertical-align: middle;">{{ $key+1 }}</td>
<td style="vertical-align: middle;">{{ $hocsinh->tenhocsinh }}</td>
<td style="vertical-align: middle;">{{ $hocsinh->sodienthoai }}</td>
<td style="text-align: center; vertical-align: middle; width: 10%;">
@if($hocsinh->hinhthe != '')
<img onclick="MymodalImage(this);" alt="{{ $hocsinh->tenhocsinh }}" src="/public/upload/hinhthe/{{ $hocsinh->hinhthe }}" style="cursor: zoom-in;" width="60"/>
@else
<img onclick="MymodalImage(this);" alt="{{ $hocsinh->tenhocsinh }}" src="/public/upload/hinhthe/noimage.png" style="cursor: zoom-in;" width="60"/>
@endif
<td style="text-align: center; vertical-align: middle; width: 10%;">
@if($hocsinh->lylich != '')
<a class="btn btn-primary" href="/public/upload/lylich/{{ $hocsinh->lylich }}">Download về máy</a>
@else
<img onclick="MymodalImage(this);" src="/public/upload/lylich/nofile.png" alt="{{ $hocsinh->tenhocsinh }}" style="cursor: zoom-in;" width="60"/>
@endif
</td>
<td style="text-align: center; vertical-align: middle;">
{{ $hocsinh->tenkhoi }}
</td>
<td style="text-align: center; vertical-align: middle;"><a href="/hocsinh/{{ $hocsinh->id }}/edit">Sửa</a></td>
<td style="text-align: center; vertical-align: middle;"><a href="/hocsinh/{{ $hocsinh->id }}/delete">Xóa</a></td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
<div id="myModal" class="modal">
<span class="close">&times;</span>
<img class="modal-content" id="img01">
<div id="caption"></div>
</div>
<script>
function MymodalImage(e)
{
// Get the modal
var modal = document.getElementById('myModal');
// Get the image and insert it inside the modal - use its "alt" text as a caption
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
modal.style.display = "block";
modalImg.src = e.src;
captionText.innerHTML = e.alt;
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
}
</script>
@endsection

+ Trong đoạn code trên. trường hợp không có file hình thẻ sẽ hiển thị hình ảnh mặc định có tên là "noimage.png" và nếu như không có file lý lịch sẽ hiển thị hình ảnh mặc định là "nofile.png". Các bạn có thể lấy hình ảnh noimage trên mạng mà các bạn thích vào thư mục "public/hocsinh/hinhthe" và thư mục "public/hocsinh/lylich".

- Sửa chức năng sửa học sinh:

+ Sửa nội dung function edit($id) trong file "HocSinhController.php" với nội dung code sau:

public function edit($id)
{
	//Lấy dữ liệu bảng tbl_khoi từ Database
	$dskhoi = DB::table('tbl_khoi')->select('id','tenkhoi')->get();
	
	//Lấy dữ liệu từ Database với các trường được lấy và với điều kiện id = $id
	$getData = DB::table('tbl_hocsinh')->select('id','tenhocsinh','sodienthoai','hinhthe','lylich','khoi')->where('id',$id)->get();
	
	//Gọi đến file edit.blade.php trong thư mục "resources/views/hocsinh" với giá trị gửi đi tên getHocSinhById = $getData và dskhoi = $dskhoi
	return view('hocsinh.edit', ['getHocSinhById' => $getData, 'dskhoi' => $dskhoi]);
}

+ Sửa nội dung form sửa học sinh: 

Thêm đoạn code sau để hiển thị kết quả kiểm tra của hàm validate() không thỏa điều kiện.

@if ($errors->any())
<div class="alert alert-danger alert-dismissible" role="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif

Thêm đoạn code sau để có thể upload file trong thẻ form: enctype="multipart/form-data"

Thêm 3 trường dữ liệu nhập vào form sửa với đoạn code sau:

<div class="form-group">
<label for="hinhthe">Chọn hình thẻ mới</label>
<input type="file" class="form-control" id="hinhthe" name="hinhthe"/>
</div>
<div class="form-group">
<label for="lylich">Chọn file lý lịch mới</label>
<input type="file" class="form-control" id="lylich" name="lylich"/>
</div>
<div class="form-group">
<label for="khoi">Chọn khối</label>
<select class="form-control" id="khoi" name="khoi" required>
<option value="">-- Chọn khối --</option>
@foreach($dskhoi as $khoi)
<option value="{!! $khoi->id !!}" {!! ($getHocSinhById[0]->khoi == $khoi->id) ? 'selected="selected"' : null !!}>{!! $khoi->tenkhoi !!}</option>
@endforeach
</select>
</div>

Sửa function update(Request $request) trong file "HocSinhController.php" với nội dung code như sau:

public function update(Request $request)
{
	//Cap nhat sua hoc sinh
	date_default_timezone_set("Asia/Ho_Chi_Minh");	

	//Kiểm tra giá trị tenhocsinh, sodienthoai, khoi
	$this->validate($request, 
		[
			'tenhocsinh' => 'required',
			'sodienthoai' => 'required',
			'khoi' => 'required',
		],			
		[
			'tenhocsinh.required' => 'Bạn chưa nhập tên học sinh!',
			'sodienthoai.required' => 'Bạn chưa nhập số điện thoại!',
			'khoi.required' => 'Bạn chưa chọn khối!',
		]
	);
	
	//Thực hiện lưu thay đổi hình thẻ khi có file
	if($request->hasFile('hinhthe')){
		$this->validate($request, 
			[
				'hinhthe' => 'mimes:jpg,jpeg,png,gif|max:2048',
			],			
			[
				'hinhthe.mimes' => 'Chỉ chấp nhận hình thẻ với đuôi .jpg .jpeg .png .gif',
				'hinhthe.max' => 'Hình thẻ giới hạn dung lượng không quá 2M',
			]
		);
		
		//Xóa file hình thẻ cũ
		$getHT = DB::table('tbl_hocsinh')->select('hinhthe')->where('id',$request->id)->get();
		if($getHT[0]->hinhthe != '' && file_exists(public_path('upload/hinhthe/'.$getHT[0]->hinhthe)))
		{
			unlink(public_path('upload/hinhthe/'.$getHT[0]->hinhthe));
		}
		
		//Lưu file hình thẻ mới
		$hinhthe = $request->file('hinhthe');
		$gethinhthe = time().'_'.$hinhthe->getClientOriginalName();
		$destinationPath = public_path('upload/hinhthe');
		$hinhthe->move($destinationPath, $gethinhthe);
		$updateHinhThe = DB::table('tbl_hocsinh')->where('id', $request->id)->update([
			'hinhthe' => $gethinhthe
		]);
	}
	
	//Thực hiện lưu thay đổi lý lịch khi có file
	if($request->hasFile('lylich')){
		$this->validate($request, 
			[
				'lylich' => 'mimes:doc,docx|max:5120',
			],			
			[
				'lylich.mimes' => 'Chỉ chấp nhận lý lịch với đuôi .doc .docx',
				'lylich.max' => 'Lý lịch giới hạn dung lượng không quá 5M',
			]
		);
		
		//Xóa file lý lịch cũ
		$getLL = DB::table('tbl_hocsinh')->select('lylich')->where('id',$request->id)->get();
		if($getLL[0]->lylich != '' &&file_exists(public_path('upload/lylich/'.$getLL[0]->lylich)))
		{
			unlink(public_path('upload/lylich/'.$getLL[0]->lylich));
		}
		
		//Lưu file lý lịch mới
		$lylich = $request->file('lylich');
		$getlylich = time().'_'.$lylich->getClientOriginalName();
		$destinationPath = public_path('upload/lylich');
		$lylich->move($destinationPath, $getlylich);
		$updateLylich = DB::table('tbl_hocsinh')->where('id', $request->id)->update([
			'lylich' => $getlylich
		]);
	}
	
	//Thực hiện câu lệnh update với các giá trị $request trả về
	$updateData = DB::table('tbl_hocsinh')->where('id', $request->id)->update([
		'tenhocsinh' => $request->tenhocsinh,
		'sodienthoai' => $request->sodienthoai,
		'khoi' => $request->khoi,
		'updated_at' => date('Y-m-d H:i:s')
	]);
	
	//Kiểm tra lệnh update để trả về một thông báo
	if ($updateData) {
		Session::flash('success', 'Sửa học sinh thành công!');
	}else {                        
		Session::flash('error', 'Sửa thất bại!');
	}
	
	//Thực hiện chuyển trang
	return redirect('hocsinh/'.$request->id.'/edit');
}

Chức năng xóa không ảnh thưởng nên chúng ta không cần sửa. Bạn có thể thêm xóa file hình thẻ và file lý lịch khi xóa học sinh như đã ghi chú trong đoạn code trên.

Vậy là chúng ta đã hoàn thành yêu cầu bài số 2. Qua bài này chúng ta có thể đúc kết được những kinh nghiệm sau:

- Sử dùng hàm validate() để kiểm tra dữ liệu nhập vào trước khi lưu xuống Database, giúp tránh bị lỗi câu lệnh sql và kiểm tra file upload không đúng định dạng.

- Muốn upload file lên website từ form chúng ta cần thêm thuộc tính sau cho thẻ <form>: enctype="multipart/form-data"

- Cách xóa file cũ để tối ưu dung lượng sử dụng trên website: unlink('đường dẫn file hình')  - Lưu ý kiểm tra tồn tại file với hàm file_exists() trước khi xóa để tránh bị lỗi.

Tôi sẽ hướng dẫn các bạn thực hiện form đăng nhập và phân quyền trong bài tập tiếp theo, mong các bạn đọc giả ủng hộ.

Chúc các bạn thực hiện thành công dự án của mình!

Ngụy Kim Hưng