- vừa được xem lúc

PHP thuần: tạo một progress bar(thanh tiến trình) trên command line

0 0 34

Người đăng: TM

Theo Viblo Asia

Tình cờ thấy một số thanh progress bar trên nodejs khá hay ho, hôm nay tôi sẽ hướng dẫn mọi người viết một cái progress bar màu mè bằng php.

Tạo class ProgressBar

<?php
final class ProgressBar
{ /**Ký tự dùng phần hoàn thành của progress bar */ const FILL_CHAR = "▓"; /**Ký tự dùng phần còn lại chưa hoàn thành của progress bar */ const NOT_FILL_CHAR = "░"; /** Độ dài tối đa của thanh progress bar */ const BAR_LENGTH = 50; /** @var int Số bứớc nhảy tối đa của progress bar, mặc định ban đầu là 0*/ private $maxProcess = 0; /** @var int Bứớc nhảy hiện tại của progress bar, mặc định ban đầu là 0 */ private $currenProcess = 0; /** @var bool Trạng thái kết thúc của thanh tiến trình */ private $endProgress = false; /** @var string Nơi lưu toàn bộ progress bar */ private $progressBar = ""; /** Danh sách màu của progress bar, cái này chỉ để cho thanh progress bar trông màu mè hơn xíu :)) */ private $colors = [];
}

Tạo constructor để khởi tạo số bước nhảy tối đa của progress bar, tiếp đó là khởi tạo các mã màu để sử dụng cho việc biến đổi màu sắc theo số % của thanh tiến trình.

public function __construct($max)
{ $this->maxProcess = $max; $this->initColorCode();
} private function initColorCode()
{ for ($i = 196; $i <= 231; $i++) { $this->colors[] = $i; } for ($i = 123; $i >= 119; $i--) { for ($j = 0; $j < 3; $j++) { $this->colors[] = $i - 36 * $j; } }
}

Hàm tạo color code theo số %:

private function getColorCode($percent)
{ $code = floor($percent / 2); if (!isset($this->colors[$code])) { $code = $this->colors[count($this->colors) - 1]; } else { $code = $this->colors[$code]; } return "\e[38;5;{$code}m";
}

Mỗi lần progress bar thay đổi, các ký tự đã show ra console trước đó phải được replace, hàm getBackward sẽ nhận vào số % hiện tại và trả về ký tự thoát tương ứng để relpace lại các ký tự đã in ra trước đó:

private function getBackward($percent)
{ $backward = (strlen($this->progressBar) + 2); if ($percent < 10) { $backward++; } return "\033[{$backward}D ";
}

Ui chao nghe lan man quá, rồi cái thanh tiến trình của tôi đâu. Thôi thì mình sẽ show code chính trước, hàm bổ trợ mình để ở dưới và giải thích sau nhé 😃)

public function start()
{ echo "\n\033[?25l"; // show break line and hide cursor $this->showProcess(0);
}

Hàm start ẩn con trỏ trên console và gọi hàm showProcess với đầu vào ban đầu là 0%(sẽ viết bên dưới)

public function advance($step = 1)
{ $this->currenProcess += $step; // Mỗi lần gọi hàm thì tăng current process lên  $percent = floor($this->currenProcess * 100 / $this->maxProcess); // tính toán số phần trăm tương ứng với process hiện tại $this->showProcess($percent); // gọi hàm để show progress bar if ($percent >= 100 && !$this->endProgress) {// nếu số phần trăm đã vượt ngưỡng 100%, đánh dấu là end progress để không tăng thêm độ dài cho progress bar $this->endProgress = true; }
}

Hàm advance cho phép truyền vào 1 tham số int, là bước nhảy của progress bar. Nếu không truyền vào thì mặc định mỗi lần gọi sẽ tăng step lên 1 đơn vị.

public function __destruct()
{ $this->endProgress = true; echo "\033[?25h\n"; //show cursor and break line
}

Sau khi chạy xong thì destructor sẽ được gọi và hiển thị con trỏ trở lại.

Còn thiếu 2 hàm createProgress và showProcess, ngay đây thôi 😃)

private function createProgress($percent)
{ $bar = ''; if ($percent >= 100) { // Nếu số phần trăm quá 100, gán lại bằng 100 để không tăng thêm độ dài cho progress bar $percent = 100; } $fillPoint = floor($percent / (floor(100 / static::BAR_LENGTH))); // tính toán xem cần fill bao nhiêu % hoàn thành vào progress bar for ($i = 0; $i < $fillPoint; $i++) { $bar .= static::FILL_CHAR; } $notFill = static::BAR_LENGTH - $fillPoint; // tính toán xem cần fill bao nhiêu % chưa hoàn thành vào progress bar for ($i = 0; $i < $notFill - 1; $i++) { $bar .= static::NOT_FILL_CHAR; } return $bar; // trả về 1 chuỗi thanh tiến trình
}
private function showProcess($percent)
{ $backward = $this->getBackward($percent); // get backward code để replace lại progress bar $bar = $this->createProgress($percent); // tạo progress bar string $colorCode = $this->getColorCode($percent); // get mã màu tương ứng với thanh tiến trình hiện tại $total = "{$this->currenProcess}/" . ($this->currenProcess > $this->maxProcess ? $this->currenProcess : $this->maxProcess); // tính tổng số step echo $this->progressBar = "{$backward}{$colorCode} {$total} " // show progress bar . Formater::ESCAPE . " [{$colorCode}{$bar}" . Formater::ESCAPE . "] {$colorCode}{$percent} %" . Formater::ESCAPE;
}
private function getColorCode($percent)
{ $code = floor($percent / 2); if (!isset($this->colors[$code])) { $code = $this->colors[count($this->colors) - 1]; } else { $code = $this->colors[$code]; } return "\e[38;5;{$code}m";
}

Cuối cùng là khởi tạo instance của ProgressBar để test thôi nào

$command = new Command;
$command->progressStart(1000);
for($i = 0; $i < 1000; $i++) { $command->progressAdvance(); usleep(50000);// sleep nửa giây cho mỗi step để xem thanh tiến trình thay đổi từ từ :))
}

Full code tại đây

Tham khảo mã màu cho console tại đây

Thank for watching ;p

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 376

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 421

- vừa được xem lúc

Sử dụng Swagger để xây dựng API documentation

Giới thiệu về Swagger. RESTful API là một tiêu chuẩn dùng trong việc thiết kế API cho các ứng dụng web (thiết kế Web services) để tiện cho việc quản lý các resource.

0 0 1k

- vừa được xem lúc

So sánh Interface và Abstract trong lập trình hướng đối tượng.

Tổng quan. Interface và Abstract class là 2 khái niệm cơ bản trong lập trình OOP.

0 0 49

- vừa được xem lúc

CURL và cách sử dụng trong PHP

Giới Thiệu. CURL là bộ thư viện được sử dụng để giúp thực hiện việc chuyển dữ liệu thông qua nhiều giao thức khác nhau (như HTTP, FPT...). Với giao thức HTTP, cURL hỗ trợ việc gửi dữ liệu sử dụng tất cả các phương thức hiện có như GET, POST, PUT, DELETE... cURL cũng hỗ trợ việc chuyền dữ liệu sử dụn

0 0 81

- vừa được xem lúc

Thêm dòng dữ liệu mới (MySQL) trong Laravel

Chào các bạn, Laravel hiện đang là hot trend trong "thế giới PHP". 1. Cấu hình cơ bản ban đầu. .

0 0 38