2011-10-04 6 views
0

저는 OOP (PHP)를 처음 사용하고 있으며 디자인 패턴 - singleton을 만났습니다. mysqli (싱글 톤 클래스)를 사용하는 DB 클래스를 찾았습니다. 일부 사용자 정의 방법을 추가했습니다 (insert_id(), query(), fetch_result() 등).PHP 싱글 톤 확장 클래스

그런 다음 UserTools이라는 새 클래스를 만들고 이전에 만든 메서드 (query(), fetch_result() 등)를 사용하도록 데이터베이스 클래스를 확장하려고합니다.

Fatal error: Call to private Database::__construct() from invalid context in (...) when I try to create instance of the new class (User Tools).

어떻게해야합니까 : 하지만이 오류가? 그것은 올바른 구조입니까?

+0

싱글턴 === 잘못하고 있습니다. 그것의 나쁜 디자인 패턴과 항상 피해야한다. – Raynos

답변

1

당신이 원하는 것을 달성하기 위해 여러 가지 방법이 있습니다 참조하십시오.

하나는 다음과 같습니다

class UserTools { 
    private $db; 
    function __construct() { 
     $this->db = Database::db_connect(); 
    } 

    function login() { /* ... */} 
} 

이 직접이 같은 생성자에 데이터베이스 인스턴스를 전달하는 데 더 좋을 거라하지만 당신이 정말로 게으른 경우

class UserTools { 
    private $db; 
    function __construct($db) { 
     $this->db = $db; 
    } 

    function login() { /* ... */} 
} 

// Usage 
$userTools = new UserTools(Database::db_connect()); 

방금 ​​수정할 수 귀하 데이터베이스 클래스를 만들고 public을 생성자로 지정하십시오.

class Database { 
    /* ... */ 
    public function __construct(){/* ... */} 
    /* ... */ 
} 

class UserTools extends Database {/* ... */} 

당신은 후자를 사용합니다. 정말 나쁜 코드이고 논리적 인 관점에서 이해가되지 않습니다. 귀하의 UserTools 클래스 데이터베이스 인스턴스를 사용하십시오. 아니요 데이터베이스입니다.

+0

두 번째를 사용하면 데이터베이스 클래스의 새 인스턴스가 만들어 집니까? (괜찮아요, btw, 고마워요.) –

+1

아니요. '데이터베이스'는 싱글 톤이므로 항상 동일한 인스턴스를 반환합니다. – Alfwed

+0

정말 고마워요! 그건 내 하루 였어. = D –

0

당신은 PHP에서 상속에

class UserTools extends DB { 
    .... 
} 

빠른 예를 들어 뭔가를 작성할 수

class A { 
    public $a; 
    public function set_a($new_a) { $this->a = $new_a; return $this; } 
    public function get_a() { return $this->a; } 
} 

class B extends A { 
    public $b; 
    public function set_b($new_b) { $this->b = $new_b; return $this; } 
    public function get_b() { return $this->b; } 
} 

$objb = new B(); 

$objb->set_a("Some Value")->get_a(); //Some Value 
+0

나는 그것을했다. 하지만 이것에 다음과 같이하면 좋을 것입니다 : public function login ($ un, $ pass) { // 여기서 DB의 메소드를 사용하고 싶습니까? } –

+0

'extends' 키워드는 모든 함수와 인스턴스 변수가 부모 ('DB') 클래스에서 자식'UserTools' 클래스로 상속되도록합니다. 더 많은 클래스를 추가 할 수 있습니다 ! –

+0

DB 싱글 톤을 확장하는 User 클래스가 올바른 일인 지 확신합니까? 논리적으로, 특히 –

1

이 메소드와 변수에만 protectedpublic가 확장을 통해 상속에 대한 이해입니다 개인은 아닙니다. 방법/변수를 private에서 protected으로 변경해보십시오. public은 모두에게 표시됩니다.

자세한 내용은 다음을 참조하십시오 PHP Visibility (Manual)

편집

는 싱글 톤 패턴을 이해합니다. 하나만 클래스 인스턴스가 예상되므로 '싱글 톤'이라고합니다. 이 때문에 싱글 톤 패턴을 구현하는 대부분의 클래스는 생성자를 private로 정의하여 둘 이상을 만드는 것을 제한합니다.

싱글 톤의 인스턴스를 만들려면 대부분의 클래스가 public 인 일종의 getInstance 정적 메서드를 정의합니다. 이 public 메소드는 private 생성자를 호출합니다. private 생성자는 클래스를 인스턴스화하려는 추가 시도를 방지하기 위해 클래스가 인스턴스화되었음을 나타내는 플래그를 설정합니다. getInstance 메서드는 생성자, 본질적으로 클래스의 인스턴스를 호출 한 결과를 반환합니다.

+0

+1 그게 오류라고 말합니다 – Xeoncross

+0

글쎄, 내 코드 아래 링크를 (pastebin 링크) 게시했습니다. 프로퍼티와 생성자는 private이며, 다른 것들은 public입니다. 하지만 나는 하나의 깡통을 이해할 수 없습니다. 수업을 연장 할 때 새로운 수업을 만들어야합니까? –

+0

아니요. 클래스를 정의 할 때 클래스를 확장합니다. 'new' 키워드를 사용하기 전까지는 클래스의 인스턴스를 만들지 않습니다. 건물에 대한 청사진을 한 세트 가져 가고 스코프 테이프가있는 다른 방에 대한 청사진을 추가한다고 상상해보십시오. 'new' 키워드를 사용하면 실제로 건물을 '빌드'합니다. –

0

대부분의 경우 싱글 톤 패턴은 생성자를 private (즉, private function __construct())로 정의하여 Singleton 클래스를 인스턴스화하는 것을 방지합니다.

그래서 사용자 정의 클래스 또는 확장중인 원본 클래스를 인스턴스화하려고하면 위의 메시지가 표시됩니다. 다른 클래스를 만들거나 함수를 정적으로 정의하고 사용해야합니다 (예 : public static function query($sql, $dbconnection)).

http://php.net/manual/en/language.oop5.patterns.php