2009-05-07 55 views
28

Tôi đang tự hỏi những gì tuyên bố của các loại dữ liệu trong bindParam() (hoặc bindValue()) được sử dụng cho ...PHP PDO :: bindParam() kiểu dữ liệu .. nó hoạt động như thế nào?

Ý tôi là, tôi nghĩ rằng nếu tôi xác định một đối số nguyên (PDO::PARAM_INT), đối số phải được chuyển đổi thành một số nguyên, chẳng hạn như

$delete->bindParam(1, $kill, PDO::PARAM_INT); 
// should work like 
$delete->bindParam(1, (int)$kill); 

hoặc ít nhất là lỗi nếu đối số không thuộc loại được khai báo. Nhưng đây không phải là trường hợp.

Googling xung quanh, tôi thấy rằng trong kho lưu trữ php.net:

Hi all,

Tôi hiện đang làm việc trên PDO. Chính xác trên hàm bindParam(). Dữ liệu tham số thứ ba có vẻ ở đây để buộc loại giá trị? Nhưng khi tôi cố gắng:

$sql = "INSERT INTO produit (idproduit, nom, marque) VALUES (NULL, :nom, :marque)"; 
$stmt = $dbh->prepare($sql); 
$nom = 'Testarossa'; $marque = 'Ferrari' ; 
$stmt->BindValue(':marque',$marque) ; 
$stmt->BindParam(':nom',$nom,PDO::PARAM_INT) ; 

$stmt->execute(); $nom = '250 GTO' ; 
$stmt->execute(); ?> 

tôi đã mong có hoặc là một lỗi PHP hoặc một interger trong cơ sở dữ liệu của tôi. Nhưng trong DB của tôi, tôi có:

22 Testarossa Ferrari 23 250 GTO Ferrari

Nó có nghĩa là nó không thay đổi nếu tôi có tham số thứ ba hay không. Hoặc có lẽ tôi nhớ điều gì đó. Ai đó có thể giúp tôi nhiều hơn? Hoặc chỉ ai đó có thể nói với tôi nơi tôi có thể tìm thấy thông tin về điều đó.

Kính trọng,

Cyruss

Đó là chính xác hoàn cảnh của tôi. Suy nghĩ của tôi đi sai ở đâu?

+1

"Tôi đã mong đợi có lỗi PHP hoặc một trình kết nối trong cơ sở dữ liệu của tôi". tôi quá – VolkerK

Trả lời

30

Trong khuôn khổ trừu tượng DB khác bằng các ngôn ngữ khác, nó có thể được sử dụng cho những thứ như đảm bảo rằng bạn đang làm đúng đắn thoát cho các giá trị trong lót (đối với trình điều khiển không hỗ trợ các thông số thích hợp ràng buộc) và cải thiện hiệu quả của mạng bằng cách đảm bảo các số được phân phối một cách thích hợp (hỗ trợ giao thức). Nó trông giống như trong PDO, nó không làm được gì nhiều.

if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) { 
       if (Z_TYPE_P(param->parameter) == IS_DOUBLE) { 
         char *p; 
         int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter)); 
         ZVAL_STRINGL(param->parameter, p, len, 0); 
       } else { 
         convert_to_string(param->parameter); 
       } 
     } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) { 
       convert_to_long(param->parameter); 
     } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) { 
       convert_to_boolean(param->parameter); 
     } 

Vì vậy, nếu bạn nói nó là một STR (hoặc nếu bạn nói gì cả vì đó là mặc định) và gõ nội bộ của dữ liệu của bạn là một đôi sau đó nó sẽ biến nó thành một chuỗi sử dụng một phương pháp, nếu nó không phải là gấp đôi thì nó sẽ chuyển đổi nó thành một chuỗi bằng cách sử dụng một phương thức khác.

Nếu bạn nói đó là một int nhưng nó thực sự là một bool sau đó nó sẽ chuyển đổi nó thành một dài.

