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

PHP 기본 강의

PHP 고급 강의

PHP & MySQL

PHP 참조 매뉴얼

PHP object oriented

object-oriented program design(영어: Object-oriented programming, 약자: OOP)에서, 객체는 정보와 정보를 처리하는 설명으로 구성된 전체로, 현실 세계의 추상화입니다.

현실 세계에서 우리가 직면한 모든 사물은 객체입니다. 컴퓨터, 텔레비전, 자전거와 같습니다.

객체의 주요 세 가지 특성:

  • 객체의 행위: 객체에 적용할 수 있는 작업으로, 켜기, 끄기는 행위입니다.

  • 객체의 형태: 어떤 메서드를 적용하면 객체는 어떻게 반응할지, 색상, 크기, 형태와 같습니다.

  • 객체의 표현: 객체의 표현은 신분증과 같으며, 동일한 행위와 상태에서 어떻게 다른지 구분합니다.

예를 들어, Animal(동물)은 추상 클래스로, 개와 양과 같은 개체를 구체적으로 구분할 수 있으며, 개와 양은 구체적인 객체로, 색상 속성이 있으며 쓰기, 달리기와 같은 행위 상태가 있습니다.

객체 지향 내용

  • 클래스 − 한 가지 사물의 추상적인 특징을 정의합니다. 클래스 정의는 데이터의 형식과 데이터에 대한 작업을 포함합니다.

  • 객체 − 클래스의 예제입니다.

  • 멤버 변수 − 클래스 내부에 정의된 변수로, 이 변수의 값은 외부에서는 보이지 않지만, 멤버 함수를 통해 접근할 수 있습니다. 클래스가 객체로 예제화되면, 이 변수는 객체의 속성으로 불립니다.

  • 멤버 함수 − 클래스 내부에 정의된 것으로, 객체 데이터에 접근할 수 있습니다.

  • 상속 − 상속성은 자식 클래스가 부모 클래스 데이터 구조와 메서드를 자동으로 공유하는 메커니즘으로, 클래스 간의 관계 중 하나입니다. 클래스를 정의하고 구현할 때, 이미 존재하는 클래스의 기반 위에서 진행할 수 있습니다. 이미 존재하는 클래스에서 정의된 내용을 자신의 내용으로 사용하고, 새로운 내용을 추가할 수 있습니다.

  • 부모 클래스 − 어떤 클래스가 다른 클래스에 상속되면 그 클래스를 부모 클래스, 기본 클래스, 슈퍼 클래스라고 부릅니다.

  • 자식 클래스 − 어떤 클래스가 다른 클래스를 상속받으면 이를 자식 클래스라고도 불렀고,도출 클래스라고도 합니다.

  • 다형성 − 다형성은 동일한 함수나 메서드가 여러 가지 타입의 객체에 작용하여 다른 결과를 얻는 것을 의미합니다. 다른 객체는 동일한 메시지를 받아 다른 결과를 생성할 수 있는 현상을 다형성이라고 합니다.

  • 중복 − 간단히 말해,同名의 함수나 메서드가 동일하지만 매개변수 목록이 다른 경우입니다. 이와 같은同名 다 매개변수의 함수나 메서드는 서로를 중복로 부르며, 중복 함수나 메서드라고 합니다.

  • 추상성 − 추상성은 일관된 데이터 구조(속성)와 행위(작업)를 가진 객체를 클래스로 추상화하는 것을 의미합니다. 클래스는 이와 같은 추상화로, 응용과 관련된 중요한 성질을 반영하면서 다른 일부 관련 없는 내용을 무시합니다. 어떤 클래스의 분류는 주관적이지만, 반드시 구체적인 응용과 관련해야 합니다.

  • 밀봉성 − 밀봉성은 현실 세계에 존재하는 어떤 도체의 속성과 행위를 결합하여 하나의 논리적 단위에 배치하는 것을 의미합니다.

  • 생성자 − 주로 객체를 생성할 때 객체를 초기화하는 데 사용되며, 즉 객체 멤버 변수에 초기 값을 할당하는 것으로, 객체 생성 문장에서 항상 new 연산자와 함께 사용됩니다.

  • 소멸 함수 − 디스트럭터(destructor)는 생성자와 반대로, 객체가 그 생명주기를 끝내면(예: 객체가 있는 함수가 호출되었을 때) 시스템이 자동으로 디스트럭터를 실행합니다. 디스트럭터는 종종 "정리" 작업을 위해 사용됩니다(예: 객체를 생성할 때 new로 메모리 공간을 할당했을 때, 종료 전에 디스트럭터에서 delete를 사용하여 메모리를 해제해야 합니다).

