2013-03-16 9 views
5

Xin chào tôi có một mẫu trường 70/80 mà tôi cần chèn vào bảng để thay vì tạo thủ công một câu lệnh chèn lớn trước hết tôi đã tạo một bảng trong db của tôi từ tên của các yếu tố đầu vào trong biểu mẫu ở đây là mã mà tôi sử dụng để tạo/thay đổi bảngCập nhật Mysqli ném Gọi tới hàm thành viên bind_param() lỗi

function createTable($array, $memberMysqli) 
{ 
    foreach ($array as $key => $value) 
    { 
      //echo "<p>Key: ".$key." => Value: ".$value . "</p>"; 
      $query = "ALTER TABLE questionnaire ADD ".$key." text"; 

      if($stmt = $memberMysqli->prepare($query)) 
      { 
       $success = $stmt->execute(); 
      } 
    } 
     echo "<h1>Array count: ". count($array) ."</h1>" ; 
} 

Điều này làm việc tốt và thay đổi chính xác như tôi muốn. Bây giờ để chèn các giá trị biểu mẫu để làm điều này tôi làm một trường chèn cơ bản lưu trữ id của hàng và sau đó có vòng lặp tất cả các biến đăng cập nhật hàng đó. Đây là mã của tôi cho điều đó:

$stmt = $memberMysqli->prepare("INSERT INTO questionnaire(userid) VALUES (?)"); 

$stmt->bind_param('s', $_POST['userid']); 
$stmt->execute(); 
$rowid = $stmt->insert_id; 
$stmt->close(); 

$memberMysqli->autocommit(FALSE); 

function updateColumn($memberMysqli, $query, $uid, $value) 
{ 
    if ($value) 
    { 
     $stmt = $memberMysqli->prepare($query); 
     //Throws bind param error here 
     $stmt->bind_param("ss", $value, $uid); 
     $stmt->execute(); 
    } 
} 

function loopInputs($array, $memberMysqli, $rowid) 
{ 
    foreach ($array as $key => $formvalue) 
    { 
     var_dump($key); 
     updateColumn($memberMysqli, "UPDATE questionnaire SET $key = ? WHERE id = ?", $rowid, $formvalue); 
    } 
} 

loopInputs($_POST, $memberMysqli, $rowid); 

$memberMysqli->commit(); 
$memberMysqli->close(); 

Điều này tạo ra lỗi liên kết và tôi không biết tại sao. Bất kỳ sự trợ giúp nào đều sẽ là tuyệt vời.

Trả lời

7

O, hãy thử một câu trả lời chuẩn.

Call to a member function (hoặc expects parameter 1 to be mysqli_result, boolean given cho kiểu thủ tục) không phải là lỗi mà chỉ là một lỗi triệu chứng, đối với một số vấn đề khác.
Thông báo lỗi này có nghĩa là không có đối tượng nào được tạo ở nơi cần.

Vì vậy - đã xảy ra sự cố khi tạo đối tượng $stmt.
Rất có thể đó là vấn đề với truy vấn. Vì vậy, chúng tôi cần theo dõi lỗi đó.

Mysqli sẽ không cho bạn biết điều gì đang xảy ra trừ khi được yêu cầu một cách rõ ràng. Vì vậy, bạn phải luôn kiểm tra kết quả của mọi chức năng mysqli tương tác với máy chủ và nếu kết quả là FALSE - hãy kiểm tra $mysqli->error.

Điều cũng rất quan trọng là chuyển thông báo lỗi mysqli thành lỗi PHP, để cho nó đi theo cài đặt báo cáo lỗi trên toàn trang.

Nếu bạn đang sử dụng mysqli_query() trên mã ứng dụng mà không đóng gói nó vào một số lớp trợ giúp, trigger_error() là cách tốt để tăng lỗi PHP, vì nó sẽ cho bạn biết tệp và số dòng xảy ra lỗi

Vì vậy, tất cả các bạn prepare(), thực hiện() và query() cuộc gọi đã được viết theo cách này:

$stmt = $mysqli->prepare($query) or trigger_error($mysqli->error."[$query]"); 

hoặc theo kiểu thủ tục

$res = mysqli_query($mysqli,$query) or trigger_error(mysqli_error($mysqli)."[$query]"); 

trong tất cả các tập lệnh của bạn
và kể từ đó bạn sẽ được thông báo về lý do, tại sao đối tượng không được tạo. (Nếu bạn tò mò về cú pháp này or, I've explained it here) Lưu ý rằng truy vấn cũng có trong thông báo lỗi, để cho phép bạn kiểm tra nó trực quan và thử nghiệm trong một môi trường khác.

Tuy nhiên, nếu bạn đóng gói truy vấn vào một số lớp, tệp và dòng từ lỗi kích hoạt sẽ hoàn toàn vô dụng vì chúng sẽ trỏ đến chính cuộc gọi chứ không phải mã ứng dụng gây ra sự cố nhất định.Vì vậy, khi chạy lệnh mysqli đóng gói, một cách khác để có thể được sử dụng:

$result = $mysqli->query($sql); 
if (!$result) { 
    throw new Exception($mysqli->error." [$query]"); 
} 

như ngoại lệ sẽ cung cấp cho bạn một stack trace, mà sẽ dẫn bạn những nơi mà từ đó một truy vấn có sai sót đã được gọi.

Lưu ý rằng bạn có thể thấy các lỗi PHP nói chung. Trên một trang web hoạt động bạn phải lén vào các bản ghi lỗi, vì vậy, cài đặt phải

error_reporting(E_ALL); 
ini_set('display_errors',0); 
ini_set('log_errors',1); 

trong khi trên một máy chủ phát triển địa phương đó là tất cả quyền thực hiện các lỗi trên màn hình:

error_reporting(E_ALL); 
ini_set('display_errors',1); 

và tất nhiên bạn không bao giờ nên sử dụng toán tử triệt tiêu lỗi (@) trước các câu lệnh của bạn.

+0

Cảm ơn! Đó là một đoạn mã tiện dụng mà tôi nên biết. Vấn đề là khi tôi đã thay đổi bảng nó tạo ra một lĩnh vực 'gửi' và điều này đã gây ra vấn đề về việc cập nhật. – lnelson92