Thang Tran Duc

@thangtd90

Report

Lỗi khi hiển thị dữ liệu trong laravel

Thang Tran Duc
Answered about 17 hours ago

Lỗi mà bạn đang gặp phải đơn giản là có một $discussion nào đó không gắn với $post, nên khi bạn gọi $dis->post sẽ nhận được kết quả là null, và sau đó gọi $dis->post->title sẽ ra lỗi.

Sở dĩ bạn dùng dd($dis->post->slug) vẫn ra dữ liệu là bởi vì bạn đang dùng dd trong vòng foreach, hàm dd sẽ chỉ in ra kết quả của vòng lặp đầu tiên, và dừng chương trình ở đó. Còn bỏ dd đi thì vòng lặp của bạn cứ thế mà chạy, chạy đến khi nào $dis->postnull thì nó sẽ bị lỗi 🤔

Trước khi print ra thì bạn thêm câu điều kiện if ($dis->post) xem sao 🤔

Cách bảo mật trong rails

Thang Tran Duc
Answered Monday, 12:48 AM

Giả sử 1 token ở máy tính của em chưa hết hạn, bị người khác lấy trộm rồi đem về máy của họ gửi request lên => có phải lúc này họ có thể lấy được data của em.?

Đúng rồi em, khi mà token của tài khoản của em bị người khác lấy, thì họ có thể dùng nó để gửi mọi request lên server, để thực hiện những action mà token đó có quyền. Họ hoàn toàn có thể xem, tạo mới, chỉnh sửa, xoá dữ liệu của em.

Thực tế thì vấn đề này không chỉ xảy ra khi em dùng token, cả với cơ chế login thông thường thì em cũng có thể gặp phải tình trạng tương tự, khi mà dữ liệu từ form submit username/password, hay dữ liệu trong cookie của em cũng có thể bị người khác lấy trộm. (thông qua việc bắt và đọc gói tin mà máy tính của em truyền đi)

Và nếu họ có thể thể truy cập sau khi lấy trọm token của em như trên thì có cách nào để phòng chống việc này không?

Cách đơn giản để giải quyết bài toán này đó chính là phải làm thế nào để người khác không thể lấy được token của em. Và HTTPS chính là câu trả lời cho vấn đề này 😉

HTTPS sẽ giúp em mã hoá được dữ liệu truyền lên, cũng như dữ liệu nhận về từ server, khiến cho người khác dù có bắt được những requests này đi chăng nữa, thì cũng không thể đọc được dữ liệu này.

Em có thể tìm hiểu thêm về HTTPS qua một vài bài viết ở dưới đây:

Ngoài ra, một số trang web có thể làm chặt chẽ hơn là họ gắn token với địa chỉ IP hiện tại của em, và sẽ vô hiệu hoá token đó nếu nó được gửi từ một IP khác. Đó cũng là một cách mà em có thể tham khảo thêm. 😄

Hỏi 1 số issue về play music với react.

Thang Tran Duc
Answered Friday, 6:51 AM

Về phần Browser không cho phép autoplay, hay autoplay mà không có tiếng, thì nó thuộc về Policy của trình duyệt rồi, bạn có thể xem thêm tại đây,

trước cũng từng có bạn khác hỏi về vấn đề này 😄

https://viblo.asia/q/autoplay-video-html5-VgZve03YKAw

Mọi người cho mình hỏi tên loại font chữ này với.

Thang Tran Duc
Answered Jan 8th, 3:03 AM

Hình như là font Operator Mono 😄

https://www.typography.com/blog/introducing-operator

operator_font.png

Tuy nhiên đây lại là font có phí bạn ạ 😂

Sự khác nhau khi gọi hàm thực thi trong ComponentWillMount và hàm setState()

Thang Tran Duc
Answered Dec 20th, 2018 6:08 AM

Có một vài điểm em cần nắm rõ, thì sẽ hiểu được bản chất của vấn đề hơn 😃

Một function trong Javascript thực tế cũng chỉ là một object, nên em có thể thực hiện các phép gán, hay pass các object đó vào trong một hàm khác. Ví dụ

function test() {
    console.log('Hello');
}

a = test;
a(); // gọi hàm, in ra Hello