아래 그림에서는 Car 클래스를 사용하여 세 개의 객체를 생성했습니다: Mercedes, Bmw, 그리고 Audi.

$mercedes = new Car();
$bmw = new Car();
$audi = new Car();

PHP 클래스 정의

PHP에서 클래스 정의는 일반적으로 다음과 같은 문법 형식으로 정의됩니다:

<?php
class phpClass {
  var $var1;
  var $var2 = 'constant string';
  
  function myfunc($arg1, $arg2) {
     [..]
  }
  [..]
}
?>

해석하면 다음과 같습니다:

  • 클래스 사용 class 클래스 이름 뒤에 키워드를 추가하여 정의합니다.

  • 클래스 이름 뒤의 대括호({}) 내에서 변수와 메서드를 정의할 수 있습니다.

  • 클래스 변수는 다음과 같이 사용됩니다 var 로 선언할 수 있으며, 변수는 초기화 값도 설정할 수 있습니다.

  • 함수 정의는 PHP 함수 정의와 유사하지만, 함수는 해당 클래스와 생성된 객체만으로 접근할 수 있습니다.

예제

<?php
class Site {
  /* 멤버 변수 */
  var $url;
  var $title;
  
  /* 멤버 함수 */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
?>

변수 $this 자신의 객체를 의미합니다.

PHP_EOL newline character.

PHP에서 객체 생성

클래스가 생성되면, 다음과 같이 사용할 수 있습니다 new 연산자를 사용하여 클래스의 객체를 생성합니다:

$w3codebox = new Site;
$taobao = new Site;
$google = new Site;

위 코드에서는 세 개의 객체를 생성했습니다. 세 개의 객체는 모두 독립적입니다. 다음은 멤버 메서드와 멤버 변수에 접근하는 방법을 보겠습니다.

멤버 메서드 호출

객체를 생성한 후에는 이 객체를 사용하여 멤버 메서드를 호출할 수 있습니다. 이 객체의 멤버 메서드는 해당 객체의 멤버 변수만操作할 수 있습니다:

// 챠널 멤버 함수 호출하여 제목과 URL 설정
$w3codebox->setTitle( "기본 튜토리얼 웹" );
$taobao->setTitle('淘宝');
$google->setTitle( "Google 검색" );
$w3codebox->setUrl( 'www.w3>setUrl( 'codebox.com' );
$taobao->setUrl('www.taobao.com');
$google->setUrl( 'www.google.com' );
// 멤버 함수 호출하여 제목과 URL을 가져옵니다
$w3codebox->getTitle();
$taobao->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$taobao->getUrl();
$google->getUrl();

전체 코드는 다음과 같습니다:

온라인 예제

<?php
class Site {
  /* 멤버 변수 */
  var $url;
  var $title;
  
  /* 멤버 함수 */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
$w3codebox = new Site;
$taobao = new Site;
$google = new Site;
// 챠널 멤버 함수 호출하여 제목과 URL 설정
$w3codebox->setTitle( "기본 튜토리얼 웹" );
$taobao->setTitle( "天猫商城" );
$google->setTitle( "Google 검색" );
$w3codebox->setUrl( 'www.w3>setUrl( 'codebox.com' );
$taobao->setUrl( 'www.tmall.com' );
$google->setUrl( 'www.google.com' );
// 멤버 함수 호출하여 제목과 URL을 가져옵니다
$w3codebox->getTitle();
$taobao->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$taobao->getUrl();
$google->getUrl();
?>

위 코드를 실행하면, 출력 결과는 다음과 같습니다:

기본 튜토리얼 웹
天猫商城
Google 검색
ko.oldtoolbag.com
www.tmall.com
www.google.com

PHP 생성 함수

생성 함수는 특별한 메서드입니다. 주로 객체를 생성할 때 객체를 초기화하는 데 사용되며, 즉 객체 멤버 변수에 초기 값을 할당합니다. 객체 생성 문장에서 new 연산자와 함께 사용됩니다.

PHP 5 개발자가 클래스에서 소멸 함수로 사용할 메서드를 정의할 수 있습니다. 문법 형식은 다음과 같습니다:

void __construct ([ mixed $args [, $... ]]] )

위의 예제에서는 생성자를 통해 $url과 $title 변수를 초기화할 수 있습니다:

function __construct( $par1, $par2 ) {
   $this->url = $par1;
   $this->title = $par2;
}

이제 setTitle과 setUrl 메서드를 호출할 필요가 없습니다:

온라인 예제

$w3codebox = new Site('ko.oldtoolbag.com', '기본 튜토리얼 웹');
$tmall = new Site('www.tmall.com', '天猫商城');
$google = new Site('www.google.com', 'Google 검색');
// 멤버 함수 호출하여 제목과 URL을 가져옵니다
$w3codebox->getTitle();
$tmall->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$tmall->getUrl();
$google->getUrl();

소멸 함수

소멸 함수(destructor)는 생성 함수와 반대로, 객체가 그 생명주기를 끝내면(예를 들어, 객체가 있는 함수가 호출되었을 때), 시스템이 자동으로 소멸 함수를 실행합니다.

PHP 5 소멸 함수 개념이 도입되었습니다. 이는 다른 객체 지향 언어와 유사합니다. 문법 형식은 다음과 같습니다:

void __destruct ( void )

예제

<?php
class MyDestructableClass {
   function __construct() {
       print "구조 함수\n";
       $this->name = "MyDestructableClass";
   }
   function __destruct() {
       print "소멸 " . $this->name . "\n";
   }
}
$obj = new MyDestructableClass();
?>

위 코드를 실행하면, 출력 결과는 다음과 같습니다:

생성자
MyDestructableClass 소멸

상속

PHP는 키워드 extends PHP는 다중 상속을 지원하지 않기 때문에, 클래스를 상속하기 위해서는 위의 형식을 사용합니다:

class Child extends Parent {
   // 코드 부분
}

예제

예제에서 Child_Site 클래스가 Site 클래스를 상속하고 기능을 확장했습니다:

<?php 
// 자식 클래스가 사이트 카테고리를 확장합니다
class Child_Site extends Site {
   var $category;
    function setCate($par){
        $this->category = $par;
    }
  
    function getCate(){
        echo $this->category . PHP_EOL;
    }
}

메서드 오버라이드

부모 클래스에서 메서드가 자식 클래스의 요구를 충족시키지 않는 경우, 메서드를 수정할 수 있습니다. 이 과정을 메서드 오버라이드(override)라고도 합니다.

예제에서 getUrl과 getTitle 메서드를 재정의했습니다:

function getUrl() {
   echo $this->url . PHP_EOL;
   return $this->url;
}
   
function getTitle(){
   echo $this->title . PHP_EOL;
   return $this->title;
}

접근 제어

PHP는 공개적, 보호적, 비공개적 키워드를 앞에 추가하여 속성이나 메서드의 접근 제어를 구현합니다.

  • public(공개적):공개적 클래스 구성원은 어디서든 접근할 수 있습니다.

  • protected(보호적):보호적 클래스 구성원은 자신과 자식 클래스 및 부모 클래스에서 접근할 수 있습니다.

  • private(비공개적):비공개적 클래스 구성원은 정의된 클래스에서만 접근할 수 있습니다.

속성 접근 제어

클래스 속성은 공개적, 보호적, 비공개적 중 하나로 정의되어야 합니다. var으로 정의된 경우 공개적으로 간주됩니다.

<?php
/**
 * MyClass 정의
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj = new MyClass();
echo $obj->public; // 이 줄은 정상적으로 실행됩니다
echo $obj->protected; // 이 줄은 즉사적인 오류를 발생시킵니다
echo $obj->private; // 이 줄도 중요한 오류가 발생할 수 있습니다
$obj->printHello(); // Public, Protected 및 Private 출력
/**
 *MyClass 정의2
 */
class MyClass2 extends MyClass
{
    // public과 protected는 재정의될 수 있지만, private는 재정의될 수 없습니다
    protected $protected = 'Protected'2';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj2 = new MyClass2();
echo $obj2->public; // 이 줄은 정상적으로 실행됩니다
echo $obj2->private; // 미정의 private
echo $obj2->protected; // 이 줄은 즉사적인 오류를 발생시킵니다
$obj2->printHello(); // Public, Protected 출력2 와 미정의
?>

메서드의 접근 제어

클래스 내의 메서드는 공유적, 비공유적 또는 보호적로 정의될 수 있습니다. 이 키워드가 설정되지 않으면 메서드는 기본적으로 공유적입니다.

<?php
/**
 * MyClass 정의
 */
class MyClass
{
    // 공유적 생성자를 선언합니다
    public function __construct() { }
    // 공유적 메서드를 선언합니다
    public function MyPublic() { }
    // 보호적 메서드를 선언합니다
    protected function MyProtected() { }
    // 비공유적 메서드를 선언합니다
    private function MyPrivate() { }
    // 이 메서드는 공유적입니다
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}
$myclass = new MyClass;
$myclass->MyPublic(); // 이 줄은 정상적으로 실행됩니다
$myclass->MyProtected(); // 이 줄은 즉사적인 오류를 발생시킵니다
$myclass->MyPrivate(); // 이 줄은 즉사적인 오류를 발생시킵니다
$myclass->Foo(); // 공유적, 보호적, 비공유적 모두 실행될 수 있습니다
/**
 * MyClass 정의2
 */
class MyClass2 extends MyClass
{
    // 이 메서드는 공유적입니다
    function Foo2();
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate(); // 이 줄은 즉사적인 오류를 발생시킵니다
    }
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 이 줄은 정상적으로 실행됩니다
$myclass2->Foo2(); // 공유적과 보호적인 것들은 실행될 수 있지만, 비공유적은 실행될 수 없습니다
class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }
    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}
class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate 
                // Foo::testPublic
?>

인터페이스

인터페이스(interface)를 사용하여 특정 클래스가 구현해야 하는 메서드를 지정할 수 있지만, 이 메서드의 구체적인 내용을 정의할 필요는 없습니다.

인터페이스는 interface 키워드로 정의된 것과 마찬가지로, 표준 클래스와 마찬가지로 정의하지만, 정의된 모든 메서드는 비어 있습니다.

인터페이스에서 정의된 모든 메서드는 공개적이어야 하며, 이는 인터페이스의 특성입니다.

인터페이스를 구현하려면 implements 계산자. 클래스는 인터페이스에서 정의된 모든 메서드를 구현해야 하며, 그렇지 않으면 致命 오류가 발생합니다. 클래스는 여러 인터페이스를 구현할 수 있으며, 여러 인터페이스 이름을 콤마로 구분할 수 있습니다.

<?php
// iTemplate 인터페이스를 선언합니다
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
// 인터페이스 구현
class Template implements iTemplate
{
    private $vars = array();
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
  
    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{'. $name .'}', $value, $template);
        }
 
        return $template;
    }
}

