English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PHP 기본 튜토리얼

PHP 고급 튜토리얼

PHP & MySQL

PHP 참조 가이드

PHP 클래스와 객체

이 튜토리얼에서는 PHP에서 object-oriented 방식으로 코드를 작성하는 방법을 배울 것입니다.

object-oriented programming이란 무엇인가요

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).

클래스를 정의하면 new 키워드를 사용하여 해당 클래스에서 객체를 생성할 수 있습니다. 이 객체 인스턴스를 통해 직접 클래스 메서드와 속성에 접근할 수 있습니다.

다른 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에 대한 더 많은 예제를 찾을 수 있습니다.