Quản lý lượng lớn mã trạng thái function trong php

Hiện, mỗi function, khi truy vấn không đủ điều kiện (else) thì mình return ra đoạn json chứa mã trạng thái (code) như 1, 2, 3, 4, 5… để xem truy vấn đó đi đến bước nào trong function.

Nhưng do có nhiều function và các mã này trùng lặp, có thư viện nào giúp giải quyết vấn đề này không mọi người.

Ví dụ:

class user extends core {

    public function checkInput(array $input) {
        if (!empty($input['name'])) {
             if (!empty($input['phone'])) {
                 return json_encode('status' => 'success', 'code' => 3);
             } else {
                 return json_encode('status' => 'false', 'code' => 2);
             }
        } else {
            return json_encode(array('status' => 'false', 'code' => 1));
        }
    }

    public function addUser(array $input) {
    
        $response = json_decode($this->checkInput('name' => $input['name'], 'phone' => $input['phone']));

        if ($response['status'] == 'success') {

            // code tạo user....
            return json_encode(array('status' => 'success', 'code' => 2));
        } else {
            return json_encode(array('status' => 'false', 'code' => $response['code']));
        }
    }
}

Sau khi mã lỗi xuất hiện thì bạn phải kết thúc hàm ngay chứ nhỉ

2 Likes

Quăng exception kèm message.

Mã giả:

catch (lỗi1) {
    raise(message1)
}
catch (lỗi2) {
    raise(message2)
}
...
3 Likes

Đúng rồi bạn. Function nằm trong nhiều class, mà các class lại kế thừa với nhau liên tục. Các mã code này gặp trùng lặp, mình muốn nó tự sinh ra một mã cố định và tự lưu trữ hay cách nào đó giúp quản lý.

Ví dụ:

class user extends core {

    public function checkInput(array $input) {
        if (!empty($input['name'])) {
             if (!empty($input['phone'])) {
                 return json_encode('status' => 'success', 'code' => 3);
             } else {
                 return json_encode('status' => 'false', 'code' => 2);
             }
        } else {
            return json_encode(array('status' => 'false', 'code' => 1));
        }
    }

    public function addUser(array $input) {
    
        $response = json_decode($this->checkInput('name' => $input['name'], 'phone' => $input['phone']));

        if ($response['status'] == 'success') {
            // code tạo user....
            return json_encode(array('status' => 'success', 'code' => 2));
        } else {
            return json_encode(array('status' => 'false', 'code' => $response['code']));
        }
    }
}

Không. Bạn không hiểu ý mình rồi. Bạn xem bình luận trên mình vừa viết nha @noname00.

Mình vừa sửa lại bài viết cho dễ hiểu hơn. Bạn có thể xem lại giúp mình với @noname00 @noz1995

Code này ‘smell’ khiếp quá. Lâu rồi không đụng vào PHP nên chỉ biết comment 1 số phương pháp clean code:

  1. Điều kiện if có return nên không cần else nữa.
  2. 'code' => 1|2|3, 3 số 1,2,3 không có nghĩa gì cả, sau này ai đọc lại code thì khó chịu lắm, bạn có thể extract ra 1 số constant, ví dụ: SUCCESS=1, FAILUE=2…
  3. https://github.com/vlucas/valitron, thư viện này xử lý tham số đầu vào. GG keyword có thể là: ‘input validation’
1 Like

Cảm ơn bạn. Như function checkInput, nếu còn có check birthday, gender, email nữa thì để biết được nó ngừng ở đâu khi mình gọi lại function này từ function khác thì mình phải return thêm code 1,2,3,4… Mình muốn tìm cách quản lý những mã code này để tránh trùng lặp. @doanguyen

Bình thường thì có lỗi phải log ra, lỗi nào log lỗi đấy là đúng, không tránh được. Nhưng mà code này của bạn xấu quá :joy:

Bạn nên viết hàm nào đó kiểu này (mình không học php, không biết cú pháp này có đúng không):

function error_encode(bool $success, int $code)
{
	if ($success)
		$status = 'success';
	else
		$status = 'false';
	return json_encode('status' => $status, 'code' => $code);
}

Thứ hai là đoạn nào return trong if thì không cần else nữa, cho nó ngắn code
Thứ ba là đoạn code check nên để trong khối if, như vậy có thể return luôn, đoạn code chính sẽ để ở ngoài, thay vì để ở trong khối else khó theo dõi:

public function addUser(array $input)
{    
	$response = json_decode($this->checkInput('name' => $input['name'], 'phone' => $input['phone']));
	if ($response['status'] != 'success')
		return error_encode(false,  $response['code']);

	// code tạo user....
	return error_encode(true,  Code.INFO2);
}