상수

클래스에서 항상 일정한 값을 상수로 정의할 수 있습니다. 상수를 정의하고 사용할 때는 $ 기호를 사용하지 않습니다.

상수의 값은 반드시 정수이어야 하며, 변수, 클래스 속성, 수학 연산 결과 또는 함수 호출일 수 없습니다.

PHP에서 5.3.0부터, 클래스를 동적으로 호출할 수 있는 변수를 사용할 수 있습니다. 그러나 이 변수의 값은 키워드(예: self, parent 또는 static)가 될 수 없습니다.

예제

<?php
class MyClass
{
    const constant = '常量值';
    function showConstant() {
        echo self::constant . PHP_EOL;
    }
}
echo MyClass::constant . PHP_EOL;
$classname = "MyClass";
echo $classname::constant . PHP_EOL; // 부터 5.3.0 부터
$class = new MyClass();
$class->showConstant();
echo $class::constant . PHP_EOL; // PHP에서 5.3.0 부터
?>

추상 클래스

어떤 클래스에도, 그 클래스에서 least 하나의 메서드가 추상으로 선언되어 있다면, 그 클래스는 추상으로 선언되어야 합니다.

추상으로 정의된 클래스는 인스턴스화될 수 없습니다.

추상으로 정의된 메서드는 호출 방식( 매개변수)만 선언되며, 구체적인 기능 구현은 정의되지 않습니다.

