2015-01-13 8 views
1

나는 상당히 새로 온 상황

에 덮어지고 있지 PHP에서 객체 지향 프로그래밍을 현재 나는 목적을 배우기위한 작은 CMS를 만드는거야. 나는 OOP에 관해서 많은 것을 배웠다. 그러나 나는 지금 이상한 문제에 직면하고있다. 데이터베이스 연결 및 쿼리를 처리하기 위해 Singleton 클래스를 만들었습니다.PHP 변수가 후속 쿼리

public static function getInstance() 
{ 
    if(!isset(self::$instance)) 
    { 
     self::$instance = new Database(); 
    } 

    return self::$instance; 
} 

같은 클래스에서 쿼리를 실행하는 방법도 있습니다. 준비된 명령.에 Y 인드 할 매개 변수가있는 선택적 매개 변수 W 조회와 두 개의 매개 변수가 필요합니다. 아래 소스를 볼 수 있습니다. 나는 같은 페이지에 여러 쿼리가있는 경우

public function execute($query, $params = array()) 
{ 
    $this->error = false; // Set 'error' to false at the start of each query. 

    if($this->query = $this->pdo->prepare($query)) 
    { 
     if(!empty($params)) 
     { 
      $index = 1; 
      foreach($params as $parameter) 
      { 
       $this->query->bindValue($index, $parameter); 
       ++$index; 
      } 
     } 

     if($this->query->execute()) 
     { 
      $this->results = $this->query->fetchAll(PDO::FETCH_OBJ); 
      $this->count = $this->query->rowCount(); 
     } 
     else 
     { 
      $this->error = true; 
     } 
    } 

    return $this; 
} 

문제는

resultscount 변수는 여전히 첫 번째 쿼리의 값이 포함되어 있습니다. 첫 번째 쿼리가 내 데이터베이스에서 모든 사용자를 검색한다고 가정 해보십시오. 두 번째 쿼리는 데이터베이스에서 모든 블로그 게시물을 검색합니다. 아무 것도 없다고 가정 해 봅시다. 게시물이 없으면 메시지를 표시하고, 그렇지 않으면 루프를 실행하여 모든 결과를 표시합니다. 이 경우 블로그 게시물이 없어도 루프가 실행됩니다. count 변수는 데이터베이스에 게시물이 있는지 여부를 확인하는 데 사용되고 첫 번째 쿼리의 15 개를 여전히 보유하고 있기 때문에 루프가 실행됩니다.

이것은 분명히 약간의 오류를 유발합니다. results과 동일합니다. 여전히 첫 번째 쿼리의 값을 보유합니다.

$query = Database::getInstance()->execute('SELECT * FROM articles ORDER BY article_id DESC'); 

if(!$query->countRes()) 
{ 
    echo '<h2>There are no blog posts in the database.</h2>'; 
} 
else 
{ 
    foreach($query->results() as $query) 
    { 
     echo '<article> 
       <h3>'.$query->article_heading.'</h3> 
       <p>'.$query->article_preview.'</p> 
       </article>'; 
    } 
} 

countRes()results() 방법은 단순히 DB 클래스에서 변수를 반환합니다.

나는 이해할 수있는 문제를 설명하기를 희망한다. 응답은 매우 감사합니다.

+1

오 gawd는'->'주위에 공백을 두지 마십시오. – Madbreaks

+1

좋아요, 내 게시물을 편집하고 제거했습니다. –

+1

두 번째 쿼리에서'prepare()'가 성공 했습니까? 그것이 실패하면,'execute'에있는 나머지 코드는 건너 뛸 것이므로, 변수는 갱신되지 않을 것입니다. PDO에 대해 오류 신호가 활성화되어 있는지 확인하십시오. – Barmar

답변

1

글로벌 데이터베이스 개체에 쿼리 관련 데이터를 연결하지 않도록 응답 개체를 사용합니다.

예 :

데이터베이스 클래스 다음
<?php 

class PDO_Response { 
    protected $count; 
    protected $results; 
    protected $query; 
    protected $error; 
    protected $success = true; 


    public function __construct($query){ 
     $this->query = $query; 
     try{ 
      $this->query->execute(); 
     }catch(PDOException $e){ 
      $this->error = $e; 
      $this->success = false; 


     } 

     return $this; 
    } 

    public function getCount(){ 
     if(is_null($this->count)){ 
      $this->count = $this->query->rowCount(); 
     } 
     return $this->count; 
    } 

    public function getResults(){ 
     if(is_null($this->results)){ 
      $this->results = $this->query->fetchAll(PDO::FETCH_OBJ); 
     } 
     return $this->results; 
    } 

    public function success(){ 
     return $this->success; 
    } 

    public function getError(){ 
     return $this->error; 
    } 
} 

: (테스트하지)

사용 예제

처리 오류에 대한 응답 클래스로 이동 실행 :

public function execute($query, $params = array()) 
{ 
    if($this -> _query = $this -> _pdo -> prepare($query)) 
    { 
     if(!empty($params)) 
     { 
      $index = 1; 

      foreach($params as $parameter) 
      { 
       $this -> _query -> bindValue($index, $parameter); 
       ++$index; 
      } 
     } 

     return new PDO_Response($this->_query); 
    } 

    throw new Exception('Some error text here'); 
} 

UPDATE

$select = $database->execute('SELECT * FROM table'); 

if($select->success()){ 
    //query succeeded - do what you want with the response 
    //SELECT 
    $results = $select->getResults(); 
} 

$update = $database->execute('UPDATE table SET col = "value"'); 

if($update->success()){ 
    //cool, the update worked 
} 

이렇게하면 후속 쿼리가 실패 할 경우 데이터베이스 개체에 연결된 이전 쿼리 데이터가 없어지지 않으므로 문제를 해결하는 데 도움이됩니다.

+0

이것은 자신의 접근 방식이 작동하지 않는 이유에 대한 op의 질문에 대답하지 않습니다. – Madbreaks

+0

맞아요.하지만 나에게 괜찮은 해결책처럼 들립니다. 그런 접근 방식에 문제가 있습니까? –

+0

필자가 마지막으로 추가 한 내용은이 방법으로 새로운 응답에서 오래된 데이터를 가져 오는 것을 방지 할 수있는 방법을 설명합니다. 이 방법의 가장 큰 차이점은 응답 개체에서 새 데이터베이스 호출을 연결 유지할 수 없다는 것입니다. 이제 두 가지를 분리했습니다. $ response 객체를 반환하는 하나의 $ database 객체가 있습니다. –

관련 문제