THẢO LUẬN

Jun 19th, 2018 4:39 a.m.

Bạn ơi, mình làm phiền bạn thêm chút xíu nữa, trường hợp nếu mình khai báo hàm foo() bên trong hàm barr(), tức là code sẽ như thế này:

function bar() {
    var a = 3;
    function foo() {
      var a = 2; //=> khi bỏ dòng này đi
      console.log(a);
   }
}

var a = 'Ahihi';
bar();

Tại sao khi bỏ dòng var a= 2 thì nó lại không log ra giá trị nào cả. Mình tưởng hàm foo() nằm trong Scope của hàm bar() nên nó có quyền truy cập vào biến var a = 3 => tức là nó sẽ in ra giá trị 3 chứ nhỉ. Trường hợp này giải thích thế nào hả bạn ?

0

Tất nhiên, sau khi bạn git add rồi commit ngay thì sẽ không sao. Còn bạn git add, xong sau đó vào chỉnh sửa file trong thư mục source thì git ko băm phần edit mới đó nhé, mà chỉ băm version bạn đã git add thôi.

nice!

0

Để tường minh mình sẽ có một folder test, bên trong có chứa 1 file test_commit.rb, trong file này có đoạn text this is test file. cd đến folder test, chạy git init sẽ có folder .git Hiện tại bên trong folder objects ở trong .git có thể được coi là trống trơn Sau đó thực hiện commit $ git commit -m 'First time init' Lúc này sẽ thấy thay đổi bên trong folder objects

Bạn chưa add mà, chỗ này nó sẽ không commit được.

$ git log --oneline
# Log commit
c83dd69 First time init
(END)

Nó sẽ ra như này:

LongNX@LPP00039344K MINGW64 ~/OneDrive/OneDrive - FPT Software/App/GoTiengViet (master)
$ git log --oneline
fatal: your current branch 'master' does not have any commits yet

0

Cám ơn bài viết của bạn. Mình có thấy vài chỗ nhầm lẫn trong bài nên cho mình list ra nhé

  1. Tính bảo mật Eloquent ORM có tính bảo mật cao hơn QueryBuilder trong việc phòng chống SQL Injection.

Cái này chắc bạn đang nói đến kiểu viết bên dưới nhỉ

DB:raw('select * from users where id =' . $id);

Chúng ta có thể dùng PDO parameter binding để tránh khả năng SQL bị tấn công, nên mình nghĩ để tránh thì phải quán triệt dùng PDO binding với các bạn developer trong team
Vd:

DB::select(
'select * from users where id = :id',
['id' => $id]
);

Note: Cẩn thận với whereRaw trong DB facade vì query sẽ không được escape

4.Lấy một trường của tất cả bản ghi .

$name = DB::table('users')->lists('name');
$users = Users::lists('name');

Hình như ví dụ này đã bị out of date so với version 5.6
Với Eloquent thì mình nghĩ sẽ dùng hàm pluck

User::pluck('name');

Còn với Query builder chúng ta dùng select thay vì dùng hàm lists (hàm list đã bị deprecated từ 5.3 thì phải)

DB::table('users')->select('name')->get();
  • Lưu ý đối tượng trả về là Laravel Collection chứ không phải array thông thường

8.Delete $user->destroy();

Hàm destroy phải gọi static function chứ không phải instance function, và hàm destroy nhận vào ID của record muốn delete.

User::destroy(1);

Ngoài ra mình đồng tình với việc cú pháp code của Eloquent dễ hiểu hơn (về mặt business). (Hiệu suất thì mình chưa bandwidth nên cũng chưa khẳng định được 😄) Nhưng thấy hơi không rõ ràng ở chỗ

Eloquent ORM dễ dàng kết nối với database hơn QueryBuilder.

Theo mình hiểu thì Eloquent, đến cuối cùng khi giao tiếp với tầng Database thì cũng sử dụng Query Builder
Chúng ta có thể tham khảo class Illuminate\Database\Eloquent\Builder để thấy rằng cuối cùng Eloquent cũng sử dụng Query Builder khi tương tác với DB
Có nghĩa là Eloquent là một wrapper về mặt business cho Query Builder, làm cho code dễ đọc hơn, và cũng cung cấp nhiều business methods hơn QueryBuilder như Eloquent Relationships, Soft delete, Eloquent Events...
Nên khi nói đến tính dễ dàng kết nối, mình nghĩ ORM base trên Query Builder nên sẽ không đánh giá.