Việc em dùng () thì là một lời gọi hàm, còn không có, thì nó chỉ như một biến (object) bình thường mà thôi.

Như vậy this.printCount(); thì là lời gọi để chạy hàm printCount, còn this.setState({ count: this.state.count + 1 }, this.printCount); thì tức là em truyền this.printCount như là một biến vào trong hàm this.setState(). Khi đó người ta gọi this.printCount là một callback, và nó chưa được gọi (chưa được chạy) ngay. Việc gọi hàm đó được thực hiện ở đâu đó trong phần logic bên trong hàm setState.

Laravel : xin mọi người thông não giúp em. không lưu tags là khoảng trống trong DB tags.

Thang Tran Duc
Answered Dec 14th, 2018 9:53 AM

Đoạn này

if ($item != " ")

bạn thử chuyển thành

if (!empty($item))

xem sao 🤔

Lỗi font tiếng việt php

Thang Tran Duc
Answered Dec 12th, 2018 12:58 AM

Bạn đang để style CSS là dùng font chữ gì vậy? Ngoài ra bạn thử bật console lên xem các file font của bạn có load về được không 🤔

Nếu chưa dùng web font gì thì bạn thử dùng Google Font như Roboto xem sao 🤔

Chẳng hạn như add đoạn sau vào trong thẻ <head>

<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<style>
    body {
        font-family: 'Roboto', serif !important;
    }
</style>

mọi người chỉ giúp em làm sao chỉ detail nhưng object ở status publish trong project laravel với ạ, hiện tại e detail luôn cả nhưng object close.

Thang Tran Duc
Answered Dec 5th, 2018 8:11 AM

Bạn dùng where để filter thêm điều kiện status xem sao 😄

$faq = $this->faqService->where(['id' => $faqId, 'status' => 'publish'])->first();

câu truy vấn trong laravel

Thang Tran Duc
Answered Dec 3rd, 2018 1:24 PM

Em nên có một bảng là hourly_order_logs, daily_order_logs. Cứ mỗi giờ, mỗi ngày thì em chạy cronjob để cập nhật số liệu vào các bảng ý, xem trong giờ trước, hay ngày hôm trước có bao nhiêu đơn hàng. Ví dụ như vào lúc 13:00 phút, job của em sẽ được chạy, và lưu vào bảng hourly_order_logs với thông tin là

id day hour order_count created_at updated_at
11 2018-12-03 11 2 2018-12-03 12:00:01 2018-12-03 12:00:01
12 2018-12-03 12 4 2018-12-03 13:00:01 2018-12-03 13:00:01

tương tự với thống kê theo ngày.

Khi cần in ra biểu đồ, thì em chỉ cần query trong các bảng log này thôi, chứ không cần phải tính toán phức tạp để đi đếm số order theo từng giờ, từng ngày nữa 😄

đăng ký mới dịch vụ twilio sms ở Việt Nam

Thang Tran Duc
Answered Nov 23rd, 2018 6:49 AM

Mình vừa thử vào https://www.twilio.com/ để đăng ký, thì vẫn đăng ký được bình thường mà nhỉ 🤔

Sau khi nhập email, password ở trang https://www.twilio.com/try-twilio , bạn sẽ được dẫn đến một trang để verify số điện thoại, bạn chọn quốc gia là Việt Nam, rồi nhập số điện thoại của mình vào, sẽ có tin nhắn được gửi tới xong bạn nhập verify code là được mà 😄

Không rõ bạn đang gặp rắc rối ở phần nào vậy nhỉ?

chỉnh sửa file trong thư mục /usr/bin/ của docker

Thang Tran Duc
Answered Nov 19th, 2018 2:23 AM

Theo mình hiểu thì bạn đang gặp 2 vấn đề,

  • Làm thế nào để chỉnh sửa file abc.sh
  • Làm thế nào để lưu lại nội dung sau khi chỉnh sửa vào image

Về hướng giải quyết thì sẽ như sau:

Chỉnh sửa file abc.sh

Nhìn chung sẽ rất khó để "mò" ra được file này nằm ở đâu trong máy của bạn, bạn nên chỉnh sửa trực tiếp trong container thôi. Bạn có thể dùng các command line editor như nano, hay vim để chỉnh sửa trực tiếp, rồi lưu lại, đây là cách nhanh chóng và dễ dàng nhất rồi 😂

