Professional Documents
Culture Documents
3. TUYỂN DỤNG.....................................................................................................3
1. PHP CORE............................................................................................................6
a. Lambda...............................................................................................................6
b. Clorsure...............................................................................................................7
c. Trait.....................................................................................................................9
2. DESIGN PATTERN............................................................................................12
a. Factory Pattern..................................................................................................12
b. Singleton Pattern...............................................................................................15
c. Prototype Pattern...............................................................................................17
e. Builder Pattern..................................................................................................22
3. LARAVEL...........................................................................................................23
e. Middleware.......................................................................................................25
4. VUEJS.................................................................................................................27
e. Component........................................................................................................31
LỜI CẢM ƠN
Sau hai tháng em thực tập tại công ty, mọi người trong công ty đã giúp đỡ em rất nhiều, em
cũng học hỏi được khá nhiều kinh nghiệm trong lĩnh vực phát triển ứng dụng web mà lúc trước em
chưa bao giờ biết tới, mở mang khai sáng cho em thêm nhiều kiến thức. Cảm ơn team anh Đôn và các
anh chị đã giúp đỡ em trong thời gian thực tập, đặc biệt là trainer thầy Phan Thanh Nhuần đã giúp em
trong thời gian thực tập rất nhiều, thầy bám sát tiến độ thực tập tiến độ của em, chỉ ra những điểm em
còn thiếu sót trong quá trình thực tập. Thực sự qua kì thực tập em cảm thấy mình trưởng thành nhiều
hơn, và có nhiều kinh nghiệm. Em cảm ơn quý công ty rất nhiều!
Em xin cảm ơn cô Đỗ Thị Minh Phụng – giảng viên đã hướng dẫn em viết báo cáo thực tập
trong thời gian vừa qua.
Xin chân thành cảm ơn cô, thầy cùng quý anh chị trong công ty!
Thời gian làm việc: Thứ 2 đến thứ 6 (8:00 đến 17:00)
Ngày thành lập công ty: 26/11/2012
Đối tác chính: Wakka Inc Co.,Ltd.
2. CÔNG NGHỆ SỬ DỤNG
Một số công nghệ mà công ty sử dụng
// Hàm thường
function helloWorld()
{
return "Hello world";
}
// Hàm Lambda
function ()
{
return "Hello world";
}
Sử dụng hàm lamda: Bởi vì các hàm này không có tên, chúng ta không thể gọi nó
như một chức năng thường xuyên. Thay vào đó ta phải gán nó vào một biến hoặc cho
vào 1 hàm khác khác như là một tham số.
Cách sử dụng
// Hàm ẩn danh
// gán cho 1 biến
$hello = function () {
return "Hello world";
}
Tại sao sử dụng lamda: Lambdas rất hữu dụng, bởi vì chúng ta không cần phải tạo
hẳn 1 hàm cho 1 lần sử dụng duy nhất.
Thông thường, chúng ta sẽ cần một hàm để làm một công việc, nhưng nó không có
nghĩa là chúng ta sẽ dùng nó trong phạm vi global. Thay vì có một hàm sử dụng một
lần và sau đó bỏ đi để nó ở đó, chúng ta có thể sử dụng một Lambda để thay thế.
Tất nhiên, chúng ta có thể sử dụng chức năng create_function trong PHP. Điều
này về cơ bản là giống nhau:
Create_function trong PHP
b. Clorsure
Closure là một class sử dụng anonymous function, nói cách khác Closure về cơ
bản giống hàm nặc danh, ngoài ra nó có thể truy cập các biến bên ngoài phạm
vi mà nó tạo ra. Closure đóng gói phạm vi của nó, nó không có quyền truy
nhập vạo phạm vi mà nó được định nghĩa hoặc thực hiện. Nó có thể kế thừa
các biến từ phạm vi cha (nơi closure được định nghĩa) vào closure với từ khóa
use.
Ví dụ minh họa:
thêm một
dấu &. Một dấu & trước một biến có nghĩa đây là một reference và vì vậy các
biến ban đầu cũng được cập nhật.
PHP hay Ruby đều là những ngôn ngữ hướng đối tượng chỉ hỗ trợ single
inheritance(đơn kế thừa). Để khắc phục những giới hạn của đơn kế thừa trong
việc sử dụng lại source code, từ PHP 5.4 trở đi PHP hỗ trợ Traits là cơ chế
giúp cho lập trình viên có thể sử dụng lại các phương thức từ các class khác
nhau một cách dễ dàng hơn. Một trait tương tự như là 1 class nhưng chỉ nhằm
mục đích nhóm chức năng lại. Và trait không thể khởi tạo giống class và trait
sinh ra để bổ sung cho kế thừa truyền thống. Thay vì phải kế thừa 1 class hay
interface để sử dụng lại 1 nhóm chức năng, thì với trait bạn không cần phải kế
thừa vẫn có thể sử dụng được
Đọc xong khái niệm chắc còn mơ hồ lắm đúng không nào. Ok, chúng ta tìm
hiểu cách sử dụng Trait qua các ví dụ sau đây nhé:
Giả sử có ví dụ minh họa sau đây:
Nếu ta muốn sử dụng lại method listUsers trong class Database cho class Users hoặc
class Report thì làm thế nào ? Trong trường hợp này thì chắc chắn các bạn sẽ nghĩ
đến từ khóa extends đúng không? Và sẽ viết như thế này:
Qua ví dụ này chúng ta thấy không cần extends nhưng chúng ta vẫn sử dụng được
các method listUsers() ở các class như : Users, Report
Sử dụng nhiều trait cùng một lúc
2. DESIGN PATTERN
Trang web tham khảo 34 Design Pattern và học design nổi tiếng:
https://refactoring.guru/design-patterns
Tại sao phải chọn Design Pattern: Mục tiêu chính của việc chọn design Pattern là tối
ưu hóa code và có tính tái sử dụng.
a. Factory Pattern
Định nghĩa: Factory Pattern thuộc nhóm khởi tạo (Creational Pattern)
Nhiệm vụ chính: của Factory Pattern là quản lý và trả về các đối tượng theo
yêu cầu, giúp cho việc khởi tạo đổi tượng một cách linh hoạt hơn.
Giải quyết vấn đề tạo một đối tượng mà không cần thiết chỉ ra một cách
chính xác lớp nào sẽ được tạo.
Sử dụng Factory Pattern trong trường hợp nào?
o 1. Tạo ra một cách mới trong việc khởi tạo các object thông qua một
interface chung
o 2. Bao gói được quá trình khởi tạo object, giấu đi được xử lý logic
của việc khởi tạo
o 3. Giảm sự phụ thuộc giữa các module, logic với các class cụ thể mà
chỉ phụ thuộc với interface hoặc abstract class.
o Lớp Circle
o Lớp Square
o Lớp Rectangle
o Lớp ShapeFactory đóng vai trò như một nhà máy để tạo ra các Shape
Hàm main()
b. Singleton Pattern
Đôi khi, trong quá trình phân tích thiết kế một hệ thống, chúng ta mong muốn
có những đối tượng cần tồn tại duy nhất và có thể truy xuất mọi lúc mọi nơi.
Làm thế nào để hiện thực được một đối tượng như thế khi xây dựng mã nguồn?
Chúng ta có thể nghĩ tới việc sử dụng một biến toàn cục (global variable :
public static final). Tuy nhiên, việc sử dụng biến toàn cục nó phá vỡ quy tắc của
OOP (encapsulation). Để giải bài toán trên, người ta hướng đến một giải pháp
là sử dụng Singleton pattern.
Singleton Pattern thuộc nhóm mẫu thiết kế khởi tạo. Mẫu thiết kế phần mềm để
hạn chế sự khởi tạo của lớp đối tượng
Đặc điểm của Singleton Pattern
1. Hàm constructor của SingletonObject PHẢI là Private
2. Giá trị biến static instance PHẢI là Private
3. Chỉ có một phương thức public static để return instance được khởi tạo ở
trên.
Sử dụng khi nào?
o Vì class dùng Singleton chỉ tồn tại 1 Instance (thể hiện) nên nó
thường được dùng cho các trường hợp giải quyết các bài toán cần
truy cập vào các ứng dụng như: Shared resource, Logger,
Configuration, Caching,
Thread pool, …
o Một số design pattern khác cũng sử dụng Singleton để triển khai:
Abstract Factory, Builder, Prototype, Facade,…
o Đã được sử dụng trong một số class của core java như:
java.lang.Runtime, java.awt.Desktop.
Chương trình minh họa:
o Lớp Single Object
o Hàm Main
c. Prototype Pattern
Khi tạo một đối tượng mới các thuộc tính của đối tượng chưa được khởi tạo,
ngoại trừ trường hợp default hoặc được khởi tạo trong trong constructor. Tuy
nhiên chúng ta có một cách tha vì tạo một đối tượng mới thi ta muốn sao chép
một đối tượng đã tồn tại chúng ta có thể làm được điều này khi implements
theo Proptotype Pattern.
Pattern này cung cấp một trong những cách tốt nhất để tạo ra một đối tượng
thay vì tạo ra Object bằng từ khóa new, Prototype pattern sử dụng việc cloning
(copy nguyên mẫu của Object).
Sử dụng khi nào?
o Khi việc tạo một object tốn nhiều chi phí và thời gian trong khi bạn đã có một
object tương tự tồn tại.
o Khi copy từ object ban đầu sang object mới và thay đổi giá trị một số thuộc
tính nếu cần
Hình minh họa
o PHPBookPrototype
o SQLBookPrototype
o BookPrototype
Vấn đề
Giả lập một của hàng nội thất gồm những lớp sau đây:
o Danh sách những sản phẩm nội thất là các class: Chair, Sofa, CoffeeTable
o Mỗi loại nội thất có các biến thể khác nhau như
là: Mordern, Victorian, ArtDeco
Vấn đề ở đây là làm sao: có cách để tạo ra các đồ vật nội thất riêng lẻ để
chúng phù hợp với các đồ vật khác trong cùng một gia đình.
Hơn nửa bạn không muốn thay đổi code hiện tại khi thêm một sản phẩm
mới trong chương trình, hoặc là các nhà cung cập nội thất không muốn
thay đổi core code xảy ra nhiều lần
e. Builder Pattern
Builder Pattern là một mẫu thiết kế thuộc nhóm khởi tạo. Mẫu thiết kế này cho
phép lập trình viên tạo ra những đối tượng phức tạp nhưng chỉ cần thông qua
các câu lệnh đơn giản để tác động nên các thuộc tính của nó
Các hàm constructor trong một class có thể lấy các tham số truyền vào param
vấn đề đối tượng có rất là nhiều param giả sử đến hàng chục param
2. Chúng ta có thể viết nhiều constructor theo từng trường hợp những trường
không bắt buộc thì gán NULL. Tuy nhiên việc này khó đọc, nhiều constructor
nếu tham số lớn, khó đọc, khó bảo trì, chương trình chạy chậm,
Vì vậy, người ta mong muốn giao công việc này cho một đối tượng chịu trách
nhiêm khởi tạo và chia việc khởi tạo đối tượng riêng lẽ, từng bước, để có thể
tiến hành khởi tạo riêng biệt ở các hoàn cảnh khác nhau. Và giải pháp được đưa
ra là sử dụng Builder Pattern như một người xây dựng.
Muốn thay đổi thiết kế cho việc lồng nhau của các hàm khởi tạo (Telescoping
Constructor Pattern). Vấn đề này phát sinh khi lập trình viên làm việc với một
lớp mà có chứa rất nhiều các thuộc tính và cần phải tạo ra nhiều hàm khởi tạo
với số lượng các thuộc tính tăng dần.
Khi cần tạo ra một đối tượng phức tạp, một đối tượng mà thuật toán để tạo tạo
lập các thuộc tính là độc lập đối với các thuộc tính khác.
3. LARAVEL
a. Xác thực trong Laravel (Authentication)
o $user = Auth::user();
o$id = Auth::id();
o$check = Auth::check();
o Ham Logout ví dụ minh họa
$taikhoan = Auth::check(); //TRUE
$taikhoan = Auth::logout();
$taikhoan = Auth::check(); // FALSE
b. Phân quyền trong Laravel (Authorization)
Authorization là cơ chế phân quyền người dùng trong laravel
Laravel cung cấp hai cách cơ bản cho việc phân quyền người dùng: Gate và Policy
c. Session trong Laravel
Khi đăng nhập tài khoản sẽ được lưu tự động vào SESSION_DRIVER mà ta tùy
chọn ở đây SESSION_DRIVER có thể là ['file','database','redis',. ]
Mặc định set biến môi trường của SESSIONS nằm trong file .env
Mặc định Session trong laravel sẽ được lưu trong file
e. Middleware
Middleware là giải pháp lọc HTTP Request, Middle định nghĩa request được chấp
nhận hay không.
Trong Laravel có rất nhiều middle ware được định nghĩa sẵn như là: Tất cả các
Middleware được dựng trong thư mục app/HTTP/middleware.
Route::[Put/GET/.....]('<tên route>',function(){})->middleware(['tên
middleware1','tên middleware2',.. . .,'tên middlewareN'])
4. VUEJS
VueJS là một framework dùng để xây dựng giao diện người dùng
Trang gốc vuejs: https://vuejs.org/
VueJS được thiết kế để cho phép người dùng thiết kế từng bước
o Xây dựng <template>
o Xây dựng <script>
o Xây dựng <style>
Dễ học, dễ sử dụng, cấu trúc quá phức tạp
Tích hợp nhiều thư viện có sẵn và kèm theo
a. Cách cài đặt VueJS
Cài đặt VueJS bằng CDN bằng các câu lệnh sau đây
<script
src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
# latest stable
$ npm install vue
Ví dụ 1: Về data và method
• Trong VueJS thường sử dụng những directive hay còn gọi là các thành phần trong
VueJS những thành phần này bắt đầu bằng v-
• Tiếp theo sao là những thuộc tính cài đặt sẵn
Ví dụ v-bind:href
Ví dụ v-bind:style
• Các thành phần hậu tố Regex
• Directive v-bind
Cú pháp mustache không dùng được bên trong các thuộc tính HTML. Thay
vào đó, bạn hãy dùng directive v-bind:
Ví dụ <a href={{link}}> </a> ERROR
Để hỗ trợ được công việc đó trong VueJS hỗ trợ Directive v-bind
Cách sử dụng đúng <a v-bind:href= “link“></a>
Một số v-bind thông dụng:
Thuộc tính v-bind:href cho phép ta thêm đường dẫn URL
Thuộc tính v-bind:style Cho phép ta định dạng style bằng VueJS
Thuộc tính v-bind:id cho phép sử dụng thuộc tính id trong VueJS
Tác dụng của việc sử dụng của những thẻ này cho phép ta sử
dụng thuộc tính dynamic (thuộc tính động)
Directive v-bind:<Atrr> có thể viết tắt là :<Attr>
• Directive v-if, v-else
Directive v-if là Dùng để kiểm tra điều kiện của một câu lệnh
Syntax v-if
• Directive v-for
Dùng để render danh sách, một số tài tiếng anh gọi là map danh sách.
Directive v-for mapping danh sách dựa trên một mảng
Cú pháp duyệt mảng v-for như sau item in items
• Directive v-on
Thể hiện bậc một sự kiện
Syntax
<tag v-on:<Event> = “func"></tag>
d. Phân biệt computed và methods
• Computed
• Methods
Ví dụ minh họa về sự khác biệt của hai cách tiếp cận này là:
Ví dụ cho hai số a + b thực phép toán cộng trước rồi hai số a và b thuộc một lớp Vue
chung với Computed và Methods, giả sử ta nhập số c thì kết quả phép tính cộng a + b +
c bằng computed sẽ dùng kết quả đã tính a + b bên trên để đưa ra kết quả là 11 số lần
chạy là 1, còn cách tiếp cận methods sẽ tính lại 3 + 2 rồi mới tiếp cộng số c điều này sẽ
xảy ra 2 lần chạy.
e. Component
Component được xem như là một phần mạnh mẽ nhất của VueJS.
Component giúp chúng ta gom code HTML thành một để tái sử dụng. Ở một mức độ
cao thì component là một thành phần được Vue.js biên dịch để xử lý các hành vi
File HTML
Trình tự truyền dữ liệu từ thành phần cha sang thành phần con. Đầu tiên nhập mã và
nhập chuỗi lưu vào v-model với data là mamau và text. Dữ liệu nhập vào sẽ lưu vào
v-model mamau và text
Mỗi lần mã màu thay đổi thì được gán theo dạng CSS color màu vào biến styleapp.
Ví dụ người dùng nhập 999fff thì hàm getMau: _.debounce() có chức năng xử lý biến
this.styleapp = “color:” + “#” + this.mamau. Sau khi câu lệnh này thực hiện xong
styleapp sẽ được kết quả “color:#999fff”
Component được định nghĩa style bằng biến stylemin, và dữ liệu hiển thị ra viết dưới
biến {{dataheader}}
Component <lp-header> định nghĩa mapping biến text vào thuộc tính “dataheader” và
biến styleapp vào thuộc tính “stylemin”.
Kết quả như hình minh họa
Nút phong to gửi sự kiện bằng $emit() vào một biến enlarge-text. Sau mỗi lần nhấn nút
phóng to thì postFontSize thuộc tính tăng lên 0.1 và sẽ truyền lên thuộc tính fontSize.
5. VIẾT ỨNG DỤNG API LARAVEL
Mô tả vấn đề: CSDL chứa danh sách một loạt các email có đuôi domain là
@gmail.com, @yahoo.co.jp @yahoo.com @lampart-vn.com.
Danh sách domain được lưu vào CSDL
Lược đồ CSDL đơn giản như sau:
Cài đặt CSDL bằng Laravel bằng chức năng Migration mà laravel dựng sẵn như
sau:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('domains');
}
}
Migration bảng Email
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('email');
}
}
Tạo dữ liệu bảng Domain gồm 4 loại domain
<?php
use Illuminate\Database\Seeder;
use App\Domain;
<?php
use App\Email;
use Faker\Generator as Faker;
return [
'email' => preg_replace('/@example\..*/', $domains[$randomDomain], $faker->unique()-
>safeEmail),
];
});
Tạo 90 Email bằng Factory vừa tạo
<?php
use Illuminate\Database\Seeder;
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|
| API Routes
|
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get('getdomain','Api\DomainController@getDomain')->name('domain.getdomain');
Route::get('getemail/{nameMail?}','Api\DomainController@getEmail')->name('mail.getemail');
Viết Controller Domain để xử lý từng route
<?php
namespace App\Http\Controllers\Api;
use App\Domain;
use App\Email;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
Giao diện đơn giản khi người dùng nhập abc combobox sẽ gọi API lấy các
domain có sẵn trong database bằng việc gợi ý những domain có sẵn:
@blur="getAutocomplete()"
outlined
dense
hide-no-data
></v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-card>
</template>
<script>
import _ from "lodash";
import axios from "axios";
export default {
name: "HelloWorld",
data: () => ({
post: [],
valueCase3: null,
answer: "",
search: null,
items: []
}),
watch:
{ search(
){
if (this.search != null) {
this.getEmail();
}
Thực tập doanh nghiệp
Giáo viên hướng dẫn: ThS. Đỗ Thị Minh Phụng Trang | 45
Nguyễn Minh Nhựt - 17520867
Báo cáo thực tập 15/11/20
}
},
mounted() {
this.getData();
},
methods: {
getData: function()
{ var vm = this;
axios
.get("http://127.0.0.1:8000/api/getdomain")
.then(function(response)
{ response.data.forEach(element => {
vm.post.push(element);
});
})
.catch(function(error) {
getAutocomplete: function()
{ this.valueCase3 = this.search;
this.items.push(this.valueCase3);
},
getEmail:
_.debounce( function()
{
Thực tập doanh nghiệp
Giáo viên hướng dẫn: ThS. Đỗ Thị Minh Phụng Trang | 46
Nguyễn Minh Nhựt - 17520867
Báo cáo thực tập 15/11/20
Source code
<template>
<v-card>
<v-container fluid>
<v-row
align="center"
>
<v-col cols="12">
<v-autocomplete
v-model="value"
:items="emailArray"
dense
filled
label="email"
:search-input.sync="search"
></v-autocomplete>
</v-col>
<v-col cols="12">
<v-autocomplete
v-model="value_domain"
:items="email_domainArray"
dense
filled
label="domain"
:search-input.sync="search_domain"
></v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-card>
</template>
<script>
import _ from 'lodash'
import axios from 'axios'
export default {
name:
'HelloWorld', data:
() =>
({ emailArray: [],
value:'',
search:null,
value_domain:'',
search_domain:null,
email_domainArray:[],
domainArray:[],
}),
watch:{ search()
{
this.debouncedGetEmail();
},
search_domain(){
if (this.search_domain.indexOf('@') !== -1) {
if(this.search_domain.substr(-1)==='@')
{ this.email_domainArray = [];
this.domainArray.forEach(element => {
this.email_domainArray.push(this.search_domain + element.domain.slice(1));
});
}
}
else {
Thực tập doanh nghiệp
Giáo viên hướng dẫn: ThS. Đỗ Thị Minh Phụng Trang | 49
Nguyễn Minh Nhựt - 17520867
Báo cáo thực tập 15/11/20
this.email_domainArray=[];
}
}
},
created: function () {
this.debouncedGetEmail = _.debounce(this.getEmail, 100);
this.getDomain();
},
methods: {
getEmail: function ()
{ const self = this;
axios.get('http://127.0.0.1:8000/api/getemail/'+this.search)
.then(function (response) {//self.emailArray=[];-->
response.data.forEach(element => {
self.emailArray.push(element);
});
}).catch(function (error) {
console.log(error);
})
},
getDomain:function ()
{ const self = this
axios.get('http://127.0.0.1:8000/api/getdomain')
.then(function (response)
{ self.domainArray = response.data;
})
.catch(function (error) {
console.log(error);
})
}
}
}
</script>