English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
이 튜토리얼에서는 PHP에서 object-oriented 방식으로 코드를 작성하는 방법을 배울 것입니다.
object-oriented programming(OOP)은 클래스와 객체 개념을 기반으로 한 프로그래밍 모델입니다. 프로세스 프로그래밍과 달리, 프로세스 프로그래밍의 중점은 데이터에 대한 작업을 수행하는 프로세스나 함수를 작성하는 것이며, object-oriented programming의 중점은 데이터와 함수를 모두 포함하는 객체를 생성하는 것입니다.
일반적이거나 프로세스 프로그래밍보다 object-oriented programming은 여러 가지 장점을 가지고 있습니다. 가장 중요한 것을 나열하면 다음과 같습니다:
그것은 프로그램에 명확한 모듈화 구조를 제공합니다.
그것은 「자신을 반복하지 마라」(DRY) 원칙을 준수하여 코드를 유지보수, 수정, 디버깅하기 쉽게 합니다.
그것은 더 적은 코드, 더 짧은 개발 시간, 그리고 높은 재사용성으로 복잡한 행동을 생성할 수 있게 합니다.
이 섹션에서는 PHP에서 클래스와 객체가 어떻게 작동하는지 설명할 것입니다.
提示:프로세스 프로그래밍 스타일로 작성된 프로그램은, 프로그램이 하나나 여러 개의 프로세스로 구성되어 있다는 것을 의미합니다. 프로세스는 특정 작업을 수행하기 위해 함께 실행되는 프로그래밍 문장의 집합입니다.
提示:「자신을 반복하지 마라」(Don't Repeat Yourself, DRY) 원칙의 의미는, 애플리케이션에서 자주 사용되는 코드를 추출하여 단일 위치에 배치하고, 반복 대신 재사용하여 코드의 반복을 줄이는 것입니다.
객체와 클래스는 object-oriented programming의 두 가지 주요 요소입니다. 클래스는 독립된 변수와 함수의 집합으로, 특정 작업을 수행하기 위해 협력하여 작동하며, 객체는 클래스의 단일 인스턴스입니다.
한 클래스는 템플릿이나 블루프린트로서, 여러 개의 단일 객체를 생성할 수 있습니다. 단일 객체를 생성할 때, 각 객체의 일부 속성이 다른 값이 있을 수 있지만, 그들은 동일한 일반 속성과 행동을 상속합니다.
예를 들어, 클래스를 집의 블루프린트로 볼 수 있습니다. 블루프린트 자체는 집이 아니라 집의 상세 계획입니다. 객체는 이 블루프린트에 따라 건설된 실제 집입니다. 동일한 블루프린트를 사용하여 여러 개의 동일한 집을 건설할 수 있지만, 각 집 내부는 다른 페인트, 인테리어 및 가정이 있을 수 있습니다. 그림과 같이:
class 키워드를 사용하여 클래스를 선언할 수 있습니다. 이 클래스 이름과 괄호()를 사용하여 다음 예제와 같이 표현할 수 있습니다.
Recangle.php라는 이름의 PHP 파일을 생성하고 다음 예제 코드를 넣어서, 클래스 코드를 프로그램의 나머지 부분과 분리할 수 있습니다. 그런 다음, 필요한 위치에서 Recangle.php 파일을 포함하면 됩니다.
<?php class Rectangle { //声明属性 public $length = 0; public $width = 0; //주기를 구하는 메서드 public function getPerimeter(){ return (2 * ($this->length + $this->width)); } //면적을 구하는 메서드 public function getArea(){ return ($this->length * $this->width); } } ?>
위의 예제에서 속성과 메서드 앞에 있는 public 키워드는접근 지정자이는 해당 속성이나 메서드가 어디서든 접근할 수 있다는 것을 의미합니다. 이에 대해 이후에 더 자세히 설명할 것입니다.
주의:문법적으로, 클래스의 변수는 속성으로, 함수는 메서드로 호출됩니다. 또한, 클래스 이름은 대체로 PascalCase(파스칼 이름법)으로 작성됩니다. 즉, 연결된 단어의 각 단어는 대문자로 시작합니다(예: MyClass).
다른 PHP 파일 test.php를 생성하고 다음 코드를 넣습니다.
<?php //클래스 정의를 포함합니다 class Rectangle { //声明属性 public $length = 0; public $width = 0; //주기를 구하는 메서드 public function getPerimeter(){ return (2 * ($this->length + $this->width)); } //면적을 구하는 메서드 public function getArea(){ return ($this->length * $this->width); } } //Rectangle 클래스에서 새로운 객체를 생성합니다 $obj = new Rectangle; //객체 속성 값을 가져옵니다 echo $obj->length; // 출력: 0 echo $obj->width; // 출력: 0 //设置对象属性值 $obj->length = 30; $obj->width = 20; //객체 속성 값을 다시 읽어 변경된 값을 표시합니다 echo $obj->length; // 출력: 30 echo "<br>"; echo $obj->width; // 출력: 20 //调用对象方法 echo $obj->getPerimeter(); // 출력: 100 echo "<br>"; echo $obj->getArea(); // 출력: 600 ?>测试看看‹/›
화살표 기호(-)은 객체의 포함된 속성과 메서드에 접근하기 위한 OOP 구조입니다. 가상 변수 $this는 호출된 객체(메서드가 속한 객체를 의미합니다)에 대한 참조를 제공합니다.
동일한 클래스의 여러 인스턴스를 사용할 때,面向对象编程의 진정한 힘은 명확하게 나타납니다. 다음 예제와 같이:
<?php //클래스 정의를 포함합니다 class Rectangle { //声明属性 public $length = 0; public $width = 0; //주기를 구하는 메서드 public function getPerimeter(){ return (2 * ($this->length + $this->width)); } //면적을 구하는 메서드 public function getArea(){ return ($this->length * $this->width); } } //Rectangle 클래스에서 여러 개의 객체를 생성합니다 $obj1 = new Rectangle; $obj2 = new Rectangle; //두 개의 객체 메서드 호출 echo $obj1->getArea(); //출력: 0 echo $obj2->getArea(); //출력: 0 //obj 설정1속성 값 $obj1->length = 30; $obj1->width = 20; //obj 설정2속성 값 $obj2->length = 35; $obj2->width = 50; //두 개의 객체 메서드를 다시 호출합니다 echo $obj1->getArea(); //출력:600 echo "<br>"; echo $obj2->getArea(); //출력:1750 ?>测试看看‹/›
위의 예제와 같이 다른 객체에서 getArea() 메서드를 호출하면 이 메서드가 다른 데이터 셋을 처리합니다. 각 객체 인스턴스는 완전히 독립적이며 자신의 속성과 메서드를 가지고 있으므로, 그들이 동일한 클래스에 속해 있더라도 독립적으로 처리할 수 있습니다.
面向对象的编程을 간소화하기 위해 PHP는 일부 마법 메서드를 제공합니다. 이 메서드는 객체에서 특정 작업이 발생할 때 자동으로 실행됩니다.
예를 들어, 새 객체가 생성될 때마다 마법 메서드 __construct()(구조 함수로 알려짐)이 자동으로 실행됩니다. 마찬가지로, 마법 메서드 __destruct()(분해 함수로 알려짐)이 객체가 파괴될 때 자동으로 실행됩니다. 객체를 파괴하면 분해 함수는 해당 객체에 할당된 모든 자원을 정리합니다.
<?php class MyClass { // 构造函数 public function __construct(){ echo ' 类 "' . __CLASS__ . '" 已启动<br>; } // 분해 함수 public function __destruct(){ echo '클래스 "' . __CLASS__ . '"이 파괴되었습니다<br>'; } } //새 객체 생성 $obj = new MyClass; //파일 끝에 메시지 출력 echo "파일 끝에 도달했습니다."; ?>测试看看‹/›
上面示例中的PHP代码将产生以下输出:
클래스 "MyClass"이 시작되었습니다 파일 끝에 도달했습니다. 클래스 "MyClass"이 파괴되었습니다
스크립트가 끝나면 자동으로 분해 함수가 호출됩니다. 그러나, 분해 함수를 명시적으로 트리거하려면 PHP unset() 함수를 사용하여 객체를 파괴할 수 있습니다. 다음과 같이 사용할 수 있습니다:
<?php class MyClass { // 构造函数 public function __construct(){ echo ' 类 "' . __CLASS__ . '" 已启动<br>; } // 분해 함수 public function __destruct(){ echo '클래스 "' . __CLASS__ . '"이 파괴되었습니다<br>'; } } //새 객체 생성 $obj = new MyClass; // 객체 파괴 unset($obj); //파일 끝에 메시지 출력 echo "파일 끝에 도달했습니다."; ?>测试看看‹/›
이제, 이 예제의 PHP 코드는 다음과 같은 출력을 생성합니다:
클래스 "MyClass"이 시작되었습니다 클래스 "MyClass"이 파괴되었습니다 파일 끝에 도달했습니다.
提示:스크립트가 완료되면 PHP는 실행 중에 할당된 모든 자원을 자동으로 정리합니다. 예를 들어, 데이터베이스 연결을 닫거나 객체를 파괴하는 것과 같습니다.
주의:__CLASS__는 다음과 같은마법常数에 포함된 클래스 이름이 있습니다. 클래스 외부에서 발생하면 비어 있습니다.
클래스는 extends 키워드를 사용하여 다른 클래스의 속성과 메서드를 상속할 수 있습니다. 상속 과정은 상속이라고 합니다. 이는面向对象的编程 모델을 사용하는 데 가장 강력한 이유 중 하나일 수 있습니다.
<?php //클래스 정의를 포함합니다 class Rectangle { //声明属性 public $length = 0; public $width = 0; //주기를 구하는 메서드 public function getPerimeter(){ return (2 * ($this->length + $this->width)); } //면적을 구하는 메서드 public function getArea(){ return ($this->length * $this->width); } } //기존 클래스 정의에 새 클래스를 정의합니다 class Square extends Rectangle { //이 메서드를 사용하여 사각형이 정사각형인지 테스트할 수 있습니다 public function isSquare(){ if($this->length == $this->width){ return true; // 正方形 } else{ return false; //不是正方形 } } } //从Square类创建一个新对象 $obj = new Square; // 设置对象属性值 $obj->length = 20; $obj->width = 20; // 调用对象方法 if($obj->isSquare()){ echo "正方形的面积是"; } else{ echo "矩形的面积是"; }; echo $obj->getArea(); ?>测试看看‹/›
上面示例中的PHP代码将产生以下输出:
正方形的面积是 400
正如您在上面的示例中看到的,尽管Square的类定义既没有显式包含getArea()方法,也没有显式包含$length和$width属性,但是Square类的实例可以使用它们,因为它们继承自父Rectangle类。
提示:由于子类是从父类派生的,因此也称为派生类,其父类称为基类。
在使用类时,您甚至可以使用可见性关键字来限制对其属性和方法的访问,以实现更好的控制。 有三个可见性关键字(从最可见到最不可见):public,protected,private,它们确定如何以及从何处访问和修改属性和方法。
public - 可以从类内部和外部的任何位置访问公共属性或方法。 这是PHP中所有类成员的默认可见性。
protected - 受保护的属性或方法只能从类本身或子类或继承类(即扩展该类的类)中访问。
private - 私有属性或方法只能从定义它的类中访问。甚至子类或继承的类也无法访问私有属性或方法。
以下示例将向您展示这种可见性实际上是如何工作的:
<?php //클래스 정의 class Automobile { //声明属性 public $fuel; protected $engine; private $transmission; } class Car extends Automobile { // 构造函数 public function __construct(){ echo ' 类 "' . __CLASS__ . '" 已启动<br>; } } //从Automobile类创建对象 $automobile = new Automobile; //尝试设置$automobile对象属性 $automobile->fuel = 'Petrol'; // ok $automobile->engine = '1500 cc'; // fatal error $automobile->transmission = 'Manual'; // fatal error //从Car类创建对象 $car = new Car; //尝试设置$car对象属性 $car->fuel = 'Diesel'; // ok $car->engine = '2200 cc'; // fatal error $car->transmission = 'Automatic'; // undefined ?>
접근성 외에도, 속성과 메서드는 static(정적)으로 선언될 수 있으며, 이는 그들이 클래스 인스턴스 없이도 접근할 수 있게 합니다. 다음과 같이 범위 해석 연산자(::)를 사용하여 정적 속성과 메서드에 접근할 수 있습니다: ClassName::$property와 ClassName::method()。
정적 메서드를 사용할 수 있지만, 다음 예제와 같이 정적 속성에 접근할 수 없습니다:
<?php //클래스 정의 class HelloClass { //정적 속성을 선언합니다 public static $greeting = "Hello World!"; //정적 메서드를 선언합니다 public static function sayHello(){ echo self::$greeting; } } //정적 속성과 메서드를 직접 접근하려고 시도하십시오 echo HelloClass::$greeting; //출력: Hello World! HelloClass::sayHello(); //출력: Hello World! //객체를 통해 정적 속성과 메서드를 접근하려고 시도하십시오 $hello = new HelloClass; echo $hello->greeting; // strict 경고 $hello->sayHello(); //출력: Hello World! ?>
위 예제에서의 키워드 self는 "현재 클래스"을 의미합니다. 이 키워드는 달러 기호($)로 시작될 수 없으며, 항상 :: 연산자(예: self :: $ name)로 시작됩니다.
self 키워드는 this 키워드와 다르며, "현재 객체" 또는 "클래스의 현재 인스턴스"을 의미합니다. 이 키워드는 항상 달러 기호($)로 시작되고, 그 뒤에-> 연산자(예: $ this-> name)。
주의:정적 메서드는 클래스 인스턴스(즉, 객체) 없이도 호출될 수 있으므로, 정적 메서드로 선언된 메서드에서 가상 변수 $this는 사용할 수 없습니다.
오브젝트-oriented programming의 기본 개념을 이제 이해하셨기를 바랍니다. PHP와 MySQL 데이터베이스 부분에서 OOP에 대한 더 많은 예제를 찾을 수 있습니다.