Hàm gọi lại PHP sử dụng biến

Khả năng sử dụng hàm gọi lại rất tiện dụng trong nhiều tình huống lập trình hàng ngày. Với các chức năng ẩn danh, bạn có thể đưa mã của riêng mình vào quá trình thực thi của một chức năng khác, giúp cải thiện đáng kể khả năng tái sử dụng mã

Đây là một số ví dụ đơn giản nhưng rất thực tế về việc sử dụng các lệnh gọi lại cho các tác vụ lập trình khác nhau. Trong mỗi ví dụ, chúng ta sẽ định nghĩa một hàm trợ giúp chấp nhận một hàm gọi lại khác làm đối số và thực hiện một số xử lý với nó. Hàm trợ giúp sau đó có thể được sử dụng lại bằng cách gọi nó nhiều lần với các đối số gọi lại tùy chỉnh

Ví dụ 1. đo thời gian

Có thể bạn đã sử dụng hàm

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
1 để đo điểm chuẩn cho chương trình của mình. Giờ đây, bạn có thể định nghĩa hàm trợ giúp
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
2, hàm này tự động thực hiện các cuộc gọi
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
1 và phép trừ thời gian cho bạn. Mã dành cho phép đo thời gian được truyền trong tham số gọi lại
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
4 và được gọi từ bên trong hàm trợ giúp

chức năng trợ giúp