+1
Jun 19th, 2018 4:19 a.m.

Cám ơn bạn nhiều nha, bạn giải thích rất chi tiết, đến đây thì mình mới hiểu được cặn kẽ hơn.

0
Jun 19th, 2018 4:19 a.m.

@huuhau95 Khá hay khi bạn cố gắng tìm hiểu PHP thuần. Bạn cần chú ý trường hợp người dùng không chọn file tải lên. Cụ thể trong ví vụ của bạn, nếu bạn không chọn file tải lên mà nhấn submit thì

$_FILES['image']['error'] = 1; // Mã lỗi

Những giá trị của error phụ thuộc vào các hằng được khai báo ở đây http://php.net/manual/en/features.file-upload.errors.php

0

Để giải thích hoàn toàn trả lời của mình, dùng mỗi lexical scope thôi là chưa đủ. Mà bạn còn phải dùng cả kiến thức của global scope - local scope nữa. Cái đoạn code tương đương mà bạn đưa ra, chính xác hay không, phải phụ thuộc vào scope. Việc giá trị của a là gì, sẽ được quyết định bởi scope của nó, và các outer scope (parent scope) bao quanh nó. Giờ ta sẽ bắt đầu với từng dòng code một, theo đúng luồng chạy (execute code) của nó, cho bạn dễ hiểu. (Lưu ý là để cho bạn dễ hiểu thôi, mục đích là để giải thích cho bạn câu này, còn nếu giải thích chi tiết và chính xác nhất, thì mình e là làm bạn loạn mất)

  1. Ta bắt đầu với var a = 'Ahihi'; Ta có một GLOBAL SCOPE, và khai báo một global variable a. Nó mang giá trị là 'Ahihi'
  2. bar(); Ở đây ta bắt đầu gọi hàm bar, 2 hàm barfoo đều đã được khai báo ở trên.
  3. Ta sẽ bắt đầu chạy hàm bar, bắt đầu với dòng code đầu tiên là var a = 3;. Như mình vừa nói ở comment trên, parent scope của bar là global scope, nó ĐÃ KHAI BÁO MỘT global variable rồi, là a có giá trị 'Ahihi'. Vào trong đây, là một LOCAL SCOPE, và ta KHAI BÁO một giá trị a MỚI, đó là một local variable, trùng tên với a đã khai báo trước đó, nhưng mang giá trị là a = 3. Lưu ý là do khác scope, nên từ dòng code này trở đi, ta dùng giá trị của a, tức là ta sẽ động tới local scope, local variable a có gía trị là 3.
  4. foo(); call hàm foo.
  5. Bắt đầu chạy hàm foo, dòng lệnh đầu tiên là var a = 2; Lại giống như trên, foo tạo ra một LOCAL SCOPE mới, khác với local scope của bar, và parent scope của nó là ... GLOBAL SCOPE, ngoài ra, nó cũng khai báo một local variable MỚI, một biến a mới có giá trị là 2. Kể từ sau dòng lệnh này, BÊN TRONG function foo, bạn dùng giá trị a thì nó sẽ là a mới này (với giá trị là 2)
  6. console.log(a); Nó sẽ in ra 2. Đương nhiên rồi, mình vừa giải thích ở bước chạy trên xong.

Giờ ta bỏ cái var a = 2 đi. Chuyện gì xảy ra? Javascript engine sẽ tìm outer scope, để xem có gía trị a đã khai báo nào không mà ta lại dùng ở đây. Và nó sẽ tìm đến parent scope, chính là GLOBAL SCOPE, và tìm được var a = 'Ahihi'.

