>백엔드 개발 >PHP 튜토리얼 >PHP 기술: PHP 프로그램에서 일부 잘못된 코드를 영리하게 피하는 방법

PHP 기술: PHP 프로그램에서 일부 잘못된 코드를 영리하게 피하는 방법

无忌哥哥
无忌哥哥원래의
2018-07-12 14:41:541594검색

이 기사에서는 PHP 예제 코드에서 잘못된 코드를 찾는 방법과 문제를 해결하는 방법을 공유합니다. 관심 있는 친구는 이를 참조할 수 있습니다.

저는 거의 1년 동안 PHP 개발을 해왔습니다. 올해 동안 저는 프로덕션 환경에서 많은 기술을 배웠고, 이 기간 동안 훌륭한 소스 코드와 코드에 관한 책도 읽었습니다. 나는 코드 작성에 대해 많은 생각을 해왔고, 다른 사람들이 작성한 좋은 코드와 나쁜 코드를 많이 보았습니다. 여기서는 내 자신의 통찰력과 개선 사항에 대해 이야기하겠습니다.

이 블로그는 코드를 작성할 때 코드를 명확하고 읽기 쉽게 만들고 함정을 피할 수 있는 규칙을 스스로 설정했습니다. 이러한 간단한 규칙은 디자인 패턴만큼 흥미롭지는 않지만 정기적으로 주의를 기울이면 코드가 더 깔끔하게 보일 수 있습니다.

1. 선언되지 않은 변수를 객체 외부에 사용하지 마세요

이 문제는 표현으로는 이해하기 어려울 수 있습니다. 이 문제는 PHP 언어 자체의 특성에 따라 결정됩니다. PHP는 약한 유형의 동적 스크립팅 언어이기 때문에 많은 경우 이 언어에는 개발자가 코드를 작성할 수 있는 매우 느슨한 조건이 제공됩니다. 그러나 종종 이러한 편리함이 함정으로 변할 수도 있으므로 동적 언어에서 몇 가지 편리한 작성 방법을 사용할 때는 특별한 주의를 기울여야 합니다.

먼저 클래스를 선언해 보겠습니다. 이 클래스의 배경 설정은 프레임워크와 함께 제공되며 수정이 허용되지 않는다는 것입니다. 실제 사례는 laravel을 참고하시기 바랍니다. 프레임워크의 Request 클래스 코드는 다음과 같습니다.

class User {
  public $username;
  public $password;
  
  public $otherInfo = [];
  
  
  public function readUserInfo() {
    return [
      'username' => $this->username,
      'password' => $this->password,
    ];
  }
  
  public function addAtri($info) {
    array_push($this->otherInfo, $info);
  }
}

이 코드는 상당히 만족스러울 것 같지만 다음으로 이 클래스를 운영해 보겠습니다.

$user = new User();
$user->userRealName = "hello world";

이러한 코드는 PHP에서는 전혀 문제가 없습니다. 실행되고 오류가 보고되지 않지만 이러한 코드는 후속 작업을 방해합니다. 이제 위의 코드가 PHP 웹 프로젝트의 인터셉터이거나 미들웨어라고 가정합니다. 그런 다음 컨트롤러에서 이 클래스의 인스턴스를 사용하고 다음과 같이 미들웨어에 추가된 변수를 사용합니다.

 class WebOperate {
   public function doOprate(User $user) {
     $user->userRealName = "hello world";
     next($user);
   }
 }

여기에 설정된 시나리오는 WebOperate가 미들웨어라는 것입니다. 모든 컨트롤러는 이 미들웨어를 거쳐 컨트롤러에 도달한 후 해당 컨트롤러 기능을 처리한 후 사용할 미들웨어 인스턴스를 삽입합니다. 컨트롤러와 미들웨어 개발자는 그 존재에 대해 별로 신경 쓰지 않습니다.

 class IndexController {
   public function index(User $user) {
     return $user->userRealName;
   }
 }

그리고 이러한 코드는 완벽하게 실행될 수 있습니다. 다음으로 개발자가 원하는 것은 이 User 클래스에 다른 기능을 추가하는 것입니다. 앞서 언급한 것처럼 이 클래스는 프레임워크 내부에 깊숙이 들어있어 찾기 어렵고, 다른 함수에서 이 클래스를 사용하기 때문에 수정이 불가능하므로 상속과 Add 메소드만 가능합니다. 개발 경험에 따르면 개발자는 이 userRealName 변수가 User 클래스에 존재한다고 생각할 것이므로 작성 방법은 다음과 같습니다.

먼저 이 User를 기반으로 파생된 Teacher 클래스:

 class Teacher extends User {
   public function sayHello() {
     return "hello world";
   }
 }

이런 식으로 우리는 선생님은 인사할 수 있지만, 이 때 여전히 컨트롤러에서 선생님의 실명을 알고 싶습니다. 어떻게 해야 할까요? 경험을 바탕으로 주입된 클래스를 Teacher로 변경하고 실제 이름을 반환할 수 있습니다.

 class IndexController {
   public function index(Teacher $user) {
     return $user->userRealName;
   }
 }

그러면 실제로 User 클래스에는 그러한 클래스가 없으므로 이 변수는 값이 없습니다. 다 그런데 경험상 미들웨어에 한번 값이 할당되어 있어서 바로 사용할 수 있어야 하는데 소스코드를 찾아보니 이 변수가 존재하지 않더라고요. 그렇다면 이전에는 이 변수를 사용할 수 있었던 이유는 미들웨어에서는 User의 강점에 가치가 부여되기 때문입니다.

따라서 선언되지 않은 변수를 클래스에서 직접 사용할 수 없습니다.

다음과 같이 작성해야 합니다.

class WebOperate {
  public function doOprate(User $user) {
    $user->addAtri([
      'userRealName' => 'hello world',
    ]);
    next($user);
  }
}

이러한 미들웨어, 상속된 클래스도 호출할 때 동일한 방법을 사용할 수 있으며 매우 간단하고 냄새가 나지 않습니다.

2. 클래스 또는 배열

사실 이 문제는 또 다른 문제로 이어지는데, 바로 함수 반환 값의 문제입니다.

우선, 함수가 여러 유형의 값을 반환하는 것은 좋지 않다고 개인적으로 생각한다는 점을 분명히 합니다. 이는 동적 언어에서 매우 일반적이며 PHP의 많은 기본 메서드에도 이것이 있습니다. , 이를 프로덕션에 사용하는 것은 적합하지 않습니다. 이 방법은 함수 반환에 불확실성을 야기하며, 우리의 결론을 증명하기 위해 많은 판단을 해야 합니다. 그러나 반환 값 유형이 하나만 있는 경우 직접 판단할 수 있습니다. 반환 값.

다음 코드와 같습니다:

public function addNewUser() {
    $res = $this->addData();
    if ($res) {
      return true;
    } else {
      return [
        'error' => 1,
        'errormsg' => "没有添加成功"
      ];
    }
  }

이와 같은 코드는 다음과 같이 호출자로서 한 번 더 판단을 내리는 경우가 많습니다.

public function index() {
    $res = $this->addNewUser();
    if (is_array($res) && isset($res['error'])) {
      return isset($res['errormsg']) ? $res['errormsg'] : "未知错误";
    }
    return "成功";
  }

이와 같은 코드는 함수가 실행될 때마다 이 오류가 발생합니다. 코드가 나타나면 코드가 아름답지 않을 뿐만 아니라 매우 부풀어 오른다.

이런 코드는 개선이 필요합니다. 먼저 함수의 반환 값을 제한하세요. 예를 들어, 이 함수는 부울 유형 숫자만 반환하도록 합니다:

public function addNewUser() {
  $res = $this->addData();
  if ($res) {
    return true;
  } else {
    return false;
  }
}

但是,显然,很多时候,我们要的不是简单的真价值,所以,我们会选择返回更多信息,这个时候,我们可以有三种处理方式。

1)返回int类型的数,然后通过这个int类型的数去判断处理结果,我们可以添加上映射关系:

class Operate{
  public $operateRes = [
    0 => '成功',
    1 => '添加失败',
    2 => '未知错误',
  ];
  
  
  public function addNewUser() {
    $res = $this->addData();
    if ($res) {
      return 0;
    } else if ($res > 1) {
      return 1;
    }
    return 2;
  }
  
}

这样方法的调用者就可以很简单的使用方法并给出提示了:

$opera = new Operate();
$res = $opera->addNewUser();
return $opera->operateRes[$res];

给出统一的返回值类型的时候就完全不需要判断返回值类型而且可以设置一个规范返回提示。

2)我们也可以使用数组

3)数组给人不缺定性,因为很多时候,数组里可以认为的少写一些元素,如果少写了,程序直接报错,很不好。

所以第三种方式就是建议将固定格式的返回,写成一个类,做返回的时候,使用这个类:

class Operate{
  public function addNewUser() {
    $res = $this->addData();
    $result = new Result();
    if ($res) {
      $result->errno = 0;
      $result->errmsg = "成功";
    } else if ($res > 1) {
      $result->errno = 1;
      $result->errmsg = "失败";
    }
    $result->errno = 2;
    $result->errmsg = "未知错误";
    return $result;
  }
  
}

class Result {
  public $errno;
  public $errmsg;
}

这样的返回,保证了所有变量的存在,同样可以减少一次判断。

所以,综合以上,在我们返回结果的时候,尽量使用同种类型的变量,尽量减少使用数组返回。

위 내용은 PHP 기술: PHP 프로그램에서 일부 잘못된 코드를 영리하게 피하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.