Nếu bạn nói đó là một bool nhưng nó thực sự là một số sau đó nó sẽ chuyển nó thành một boolean đúng.

Điều này thực sự là tất cả những gì tôi thấy (nhanh chóng) nhìn vào nguồn stmt, tôi tưởng tượng một khi bạn vượt qua các thông số vào trình điều khiển họ có thể làm phép thuật bổ sung. Vì vậy, tôi đoán rằng tất cả các bạn nhận được là một chút làm đúng và rất nhiều toàn bộ hành vi mơ hồ và phương sai giữa các trình điều khiển.

+1

Doh, tôi đã đăng tải ninja. Đoán tôi chỉ trả lời chậm thôi ^^. – gradbot

+0

Chết tiệt, tôi nghĩ nó đã trốn thoát./Chạy về nhà để sửa mã. –

+0

Ah ok, tôi đã tìm thấy http://php.net/manual/en/pdo.prepared-statements.php không có lỗi. –

5

Có ít nhất một tác dụng PDO :: PARAM_INT đã trên INSERT truy vấn: các giá trị boolean được chuyển đổi thành 0 hoặc 1. Giống như trong

$i = true; 
$stmt->bindParam(':i', $v, PDO::PARAM_INT);

pdo_stmt.c:

else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) { 
     convert_to_long(param->parameter); 
}

+1

Oh .. im tự hỏi nếu hiệu ứng này thực sự là hữu ích .. những gì về data_typeS khác? chuỗi, v.v ...? – Strae

+0

Tôi chưa tìm thấy tài liệu đáng tin cậy cho các tính năng này. Vì vậy, tôi có thể đi qua tất cả các mã trong/ext/pdo * ... hoặc đơn giản là không dựa vào tham số đó cho các truy vấn INSERT, UPDATE .... – VolkerK

+0

Ok, tôi sẽ thử dùng các truy vấn SELECT để xem liệu 'vấn đề' có ảnh hưởng đến chúng không ... Buồn, dù sao, việc khai báo data_type sẽ hữu ích ngay cả đối với việc kiểm soát luồng/vệ sinh trong các truy vấn INSERT . – Strae

3

tôi đã cố gắng điều tương tự với BindValue và nhận được kết quả tương tự, do đó hành vi mà bạn đang thấy không giới hạn ở bindParam.

$stmt->BindValue(':marque', $marque) ; 
$stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ; 

$stmt->execute(); 
$nom = '250 GTO'; 
$stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ; 
$stmt->execute(); 
19

Vì vậy, tôi quyết định đi sâu vào mã nguồn PHP và đây là những gì tôi đã tìm thấy.

static int really_register_bound_param trong ext/PDO/pdo_stmt.c trên đường dây 329 của phiên bản 5.2.9

if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) { 
    if (Z_TYPE_P(param->parameter) == IS_DOUBLE) { 
     char *p; 
     int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter)); 
     ZVAL_STRINGL(param->parameter, p, len, 0); 
    } else { 
     convert_to_string(param->parameter); 
    } 
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) { 
    convert_to_long(param->parameter); 
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) { 
    convert_to_boolean(param->parameter); 
} 

Đây là những chuyển đổi PDO làm trong ràng buộc.

  • PDO :: PARAM_STR chuyển đổi bất kỳ nội dung nào bạn đưa chuỗi thành chuỗi trừ null.
  • PDO :: PARAM_INT chuyển đổi bools vào chờ đợi
  • PDO :: PARAM_BOOL chuyển chờ đợi vào bools

Vậy là xong. Không có gì khác được chuyển đổi. PDO sử dụng các cờ PARAM để định dạng SQL không sử dụng các kiểu dữ liệu.

+0

"PDO :: PARAM_STR chuyển đổi bất kỳ thứ gì bạn đưa nó thành chuỗi" ngoại trừ NULL –

Các vấn đề liên quan