Nếu bạn không quen với việc sử dụng các terminal editor trên, thì bạn có thể đi theo hướng khác là mount một thư mục từ bên ngoài máy host của bạn vào bên trong container, bằng tham số -v khi chạy: docker run -ti -v host_folder:/temporary image_name /bin/bash. Với việc sử dụng Docker Volume thông qua option -v như vậy, thì thư mục trong container sẽ được link với thư mục ngoài máy host, bạn chỉ cần dùng lệnh copy file từ /usr/bin/ vào thư mục /temporary, rồi sửa bằng notepad ở bên ngoài, sau đó từ /temporary copy ngược lại /usr/bin là được.

Lưu lại nội dung vào image

Sau khi edit được nội dung file, bạn có thể lưu lại trạng thái của container hiện tại, để tạo thành image mới, bằng lệnh docker commit. Về cú pháp của lệnh này, bạn có thể tham khảo ở trang document của Docker

docker commit -m "Edit abc.sh file" your_container_id new_image_name

Tuy nhiên, cách thực hiện việc thay đổi nội dung 1 image bằng cách edit trực tiếp bên trong container rồi lưu lại bằng docker commit không phải là một cách hay, và không được khuyến khích làm. Nếu image của bạn đang dùng có public Dockerfile, bạn nên sửa trực tiếp từ file Dockerfile đó, và build lại image của riêng mình thì hơn 😄

Unresolvable dependency resolving [Parameter #0 [ <required> $model ]] in class App\Repositories\Eloquents\DbBaseRepository

Thang Tran Duc
Answered Nov 14th, 2018 12:29 AM

Bạn đang gặp phải lỗi đó là do Laravel không thể resolve ra một instance mà class DbBaseRepository yêu cầu.

Cụ thể là ở đoạn code Constructor của class DbBaseRepository

/**
     * @param $model
     */
    function __construct($model)
    {
        $this->model = $model;
    }

Đoạn này để tạo ra một instance của class DbBaseRepository thì ta cần một instance $model nữa, tuy nhiên framework lại không hề biết làm thế nào để tạo ra cái $model đó.

Bởi thế, trước tiên, bạn cần phải chỉ rõ $model đó đến từ đâu, là instance của class nào, làm thế nào để có thể resolve được ra nó trước đã 🤔

Chẳng hạn như là function __construct(DbBaseModel $model), hoặc là bạn có thể bỏ hẳn nó ở phần parameters trong constructor đi, và khởi tạo nó ở bên trong ý 😄

function __construct()
{
    $this->model = new $this->getModel();
}

Bạn đang dùng OS/distro nào? Cảm thấy ra sao?

Thang Tran Duc
Answered Nov 9th, 2018 12:29 AM

Mình nghĩ là nếu không phải là làm app cho Windows thì bạn không có lý do gì để dùng Windows để code cả 😂

Linux Distro thì có lẽ Ubuntu là đem lại UX tốt nhất 😄

Một số câu hỏi liên quan đến Nuxtjs ( Vuejs)

Thang Tran Duc
Answered Nov 8th, 2018 1:44 AM

Về câu hỏi 1 của em:

  • localStorage là một đặc tả của HTML5, chứ không phải là một phần của Javascript. Tức nó chỉ tồn tại trên một số các trình duyệt có hỗ trợ mà thôi. Khi chạy ở phần server (nodejs), đương nhiên là sẽ không có biến nào là localStorage cả, nên đoạn code của em sẽ bị lỗi.
  • Việc dùng if (process.browser) là để check xem đoạn code javascript đó đang được chạy ở phía server, hay phía client (browser), nhằm đảm bảo phần code liên quan đến localStorage chỉ chạy ở phía trình duyệt thôi, và nó là cần thiết bởi nếu bê đoạn code đó lên chạy ở phần server thì sẽ có lỗi, như em đã gặp phải 😄

Về câu hỏi thứ 2 của em:

  • Bình thường Laravel tự động check CSRF token là bởi vì các controller phía backend được chỉ định là phải làm thế. Xử lý logic check CSRF token được đặt ở trong app/Http/Middleware/VerifyCsrfToken.php (được kế thừa từ class Illuminate\Foundation\Http\Middleware\VerifyCsrfToken). Middleware này được mặc định add vào middleware group web (em có thể check nội dung trong file app/Http/Kernel.php). Nên tất cả các routes em khai báo mà có middleware group là web thì đều sẽ phải verify CSRF token, hay nói cách khác, để truy cập vào các route đó thì phía client phải submit CSRF token lên.
  • Bên cạnh middleware group là web, Laravel còn có middleware group khác là api. Mặc định của api không có middleware CSRF. Cụ thể đoạn code của phần đó (trong file Kernel.php) như sau. Em có thể tham khảo thêm tại phần document về Middleware Groups trên website của Laravel
/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:60,1',
        'auth:api',
    ],
];
  • Do đó, khi truy cập đến các route mà có middle group là api thì em không cần submit CSRF token lên, đó là lý do tại sao em có thể gọi trực tiếp từ POSTMAN mà không bị lỗi gì 🤔