Nếu bạn sợ trùng thì quản lý theo từng khối. Chẳng hạn 0->999 là lỗi về kết nối, 1000->1999 là lỗi về validate, 2000->2999 là lỗi về quá tải đường truyền… gì đó, lỗi nào thì đặt tên riêng cho nó cho dễ đọc.

3 Likes

Cảm ơn bạn. Về phần $response['code'], mình cần phải đặt một mã, nhưng nếu nhiều function, mà function nào cũng bắt đầu đặt từ 1,2,3… có cách nào để quản lý mã này không bạn, thư viện…

Thế thì vấn đề mấu chốt là tại sao function nào cũng là 1, 2, 3? Tại sao không phải là những function này thì 1, 2, 3; những fuction nào đó khác thì 1001, 1002, 1003; những fuction nào đó khác nữa thì 2001, 2002, 2003…?

1 Like

Cảm ơn bạn. Mình có một câu hỏi, mình dùng các thư viện php, mà do PHP chỉ cho phép extends duy nhất một class, mà tất cả các class của mình đều đã extends, giờ mình muốn đưa các function của thư viện này để truy vấn trong class thì lại không được, có cách nào không bạn, nếu có thể gọi như trait thì tốt quá

Bạn @noname00 đưa đúng hướng rồi, vấn đề còn lại là tìm hiểu các xử lý Exception trong framework thôi.

<?php

class UserController extends Controller
{
   public function login($username, $password)
   {
       try {
           UserAuth::login($username, $password);
       } catch ($ex) {
           throw new UnauthorizedException("...", $ex);
       }
   }
}

class UnauthorizedException extends Exception { }

class ExceptionHandler
{
   public function handle($ex)
   {
       if ($ex instanceof UnauthorizedException) {
           return json()->with([
               'status_code' => 403,
               'error' => [
                   'message' => $ex->message,
                   'description' => $ex->description
               ]
           ]);
       }
   }
}

class Bootstrap
{
   protected $exceptionHandler;
   
   public function handle()
   {
       // ...
       try {
           $controller = new UserController();
           $controller->login($username, $password);
       } catch ($ex) {
           $exceptionHandler->handle($ex);
      }
   }
}
4 Likes

Cảm ơn Hùng nhiều @hungaya

Mình đang gặp vấn đề lâu nay, mình dùng các thư viện php, mà do PHP chỉ cho phép extends duy nhất một class trong mỗi class, mà tất cả các class của mình đều đã extends, giờ mình muốn đưa các function của thư viện này để truy vấn trong class thì lại không được, có cách nào không bạn, nếu có thể gọi như trait thì tốt quá

Bạn đâu cần phải extends một thư viện để có thể truy vấn? :thinking: Dùng require, include mà thêm thư viện vào dùng thôi, trùng tên function thì thêm namespace. :no_mouth:
Còn nếu trùng output thì do bạn rồi, sao không hiển thị thông tin rõ ràng hơn.
Nếu chỉ cần theo dõi các bước truy vấn thì dùng XDebug.

3 Likes

Ý bạn là bạn muốn một cơ chế để handle exception?
Mình không code PHP, nhưng mình nghĩ ý tưởng này của mình sẽ có ích
Đầu tiên bạn có thể viết một class response gồm

  • code chứa HTTP Status Code, code này là tiêu chuẩn nên PHP có lib sẵn cho chuyện này
  • message là message trả về cho UI
  • data là object mà backend trả về cho UI

VD1:

{
    "code": 200,
    "message": "found",
    "data": {
        "username": "adam",
        "age": 20,
        "email": "[email protected]"
    }
}

VD2:

{
    "code": 404,
    "message": "User not found",
    "data": null
}

Khi bạn trả về response thì theo cấu trúc đó thôi, nếu gặp lỗi như validation hay try-catch thì return ra response ngay

Còn một cách khác là viết một controller/service để handle exception. Nếu gặp lỗi thì throw ra exception thì tự động controller/service phụ trách việc handle exception sẽ làm việc tách message + status lỗi từ exception ra, build thành response rồi trả về cho UI

3 Likes

Cảm ơn bạn @SakaDream . Mình vừa làm cách này.

Mình đang gặp vấn đề lâu nay, mình dùng các thư viện php, mà do PHP chỉ cho phép extends duy nhất một class trong mỗi class, mà tất cả các class của mình đều đã extends, giờ mình muốn đưa các function của thư viện này để truy vấn trong class thì lại không được, có cách nào không bạn, nếu có thể gọi như trait thì tốt quá.

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?