+1

[PHP Thực Chiến] Dẹp bỏ trò "cộng chuỗi" URL phèn với http_build_query

Chào anh em, lại là mình đây.

Làm Backend, chắc chắn anh em không thể né được cái cảnh phải gọi API sang một hệ thống khác (như tích hợp cổng thanh toán VNPay, Momo, hoặc gọi sang một service search nào đó). Và cái rắc rối thường gặp nhất chính là việc phải truyền một đống tham số (parameters) lên cái URL.

Giả sử anh em đang code tính năng filter cho một hệ thống e-commerce chuyên bán mỹ phẩm chẳng hạn. Khách hàng chọn: danh mục "skincare", giá từ 100k đến 500k, thương hiệu là "Vichy" và "La Roche-Posay", xếp theo giá tăng dần

Nếu dùng tư duy "cộng chuỗi" truyền thống (thứ mà 90% anh em fresher hay làm), code của anh em trông sẽ tởm lợm như thế này:

Nhìn bẩn mắt không? Thiếu một cái dấu &, quên urlencode() một phát là API bên kia chửi "Bad Request" ngay. Hôm nay, mình sẽ giới thiệu (hoặc nhắc lại) cho anh em một hàm "thần thánh" có sẵn trong PHP giúp anh em dọn dẹp cái đống rác này trong vòng 1 nốt nhạc: http_build_query.

1. http_build_query là cái quái gì?

Đúng như tên gọi, hàm này sinh ra để xây dựng (build) một chuỗi truy vấn (query string) chuẩn chỉ cho URL từ một mảng (Array) hoặc một Object trong PHP.

Việc của anh em cực kỳ đơn giản: Vứt cho nó một cái mảng, nó sẽ tự động nối key và value bằng dấu =, nối các cặp với nhau bằng dấu &, và đặc biệt là tự động URL-encode (mã hóa các ký tự đặc biệt như khoảng trắng, tiếng Việt có dấu, dấu &, dấu =...) cực kỳ an toàn

Hãy xem nó biến hóa cái logic lằng nhằng phía trên thành một tác phẩm nghệ thuật nhé:

Kết quả in ra sẽ là:

https://api.my-ecommerce.com/products?category=skincare&price_min=100000&price_max=500000&brands%5B0%5D=vichy&brands%5B1%5D=laroche-posay&sort=price_asc&search=Kem+ch%E1%BB%91ng+n%E1%BA%AFng

Anh em thấy gì chưa?

  1. Nó tự động biến mảng brands thành brands[0]=vichy&brands[1]=laroche-posay cực kỳ chuẩn xác.
  2. Cụm từ "Kem chống nắng" được mã hóa an toàn thành Kem+ch%E1%BB%91ng+n%E1%BA%AFng mà anh em chả cần gọi hàm encode nào cả.

2. Những "Tuyệt chiêu" ẩn giấu của http_build_query

Gemini đã nói [PHP Thực Chiến] Dẹp bỏ trò "cộng chuỗi" URL phèn chúa với http_build_query

Chào anh em, lại là bố đời đây.

Làm Backend, chắc chắn anh em không thể né được cái cảnh phải gọi API sang một hệ thống khác (như tích hợp cổng thanh toán VNPay, Momo, hoặc gọi sang một service search nào đó). Và cái rắc rối thường gặp nhất chính là việc phải truyền một đống tham số (parameters) lên cái URL.

Giả sử anh em đang code tính năng filter cho một hệ thống e-commerce chuyên bán mỹ phẩm chẳng hạn. Khách hàng chọn: danh mục "skincare", giá từ 100k đến 500k, thương hiệu là "Vichy" và "La Roche-Posay", xếp theo giá tăng dần.

Nếu dùng tư duy "cộng chuỗi" truyền thống (thứ mà 90% anh em fresher hay làm), code của anh em trông sẽ tởm lợm như thế này:

Nhìn bẩn mắt không? Thiếu một cái dấu &, quên urlencode() một phát là API bên kia chửi "Bad Request" ngay. Hôm nay, mình sẽ giới thiệu (hoặc nhắc lại) cho anh em một hàm "thần thánh" có sẵn trong PHP giúp anh em dọn dẹp cái đống rác này trong vòng 1 nốt nhạc: http_build_query.

  1. http_build_query là cái quái gì? Đúng như tên gọi, hàm này sinh ra để xây dựng (build) một chuỗi truy vấn (query string) chuẩn chỉ cho URL từ một mảng (Array) hoặc một Object trong PHP.