추상 클래스를 상속받을 때, 자식 클래스는 부모 클래스에서의 모든 추상 메서드를 정의해야 합니다. 또한, 이 메서드의 접근 제어는 부모 클래스와 같아야하거나 더 넓어야 합니다. 예를 들어, 특정 추상 메서드가 보호된 메서드로 선언되었을 경우, 자식 클래스에서 구현된 메서드는 보호된 메서드나 공개된 메서드로 선언되어야 하며, 사생활적인 메서드로 정의될 수 없습니다.

<?php
abstract class AbstractClass
{
 // 자식 클래스는 이러한 메서드를 정의해야 합니다.
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);
    // 일반 메서드(추상 메서드가 아닌 메서드)
    public function printOut() {
        print $this->getValue() . PHP_EOL;
    }
}
class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}
class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>

위 코드를 실행하면, 출력 결과는 다음과 같습니다:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

또한, 자식 클래스 메서드는 부모 클래스 추상 메서드에 존재하지 않는 선택적 매개변수를 포함할 수 있습니다.

예를 들어, 자식 클래스는 선택적 매개변수를 정의했지만, 부모 클래스의 추상 메서드 선언에 없더라도 정상적으로 실행될 수 있습니다.

<?php
abstract class AbstractClass
{
    // 우리의 추상 메서드는 필요한 매개변수만 정의해야 합니다.
    abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
    // 우리의 서브 클래스는 부모 클래스의 서명에 존재하지 않는 선택적 매개변수를 정의할 수 있습니다.
    public function prefixName($name, $separator = ".") {
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }
        return "{$prefix}{$separator} {$name}";
    }
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>

