NHỮNG LỖI HAY GẶP KHI LÀM DỰ ÁN PHP
09/03/2022 547

Trong bài viết này, anh Trần Quý Miêng – người đã có một khoảng thời gian dài làm việc trong lĩnh vực IT, trải qua nhiều dự án với các vai trò khác nhau tại CO-WELL Asia sẽ chia sẻ về các lỗi hay gặp trong một dự án PHP. Hy vọng sẽ giúp mọi người phòng tránh, hoặc tham khảo hướng giải quyết khi gặp phải trong quá trình thực hiện dự án nhé.
1. Lỗi sử dụng biến mà chưa check xem index có hay chưa, đối tượng có null hay không
Mình dám chắc đến 99% anh em đã gặp vs bị lỗi này (cả mình thời gian đầu cũng hay mắc phải)
local.ERROR: Undefined index: test {“userId”:273,“exception”:"[object] (ErrorException(code: 0): Undefined index: test at
local.ERROR: Trying to get property of non-object {“userId”:273,“exception”:"[object] (ErrorException(code: 0): Trying to get property of non-object at
Vấn đề này hầu hết các bạn đã gặp nhìn là hiểu ra vấn đề ngay nhưng lại rất hay bị lặp lại, không chỉ bị ở PHP mà cả ở JS.
Theo mình để hạn chế lỗi trên có các cách sau:
- Luôn coi các hàm của mình là 1 black box thực hiện validation và check các biến đc truyền vào và lấy ra từ 1 hàm khác xem có không và có đúng vs giá trị mình mong muốn không. Quan điểm của mình là không tin vào ai, đẩy lên từ người dùng hay giá trị trả về từ 1 hàm khác.
- Khi test luôn test đủ case không có giá trị, giá trị truyền lên không đúng như mong muốn, giá trị truyền lên đúng. Trên browser các bạn cứ thử sửa name hay id của element rồi test xem sao. Gần đây Vue, React phát triển nên chúng ta viết nhiều API, khi đó các bạn nên test API khi không gửi 1 tham số nào thì nó có lỗi không.
- Về mặt code, các bạn có thể tham khảo ở ngày các code của các framework mà các bạn đang làm. Tại sao khi chúng ta dùng hàm $request->get(‘dealerId’); không bao giờ lỗi Undefined index nếu xem qua src core sẽ thấy họ có check
return \array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
Vậy sao chúng ta lại không thể dựng hàm cho riêng mình? Như mình có viết hàm này để dùng cho việc get data từ 1 mảng. Tương tự với 1 object cũng cần check xem object đó có hay null trước khi thao tác với object.
public static function getData($arrayData, $key, $default = null){
if(isset($arrayData[$key])){
return $arrayData[$key];
}
return $default;
}
2. Việc sử dụng try catch vs log
Khi viết code, anh em rất quen thuộc vs việc dùng try catch nhưng lại không viết log trong catch, có thể do anh em quen vs việc dùng môi trường local khi có lỗi sẽ dùng dd để điều tra vs tái hiện. Nhưng khi dự án được đẩy lên môi trường Product, 1 ngày đẹp trời khách báo có lỗi thì sẽ như thế nào? Về cơ bản, chúng ta không thể lấy data từ Product được, và có nhưng lỗi không tái hiện được ngoài môi trường Product thì khi đó phải xử lý làm sao? Thế nên khi các bạn dùng try catch nên dùng log để log ra các lỗi khi có exception xảy ra. Tôi khuyên các bạn nên dùng cách Log
\Log::error("prefix: " . $e);
Khi đó nếu có lỗi, các bạn sẽ có khá nhiều thông tin để phán đoán đó là lỗi gì.
Các bạn cũng nên chú ý log level chỗ nào dùng error chỗ nào dùng info. Mình thấy có nhiều bạn log ra các thông tin để debug nhưng lại dùng Log::error. Khi dự án có hệ thống quản lý log các bạn sẽ nhận được rất nhiều mail báo có log error mà trong khi thực tế lại không phải vậy
3. Việc xử lý Data base trong vòng lặp
Cái này mình cũng thấy rất nhiều người làm. Về căn bản, khi làm trên local thì data ít và database vs web service là trên cùng 1 PC nên các bạn sẽ không thấy sự khác biệt là mấy. Nhưng khi deploy trên hệ thống thì database vs web service sẽ ở 2 nơi khác nhau nên việc xử lý database trong vòng lặp sẽ có nhiều ảnh hưởng.
Hãy tưởng tượng, bạn đang ở tầng 8 là web server, còn tầng 1 chính là data base. Khi các bạn thao tác vs data base thì tương tự như các bạn ở tầng 8 xuống tầng 1 lấy đồ lên (GET) hay cất đồ vào (INSERT). Chỉ có 1 thang máy từ tầng 8 xuống tầng 1, mà bạn có tận 10 món đồ cần xuống tầng 8 để xử lý (lấy hay cất đi). Giả sử 1 lần thang máy đi mất 2 phút, nếu mỗi lần các bạn xử lý 1 đồ thì 10 đồ sẽ mất ~ 10×2 = 20 phút. Nhưng nếu 1 lần các bạn lấy luôn 10 đồ thì các bạn chỉ mất có ~2 phút để xử lý. Đến đây các bạn hiểu sao không nên xử lý database trong loop rồi đúng không.
Nhưng sẽ có bạn hỏi thế 10 đồ đó nặng 1 tấn trong khi tháng máy của bạn 1 lần chỉ max chở đc 0.5 tấn thì sao. Cũng giống như hệ thống của bạn data truyền gửi từ webservice đến database cũng có 1 giá trị giới hạn thế nên bài toán ở đây là trong vòng lặp cần tính toán ước lượng được lượng data 1 lần có thể gửi để chia ra thành các gói cần thiết, vừa gửi được sang database vừa đảm bảo số lần gửi ít nhất. Như bài toán trên nếu thang máy chỉ chở đc 0.5 tấn thì không thể cùng lúc xử lý 10 đồ được thay vào đó chúng ra cần chia ra làm 2 lần mỗi lần xử lý 5 đồ.
Kết lại
Và trên đây là một số lỗi mà team hay mắc phải khi triển khai dự án PHP. Hy vọng có thể giúp mọi người chú ý hơn và khắc phục hoàn toàn được những lỗi này. Đừng quên theo dõi chuyên mục CODEWELL trên website CO-WELL Asia để đón đọc những bài viết công nghệ bổ ích nhé!
Trần Quý Miêng – CO-WELL Asia.