2014-05-20 3 views
0

클래스라는 Form이 있습니다. 나는 레코드를 데이터베이스에 저장하기 위해 호출하는 add_form() 메서드를 가지고있다. add_form()은 기본적으로 레코드를 데이터베이스에 추가하고 영향을받는 행을 반환합니다. 클래스 또는 OOP 접근법을 사용하지 않고이 함수를 사용할 때 제대로 작동합니다. 하지만 이제 exec()가 정의되지 않은 함수라는 오류가 발생합니다. 가변 개수가 정의되지 않았습니까? 그것은 단지 쿼리를 실행하는 execute() 대신 영향을받는 행을 반환하기 때문에 exec()를 사용합니다.PDO MySQL 클래스 함수

class Forms 
{ 
    private $database; 
    private $count; 

    public function __construct(PDO $database) 
    { 
    $this->database = $database; 
    } 

    function add_form($lastname, $firstname, $island, $region, $province, $baranggay, $city, $address, $gender, $birthdate) 
    { 
    $sql = "INSERT INTO forms (lastname, firstname, island, region, province, baranggay, city, address, gender, birthdate) VALUES (:lastname, :firstname, :island, :region, :province, :baranggay, :city, :address, :gender, :birthdate)"; 
    $stmt = $this->database->prepare($sql); 
    $count->exec(array(
        ':lastname'=>$lastname, 
        ':firstname'=>$firstname, 
        ':island'=>$island, 
        ':region'=>$region, 
        ':province'=>$province, 
        ':baranggay'=>$baranggay, 
        ':city'=>$city, 
        ':address'=>$address, 
        ':gender'=>$gender, 
        ':birthdate'=>$birthdate 
       )); 
    return $count; 
    } 

} 
+1

오류 메시지를 전체적으로 포함 시키십시오. 코드를 직접 디버깅하려고 시도한 내용을 알려주십시오. 물론 : [RT (F) M] (http://www.php.net/PDO) ... –

답변

2

최초의 것들의 커플 : 전화를해야하는 방법은 exec, PDOStatement::execute을하지라고합니다. exec 방법은 PDO 클래스 as the manual clearly shows의 방법입니다. 그러나 PDO::exec은 준비된 문을 사용하지 않으므로 안전하지 않으므로 PDOStatement을 사용하고 적절한 방법을 사용하는 것이 좋습니다. 그것은
다음, 당신이 $stmt라는 변수에 준비된 명령문 (PDOStatement 예)를 할당하지만 정의되지 않은 변수exec를 호출 ... 역시 준비된 문에서 영향을받는 행의 수를 얻기 위해 매우 쉽습니다 : $count :

$stmt = $this->database->prepare($sql); 
    $count->exec(array(//<--- should be $stmt->execute(array()); 
        ':lastname'=>$lastname, 
        ':firstname'=>$firstname, 
        ':island'=>$island, 
        ':region'=>$region, 
        ':province'=>$province, 
        ':baranggay'=>$baranggay, 
        ':city'=>$city, 
        ':address'=>$address, 
        ':gender'=>$gender, 
        ':birthdate'=>$birthdate 
)); 

그런 다음, 영향을받는 행의 수를 얻기 위해, 당신은 the rowCount method 호출 할 필요가 :

return $stmt->rowCount(); 

함께 이러한 문제를 넣고 어플리 코드에 에드, 당신은 당신의 코드를 변경해야합니다 쿼리에

$vals = array(
    'firstname' => 'Joe', 
    'lastname' => 'Goodboy' 
); 
$count = $pdo->exec(
    'INSERT INTO hackable (firstname, lastname) 
    VALUES ("'.$vals['firstname'].'", "'.$vals['lastname'].'")' 
);//all is well 
//BUT: 
$vals = array(
    'firstname' => 'Evil", /*', 
    'lastname' => '*/ (SELECT CONCAT_WS(",", id, username, password) 
     FROM users 
     WHERE isAdmin = 1 
     LIMIT 1 
    )); --' 
$count = $pdo->exec(
    'INSERT INTO hackable (firstname, lastname) 
    VALUES ("'.$vals['firstname'].'", "'.$vals['lastname'].'")' 
);//OUCH!! 

후자의 입력 결과 :

INSERT INTO hackable (firstname, lastname) 
VALUES ("Evil", /*, "*/ 
    (SELECT CONCAT_WS(",", id, username, password) 
    FROM users 
    WHERE isAdmin = 1 
    )); -- ", "") 
완성도를 들어

$stmt->execute(array()); 
$count = $stmt->rowCount(); 
//optional: 
$stmt->closeCursor(); 
return $count; 

, 여기 exec를 사용하여 안전하지 않은 버전입니다

그냥 사용자 입력으로 쿼리를 실행하는 것이 나쁜 생각이라는 것을 보여주는 것입니다 ...

asside로 일부 코드 검토 :
항상subscribe to the coding standards most major players subscribe to을 작성하는 습관을 기르게하십시오. 즉, 메소드는 camalCased 여야합니다. add_formaddForm이어야합니다. 또한 자신에게 부탁을하고, 문서 블록을 추가

/** 
* Inserts data provided by $bind into forms table 
* @param array $bind 
* @return int 
* @throw PDOException (if PDO::ERRMODE is set to PDO::ERRMODE_EXCEPTION) 
*/ 
public function addForm(array $bind) 
{//PUBLIC + camelCased name 
    $stmt = $this->database->prepare($queryString); 
    $stmt->execute($bind); 
    return $stmt->rowCount(); 
} 

그러나 전체에

형태는 고정 된 레이아웃을 가지고 있으며, 지정된 값 번호가 예상된다. 당신은 내가 세터와 게터를 사용하도록 촉구 이유를 알고 싶은 경우에,

class From extends DataModel 
{//where DataModel is an abstract class 
    protected $lastname = null; 
    protected $firstname = null; 
    //all properties hiere 
    public function __construct(array $data) 
    {//use assoc array in constructor 
     foreach ($data as $key => $value) 
     { 
      $setter = 'set'.ucfirst($key); 
      if (method_exists($this, $setter))//define setters for properties! 
       $this->{$setter}($value); 
     } 
    } 
    /** 
    * method to turn instance into bind array 
    * Optionally omit null values for WHERE clauses 
    * @param bool $includeNulls = true 
    * @return array 
    */ 
    public function toBind ($includeNulls = true) 
    { 
     $bind = array(
      ':firstname' => $this->firstname, 
      ':lastname' => $this->lastname, 
      //do this for all properties 
     ); 
     if ($includeNulls === false) 
      return array_filter($bind);//unset null values 
     return $bind; 
    } 
} 

을 대신 check out some of my answers on codereview.stackexchange, 마법 __get__set 호출 : 큰 프로젝트에서, 당신은 아마 이것에 대한 데이터 클래스를 정의하게 될 겁니다. 이전에 자세히 설명했습니다.