function runWithTimer(callable $cb, &$seconds) {
  $t0 = microtime(true);
  try { 
    $res = $cb();
    return $res;
  }
  finally {
    $t1 = microtime(true);
    $seconds = $t1 - $t0;
  }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hàm trợ giúp sử dụng tham số

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
5 được truyền bằng tham chiếu để lưu trữ số giây kết quả. Hàm trợ giúp tự trả về giá trị trả về của hàm gọi lại
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
4. Nó cũng có thể được triển khai theo cách khác (hàm trợ giúp trả về số giây và lưu trữ giá trị trả về của hàm gọi lại trong một tham số được truyền bởi tham chiếu)

Cách sử dụng

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Số giây hàm gọi lại đang thực thi được lưu vào biến

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
7. Bản thân chức năng gọi lại đã trả về
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
8, được lưu vào biến
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
9

Lưu ý rằng thực hiện phép trừ thời gian cuối cùng trong khối

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
10 đảm bảo rằng chúng tôi nhận được số giây kết quả ngay cả khi hàm gọi lại đưa ra một ngoại lệ

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
1

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

ví dụ 2. Bộ đệm đầu ra

Một số hàm hiện có của bạn có thể lặp lại đầu ra thay vì trả về dưới dạng chuỗi. Lý tưởng nhất là bạn nên viết lại các hàm đó để trả về các chuỗi, nhưng để giải quyết nhanh chóng, bạn có thể sử dụng bộ đệm đầu ra. Hàm trợ giúp

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
11 đóng gói các lệnh gọi vùng đệm đầu ra cần thiết cho bạn

chức năng trợ giúp

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
4

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Cách sử dụng

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
5

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Ở đây, đầu ra của hàm gọi lại được lưu dưới dạng chuỗi vào biến

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
12. Bản thân chức năng gọi lại đã trả về
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
8, được lưu vào biến
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
9

Bạn cũng có thể sử dụng gọi lại dựa trên chuỗi để dễ dàng lưu trữ đầu ra của chức năng lặp lại hiện có

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
9

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

ví dụ 3. giao dịch cơ sở dữ liệu

Hàm

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
15 lưu trữ mã lặp đi lặp lại để thực hiện và khôi phục các giao dịch cơ sở dữ liệu

chức năng trợ giúp

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
1

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hàm trợ giúp thực thi gọi lại

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
4 và gọi lùi giao dịch nếu gọi lại đưa ra một ngoại lệ. Mặt khác, nó cam kết giao dịch. (Gọi lại
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
4 phải chứa logic thao tác dữ liệu cơ sở dữ liệu, nếu không, sẽ không có ý nghĩa gì khi chuyển nó tới hàm
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
15. )

GHI CHÚ. Trong mã dự án thực, bạn có thể triển khai hàm trợ giúp như một phương thức của lớp nhà cung cấp kết nối cơ sở dữ liệu của mình, để đối tượng

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
19 có thể được lưu trữ trong một biến lớp thay vì được truyền lặp đi lặp lại thông qua tham số hàm

Cách sử dụng

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
6

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Trong ví dụ này, hàm gọi lại được biểu thị bằng hàm ẩn danh sẽ chèn dữ liệu vào hai bảng cơ sở dữ liệu khác nhau. Logic thao tác cơ sở dữ liệu được đóng hộp đen trong hàm

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
40. Khi một lỗi cơ sở dữ liệu được báo hiệu bởi một giá trị trả về
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
41, hàm gọi lại sẽ đưa ra một ngoại lệ và do đó gây ra tình trạng khôi phục giao dịch. Mặt khác, nó trả về số lượng hàng đã chèn, cuối cùng được lưu trữ trong biến
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
42

Do dữ liệu

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
43 dành cho việc chèn cơ sở dữ liệu được xác định bên ngoài phạm vi của hàm ẩn danh, chúng tôi đã áp dụng cấu trúc
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
44 trong định nghĩa hàm ẩn danh để đưa biến
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
45 vào phạm vi bên trong (
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
46)

GHI CHÚ. Bạn có thể sử dụng các hàm trợ giúp tương tự ngay cả đối với các tác vụ liên quan đến cơ sở dữ liệu khác, chẳng hạn như thực thi các hàm gọi lại đối với cơ sở dữ liệu mặc định nhất định (có thể bạn sẽ sử dụng

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
47 trong mã hàm trợ giúp)

Ví dụ 4. Bộ nhớ đệm

Ví dụ cuối cùng của chúng tôi xử lý bộ nhớ đệm của các giá trị trả về của hàm. Thông thường, bạn sẽ muốn lưu vào bộ nhớ cache các tính toán tiêu tốn tài nguyên, các chức năng truy vấn cơ sở dữ liệu hoặc các cuộc gọi liên quan đến I/O khác

Tương tự như các hàm trợ giúp đã đề cập trước đây,

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
48 chấp nhận hàm gọi lại trong tham số
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
4. Hàm gọi lại này đại diện cho một tính toán mà chúng tôi muốn lưu vào bộ đệm các giá trị trả về. Hàm trợ giúp cuối cùng trả về một hàm ẩn danh hoàn toàn mới, sau đó có thể được mã bên ngoài sử dụng làm hàm lưu trữ

chức năng trợ giúp

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
7

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Trước tiên, hàm trợ giúp tạo mảng

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
50, mảng này sẽ dùng làm bộ lưu trữ cho các giá trị trả về được lưu trong bộ nhớ cache. Sau đó, nó trả về một hàm ẩn danh thực thi một lệnh gọi lại
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
4 đã cho và lưu trữ giá trị trả về của nó, nhưng chỉ khi nó không tìm thấy giá trị trả về của nó đã được lưu trữ trong bộ đệm. Hàm ẩn danh được trả về có thể đã được tạo thành hai nhánh, đây chỉ là một tinh chỉnh về hiệu suất - các giá trị trả về của các hàm gọi lại chỉ chấp nhận một đối số có thể được lưu vào bộ đệm hiệu quả hơn, đó là mục đích của nhánh đầu tiên

Cách sử dụng

Chúng tôi sẽ xác định chức năng truy vấn dữ liệu của người dùng

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
52 từ cơ sở dữ liệu và sau đó chúng tôi tạo chức năng lưu trữ bộ đệm
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
53 từ nó

function runWithTimer(callable $cb, &$seconds) {
  $t0 = microtime(true);
  try { 
    $res = $cb();
    return $res;
  }
  finally {
    $t1 = microtime(true);
    $seconds = $t1 - $t0;
  }
}
2

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Như bạn thấy, lệnh gọi lặp lại tới

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
53 với đối số
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
55 chưa gọi hàm
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
52, vì giá trị trả về đã được lấy từ bộ đệm

Nếu bạn muốn thực hiện cuộc gọi tới

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
52 với tham số tùy chọn
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
58 thay đổi, bạn sẽ phải gọi
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
48 với tham số
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
90 được đặt thành
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
8

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
0

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

GHI CHÚ. Chúng tôi đã sử dụng hàm gọi lại dựa trên chuỗi

$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
92 làm đối số cho hàm
$seconds = 0;
$res = runWithTimer(function () {
  sleep(3);
  return true;
}, $seconds);
var_dump($seconds, $res);
// Outputs: float(3.022805929184) bool(true)
48 trong ví dụ này, nhưng bạn cũng có thể sử dụng hàm gọi lại hàm ẩn danh một cách tự nhiên

Phần kết luận

Tôi hy vọng ví dụ này đã giúp bạn hiểu cách xây dựng mã tốt hơn. Chúng cũng đóng vai trò giới thiệu về lập trình chức năng trong PHP