Vấn đề về phân trang trong PHP

Thang Tran Duc
Answered Nov 2nd, 2018 3:12 AM

Bạn thử tham khảo cách sau xem 😄

Mình vừa nghĩ vừa code thẳng trên này luôn, nên không đảm bảo nó sẽ chạy được luôn đâu, bạn check qua nhé 😄

// $currentPage số trang hiện tại 
// $totalPage tổng số trang
$pagination = [$currentPage]; // Đây là mảng lưu các trang sẽ xuất hiện ở phần phân trang
while (count($pagination) < 5) { // Sẽ chạy vòng lặp cho đến khi nào mảng này có đủ 5 phần tử thì thôi
    $left = $pagination[0] - 1; // Phần tử tiếp theo ở bên trái sẽ là phần tử bên trái ở thời điểm hiện tại trừ đi 1
    $right = $pagination[count($pagination) - 1] + 1; // Phần tử tiếp theo ở bên phải sẽ là phần tử bên phải ở thời điểm hiện tại cộng với 1
    $added = false; // Biến để kiểm tra xem có trang mới được thêm vào không
    if ($left > 0) {
        array_unshift($pagination, $left); // Đẩy page mới vào đầu mảng 
        $added = true;
    }
    if ($right <= $totalPage) {
        array_push($pagination, $right); // Đẩy page mới vào cuối mảng 
        $added = true;
    }
    if (!$added) { // Nếu cả bên trái lẫn bên phải đều không thể thêm phần tử nào vào nữa, thì break khỏi vòng lặp
        break;
    }
}
// Sau vòng lặp này bạn sẽ có một mảng có tối đa là 5 trang
if ($pagination[0] != $currentPage) { // Nếu trang ngoài cùng bên trái, mà không phải là current page, thì sẽ có nút Previous 
     array_unshift($pagination, '< Previous');
}

if ($pagination[count($pagination) - 1] != $currentPage) { // Nếu trang ngoài cùng bên phải, mà không phải là current page, thì sẽ có nút Next 
     array_push($pagination, 'Next >');
}

// Đến đây bạn sẽ có mảng $pagination chứa đủ Previous, Next, lẫn 5 trang xung quanh currentPage, bạn chỉ cần foreach rồi in ra thôi :D

join query builder trong laravel

Thang Tran Duc
Answered Oct 29th, 2018 1:30 AM

trong product_tag của em có data:
product_id: 1; tag_id:[tag1, tag2, tag3]

Vấn đề của em đang nằm ở phần thiết kế cơ sở dữ liệu này 😄

Cách thức lưu ở bảng trung gian như của em như ở trên là không hợp lý, lưu như vậy em rất khó để dùng lệnh join khi select tags cho một product. Ngoài ra khi select products cho một tag thì sẽ còn khó khăn hơn.

Em nên lưu dữ liệu như sau:

Bảng products

id name
1 S9
2 S9+
3 Iphone X

Bảng tags

id name
1 Android
2 iOS
3 Samsung

Bảng product_tag

id product_id tag_id
1 1 1
2 1 3
3 3 2

Như vậy em có thể dùng tính năng Many to Many Relationship của Laravel để có thể dễ dàng load ra tags từ $product bằng câu lệnh $product->tags hoặc ngược lại. Em có thể tham khảo các câu trả lời khác trong bài này để có thêm thông tin chi tiết hơn nhé 😉