Việc của anh em cực kỳ đơn giản: Vứt cho nó một cái mảng, nó sẽ tự động nối key và value bằng dấu =, nối các cặp với nhau bằng dấu &, và đặc biệt là tự động URL-encode (mã hóa các ký tự đặc biệt như khoảng trắng, tiếng Việt có dấu, dấu &, dấu =...) cực kỳ an toàn.

Hãy xem nó biến hóa cái logic lằng nhằng phía trên thành một tác phẩm nghệ thuật nhé:

Kết quả in ra sẽ là: https://api.my-ecommerce.com/products?category=skincare&price_min=100000&price_max=500000&brands[0]=vichy&brands[1]=laroche-posay&sort=price_asc&search=Kem+chống+nắng

Anh em thấy gì chưa?

Nó tự động biến mảng brands thành brands[0]=vichy&brands[1]=laroche-posay cực kỳ chuẩn xác.

Cụm từ "Kem chống nắng" được mã hóa an toàn thành Kem+ch%E1%BB%91ng+n%E1%BA%AFng mà anh em chả cần gọi hàm encode nào cả.

2. Những "Tuyệt chiêu" ẩn giấu của http_build_query

Phần lớn anh em chỉ ném một cái tham số đầu tiên (cái mảng) vào hàm này. Nhưng thực ra nó nhận tới 4 tham số lận. Dưới đây là 2 cái tham số phía sau cực hay mà ít ai để ý:

A. Tham số thứ 2: numeric_prefix (Cứu cánh khi mảng không có key) Giả sử anh em có một mảng chỉ chứa value (index là số): $data = ['apple', 'banana'];

Nếu dùng http_build_query($data), nó sẽ ra:0=apple&1=banana. Nhiều hệ thống nhận cái key là số nguyên 0, 1 nó sẽ báo lỗi biến không hợp lệ. Lúc này, anh em truyền thêm tham số thứ 2 vào làm tiền tố:

B. Tham số thứ 3: arg_separator (Đổi dấu &) Mặc định PHP nối các cặp key-value bằng dấu &. Nhưng nếu anh em đang làm việc với một cái API "dị hợm" nào đó yêu cầu phải nối bằng dấu chấm phẩy ; thì sao? Đơn giản:

3. Lưu ý xương máu khi xài (Gotchas)

Code nhàn là thế, nhưng anh em cũng cần để ý vài điểm nhỏ để không tự bóp dái mình:

  • Giá trị Null: Nếu trong mảng có một phần tử mang giá trị null, http_build_query sẽ bỏ qua luôn phần tử đó trong chuỗi output. Nếu API bên kia ép buộc phải có key đó (dù rỗng), hãy set nó là chuỗi rỗng "" thay vì null nhé.
  • Giá trị Boolean: Nếu là true, nó sẽ in ra 1. Nếu là false, nó sẽ in ra 0. Rất chuẩn mực cho việc truyền data qua HTTP.
  • Object cũng chơi được: Nếu anh em lười chuyển Object sang Array, cứ ném thẳng cái Object vào. Hàm này sẽ lấy các thuộc tính public của Object đó để build URL.

Chốt hạ

Làm Backend thì phải toát lên cái vẻ chuyên nghiệp, từ tư duy hệ thống cho đến những dòng code nhỏ nhất. Đừng bao giờ viết code cộng chuỗi URL bằng tay nữa, nó vừa xấu, vừa dễ dính lỗi cú pháp, lại vừa dễ bị hổng bảo mật (vì quên URL encode).

Cứ nhét hết data vào một cái mảng gọn gàng, rồi phang http_build_query là đời tươi sáng.

Anh em thấy tip này hữu ích thì cho mình xin một upvote nhé! Hoặc nếu anh em có đang dùng framework (như cái HTTP Client siêu xịn của Laravel) để lấp liếm đi cái hàm này thì comment chia sẻ anh em cùng học hỏi nha. Peace!


All rights reserved

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í