출력 결과는 다음과 같습니다:

Mr. Pacman
Mrs. Pacwoman

Static 키워드

클래스 속성이나 메서드를 static(정적)으로 선언하면 클래스를 인스턴스화하지 않고도 직접 접근할 수 있습니다.

정적 속성은 클래스가 이미 인스턴스화된 객체를 통해 접근할 수 없습니다. (하지만 정적 메서드는 가능합니다).

정적 메서드는 객체를 통해 호출되지 않기 때문에, 정적 메서드에서는 $this 표현식이 사용할 수 없습니다.

정적 속성은 객체를 통해 접근할 수 없습니다. -> 연산자를 사용하여 접근할 수 있습니다.

PHP에서 5.3.0부터, 클래스를 동적으로 호출할 수 있는 변수를 사용할 수 있습니다. 그러나 이 변수의 값은 self, parent 또는 static와 같은 키워드일 수 없습니다.

<?php
class Foo {
  public static $my_static = 'foo';
  
  public function staticValue() {
     return self::$my_static;
  }
}
print Foo::$my_static . PHP_EOL;
$foo = new Foo();
print $foo->staticValue() . PHP_EOL;
?>

위 프로그램을 실행하면, 출력 결과는 다음과 같습니다:

foo
foo

Final 키워드

PHP 5 final 키워드가 추가되었습니다. 부모 클래스에서 메서드가 final로 선언되면 자식 클래스는 이 메서드를 오버라이드할 수 없습니다. 클래스가 final로 선언되면 상속할 수 없습니다.

다음 코드 실행 시 오류가 발생합니다:

<?php
class BaseClass {
   public function test() {
       echo "BaseClass::test() called" . PHP_EOL;
   }
   
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called" . PHP_EOL;
   }
}
class ChildClass extends BaseClass {
   public function moreTesting() {
       echo "ChildClass::moreTesting() called" . PHP_EOL;
   }
}
// 에러 메시지Fatal error: Cannot override final method BaseClass::moreTesting()
?>

부모 클래스 생성자 메서드 호출

PHP는 자식 클래스의 생성자 메서드에서 자동으로 부모 클래스의 생성자 메서드를 호출하지 않습니다. 부모 클래스의 생성자 메서드를 호출하려면, 자식 클래스의 생성자 메서드에서 호출해야 합니다 parent::__construct()

<?php
class BaseClass {
   function __construct() {
       print "BaseClass 클래스의 생성자 메서드" . PHP_EOL;
   }
}
class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();  // 자식 클래스 생성자 메서드는 자동으로 부모 클래스의 생성자 메서드를 호출할 수 없습니다
       print "SubClass 클래스의 생성자 메서드" . PHP_EOL;
   }
}
class OtherSubClass extends BaseClass {
    // BaseClass의 생성자 메서드를 상속
}
// BaseClass 생성자 메서드 호출
$obj = new BaseClass();
// BaseClass, SubClass 생성자 메서드 호출
$obj = new SubClass();
// BaseClass 생성자 메서드 호출
$obj = new OtherSubClass();
?>

위 프로그램을 실행하면, 출력 결과는 다음과 같습니다:

BaseClass 클래스의 생성자 메서드
BaseClass 클래스의 생성자 메서드
SubClass 클래스의 생성자 메서드
BaseClass 클래스의 생성자 메서드