Cách dùng PyStringNode trong Behat đối với ngôn ngữ PHP

Thang Tran Duc
Answered Oct 25th, 2018 5:58 AM

pystrings là cách để khai báo một đoạn văn bản dài trên nhiều dòng (Multiline Strings). Sở dĩ nó có tên là pystrings bởi vì nó vay mượn cú pháp của Python.

Trong Python, ta có thể dùng """ để khai báo một đoạn comment block, tức ta có thể viết bao nhiêu nội dung vào giữa phần mở """ và phần đóng """ cũng được.

Behat cũng sử dụng cú pháp đó để cho phép bạn khai báo một đoạn text dài, nhiều dòng. Tức bình thường thay vì bạn viết

Scenario:
  Given a post with the content "This is a very long post \n This is a new line \n This a another new line \n As you see, we have to use /\n for a line break"

Bạn có thể dùng cú pháp của pystrings để viết thành

Scenario:
  Given a post with the content:
     """
     This is a very long post
     This is a new line
     This a another new line
     As you see, we do not have to use \n for a line break
     """

Đoạn multiline strings này sẽ tự động được xử lý bởi class PyStringNode, và một instance của class này sẽ tự động được đẩy vào hàm của bạn ở argument cuối cùng.

/**
 * @Given a post with the content:
 */
public function blogPost(PyStringNode $content)
{
    $this->checkLength($content->getRaw());
}

Để lấy ra nội dung text từ một instance PyStringNode bạn có thể dùng hàm ->getRaw() như ở trên 😃

Bạn có thể xem thêm tại Document của Behat tại đây

Tích hợp cổng thanh toán Onepay vào website sử dụng Laravel

Thang Tran Duc
Answered Oct 23rd, 2018 5:48 AM

Mình thấy trên web site của Onepay họ có public module PHP về phần tích hợp thanh toán nội địa cũng như quốc tế, bạn thử tải về rồi check qua xem sao:

Ngoài ra trên Github cũng có package laravel-onepay này tích hợp thanh toán Onepay vào Laravel, bạn cũng thử tham khảo qua cách tổ chức code của họ xem sao 😉

Cấu hình máy chủ thế nào cho app realtime

Thang Tran Duc
Answered Oct 16th, 2018 9:55 AM

Ý bạn là muốn duy trì khoảng 100 kết nối websocket để thực hiện tính năng thông báo realtime à 🤔

Nếu chỉ là 100 kết nối websocket thì cũng không phải là cái gì lớn lắm, không rõ bạn còn chạy những services gì khác nữa không, nhưng nếu không có gì đặc biệt thì tầm server 2 Cores 4GB RAM (option 20$/tháng) của Vultr là ổn. Nếu thấy vẫn tốn kém thì bạn cứ thử với option thấp hơn (1 cores, 2GB RAM) xem sao 😄

tool/thư viện tạo ra string hiển thị tốt trong commandline

Thang Tran Duc
Answered Oct 4th, 2018 6:53 AM

Mình thì không dùng CSharp nên không được rõ lắm, còn với nodejs thì mình dùng package console.table này, có vẻ như cũng phù hợp với bài toán của bạn 😄

File CSV của mình

Field,Type,Null,Key,Default,Extra
ID,bigint(20) unsigned,NO,PRI,NULL,auto_increment
user_login,varchar(60),NO,MUL,,
user_pass,varchar(255),NO,,
user_nicename,varchar(50),NO,MUL,,
user_email,varchar(100),NO,MUL,,
user_url,varchar(100),NO,,,
user_registered,datetime,NO,,0000-00-00 00:00:00,
user_activation_key,varchar(255),NO,,,
user_status,int(11),NO,,0,
display_name,varchar(250),NO,,,

Code

const cTable = require('console.table');
const csvFilePath = 'test.csv';
const csv = require('csvtojson');
csv()
    .fromFile(csvFilePath)
    .then((jsonObj) => {
        console.table(jsonObj);
    });

Kết quả

Screen Shot 2018-10-04 at 1.50.59 PM.png

Mình search với từ khoá console.table CSharp thì có package ConsoleTables này dành cho C#, bạn thử dùng xem sao 😄