Ở trên mình có nói, code tương đương mà bạn đưa ra chính xác hay không, phụ thuộc vào scope. Đấy là bởi, nó sẽ là đoạn code tương đương thật sự, nếu như function foo được khai báo bên trong bar, mục tiêu, là để scope của chúng theo đúng thứ tự phân cấp global scope -> bar scope -> foo scope. Code tương đương mà bạn đưa ra, chỉ là luồng chạy của code. Còn javascript hiểu, và đọc giá trị như nào, là việc khác, và việc khác này, phụ thuộc vào Scope.

+1
Jun 19th, 2018 3:46 a.m.

mình login xong, gọi req.user thì nó không tìm thấy! ko biết lúc login xong user được lưu vào đâu?

0

@thangtd90 @vinhnguyen Hai anh phân tích đầy đủ và chi tiết quá. Em không thể accept hai câu trả lời được sao? 😐

0

@quynh001 Cảm ơn anh đã phân tích rất hay và chi tiết. Em không coi đây là điểm yếu vì Laravel vẫn quá "pro" và vì em không giám chắc rằng mình viết được concrete nào "hay ho" hơn concrete mặc định của nó.

Giống như anh nói "trade-offs giữa sự đơn giản và tính đầy đủ ấy" và phân tích.

PHP là một duck typed language thay vì strong typed như trong một số ngôn ngữ khác như Java, .NET. Với các ngôn ngữ dạng strong typed, method signature trong interface thường phải định nghĩa cả kiểu cho parameters và kiểu trả về --> đảm bảo type safety. Trong PHP thì không như vậy thường sẽ ko có kiểu xác định. Do đó với PHP, các phương thức của một object sẽ xác định cách object đó có thể sử dụng thay vì phải phụ thuộc vào sự kế thừa từ một class khác hoặc một thể hiện cụ thể của interface. Tất nhiên PHP vẫn có thể là một strong typed nếu muốn

Em chỉ không thích phong cách code như vậy. Với em, khi đã viết interface và type-hint interface, chỉ nên gọi những phương thức đã được định nghĩa trên interface đó.

+1
Avatar
đã bình luận cho bài viết
Jun 19th, 2018 3:18 a.m.

rất hay

0

dạ vâng eloquent xây dựng sẵn sử dụng PDO nên nó theo 1 cấu trúc rồi ạ!, ý em là sử dụng code sql thuần mh có thể check được những cái mà mình nghĩ eloquent chưa đáp ứng được ạ!

0
Jun 19th, 2018 3:06 a.m.

Mình nghĩ là bạn nên đưa thêm 1 số thông tin như là bạn sẽ quản lí, lưu trữ những gì, mục đích ra sao thì sẽ dễ hỗ trợ hơn.

0
Jun 19th, 2018 2:53 a.m.

Hay

0
Jun 19th, 2018 2:31 a.m.

Nếu đã biết có "sơ sót", và "sơ sót" đó là gì, b nên nêu ra trong câu hỏi, để mọi người không mất thời gian để xem tất cả các bảng đó.

0
Jun 19th, 2018 2:22 a.m.

good

0
Eloquent ORM có tính bảo mật cao hơn QueryBuilder trong việc phòng chống SQL Injection.

Đoạn trên em viết ntn cơ mà

0
Jun 19th, 2018 1:59 a.m.

mình có thắc mắc là trên trang jwt.io mình dễ dàng decode được chuỗi JWT mà ko cần khóa, nếu có ai đó lấy được chuỗi JWT mà user gửi lên thì hoàn toàn có thể lấy được quyền truy cập. V liêu JWT có an toàn ko nhỉ?

0

Screenshot from 2018-06-19 08-23-13.png Screenshot from 2018-06-19 08-28-06.png Mình dựa vào bài của bạn để làm đối với model User, sử dụng form request để validate trong controller. Trường hợp mình gửi ảnh đây là để trường name trống thì vẫn hiện thông báo lỗi. Ngay sau khi nhập name và để email trống thì console hiện báo như thế. Mình kiểm tra có báo yêu cầu không để trống email trong trình duyệt. Mong bạn có thể xem hộ mình.

+1

dạ vâng a? em nghĩ dùng db raw thì code bảo mật sẽ chặt chẽ hơn chứ anh?

0
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí