mysql_fetch_array () / mysql_fetch_assoc () / mysql_fetch_row () / mysql_num_rows, v.v ..., dự kiến ​​tham số 1 sẽ là tài nguyên


960

Tôi đang cố gắng chọn dữ liệu từ bảng MySQL, nhưng tôi nhận được một trong các thông báo lỗi sau:

mysql_fetch_array () dự kiến ​​tham số 1 sẽ là tài nguyên, được đưa ra boolean

Đây là mã của tôi:

$username = $_POST['username'];
$password = $_POST['password'];

$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');

while($row = mysql_fetch_array($result)) {
    echo $row['FirstName'];
}

15
bạn có thể nhận được nhiều thông điệp eroor hữu ích hơn bằng cách sử dụng :: QUERY hoặc die (mysql_error ());
nik

123
Ngoài ra, lưu ý bắt buộc: Mã của bạn dễ bị SQL SQL tiêm . Bạn nên xác nhận và / hoặc thoát khỏi đầu vào của người dùng. Có một cái nhìn vào mysql_real_escape_string. Không bao giờ tin tưởng dữ liệu người dùng.
Felix Kling

7
Trên thực tế, mã của OP sẽ gây ra lỗi cú pháp trên máy chủ MySQL, nhưng ít nhất nó không dễ bị SQL Injection vì các trích dẫn đơn không có nội suy thay đổi.
szgal

4
@FelixKling Tôi nhận ra rằng điều này rất cũ và có thể là chính xác nhất có thể tại thời điểm đó, nhưng nhận xét của bạn bây giờ sai một cách nguy hiểm theo một cách: mysql_real_escape_stringkhông phải là bảo vệ tất cả và cuối cùng của SQL; nó vẫn dễ bị tấn công. (Không, bạn chưa bao giờ nói nó hoàn hảo, nhưng bạn ngụ ý đó là giải pháp bắt buộc duy nhất) Giải pháp tốt nhất hiện nay là PDO, theo như tôi biết.
Vụ kiện của Quỹ Monica

2
Gah Mở rộng câu hỏi này để bao gồm MySQLi và PDO là một ý tưởng tồi. Mỗi cái đều có cú pháp và thông báo lỗi hơi khác nhau và chúng hoàn toàn có thể có câu hỏi riêng. Kết hợp tất cả mọi thứ vào một câu hỏi ba phần khổng lồ chỉ làm cho điều này trở nên ít Googlizable và buộc những người đến đây phải lội qua nội dung không liên quan để đạt được những gì họ muốn. Nó cũng vô hiệu hóa rất nhiều câu trả lời dưới đây và làm cho câu hỏi này "Quá rộng" theo các tiêu chuẩn mà chúng ta thường áp dụng. Theo tôi, đó là một mớ hỗn độn, nhưng bây giờ đã quá muộn để khắc phục.
Mark Amery

Câu trả lời:


667

Một truy vấn có thể thất bại vì nhiều lý do trong trường hợp cả phần mở rộng mysql_ * và phần mở rộng mysqli sẽ trả về falsetừ các hàm / phương thức truy vấn tương ứng của chúng. Bạn cần kiểm tra tình trạng lỗi đó và xử lý nó cho phù hợp.

phần mở rộng mysql_ * :

LƯU Ý Các hàm mysql_ không được dùng nữa và đã bị xóa trong phiên bản php 7.

Kiểm tra $resulttrước khi chuyển nó đến mysql_fetch_array. Bạn sẽ thấy rằng đó là falsevì truy vấn thất bại. Xem mysql_querytài liệu về các giá trị trả về có thể và đề xuất về cách xử lý chúng.

$username = mysql_real_escape_string($_POST['username']);
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '$username'");

if($result === FALSE) { 
    die(mysql_error()); // TODO: better error handling
}

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}


phong cách thủ tục mở rộng mysqli :

$username = mysqli_real_escape_string($mysqli, $_POST['username']);
$result = mysqli_query($mysqli, "SELECT * FROM Users WHERE UserName LIKE '$username'");

// mysqli_query returns false if something went wrong with the query
if($result === FALSE) { 
    yourErrorHandler(mysqli_error($mysqli));
}
else {
    // as of php 5.4 mysqli_result implements Traversable, so you can use it with foreach
    foreach( $result as $row ) {
        ...

phong cách oo :

$username = $mysqli->escape_string($_POST['username']);
$result = $mysqli->query("SELECT * FROM Users WHERE UserName LIKE '$username'");

if($result === FALSE) { 
    yourErrorHandler($mysqli->error); // or $mysqli->error_list
}
else {
    // as of php 5.4 mysqli_result implements Traversable, so you can use it with foreach
    foreach( $result as $row ) {
      ...

sử dụng một tuyên bố chuẩn bị:

$stmt = $mysqli->prepare('SELECT * FROM Users WHERE UserName LIKE ?');
if ( !$stmt ) {
    yourErrorHandler($mysqli->error); // or $mysqli->error_list
}
else if ( !$stmt->bind_param('s', $_POST['username']) ) {
    yourErrorHandler($stmt->error); // or $stmt->error_list
}
else if ( !$stmt->execute() ) {
    yourErrorHandler($stmt->error); // or $stmt->error_list
}
else {
    $result = $stmt->get_result();
    // as of php 5.4 mysqli_result implements Traversable, so you can use it with foreach
    foreach( $result as $row ) {
      ...

Những ví dụ này chỉ minh họa những gì nên làm (xử lý lỗi), chứ không phải làm thế nào để làm điều đó. Mã sản xuất không nên sử dụng or diekhi xuất HTML, nếu không, ít nhất nó sẽ tạo ra HTML không hợp lệ. Ngoài ra, thông báo lỗi cơ sở dữ liệu không nên được hiển thị cho người dùng không phải quản trị viên, vì nó tiết lộ quá nhiều thông tin .


9
Đúng, nhưng sử dụng die () nếu truy vấn thất bại là một ít đến nhiều.
2ndkauboy

28
Tôi sẽ thiết kế toàn bộ cơ chế xử lý lỗi cho OP, nhưng quyết định rằng nó có thể vượt quá phạm vi câu trả lời của tôi.
Edward Dale

@ scompt.com Có, nó cũng được đề cập trong một số câu trả lời khác. Tôi đoán rằng tôi chỉ đưa ra quan điểm rằng đây là câu trả lời được chấp nhận cho câu hỏi có khả năng hiển thị cao, ngoài lời khuyên (xuất sắc) về cách bắt lỗi đúng trong tương lai, nên (IMHO) thực sự trả lời câu hỏi cụ thể (nghĩa là giải thích tại sao có lỗi trong trường hợp này).
Sepster

2
Thay vì if($result === FALSE)bạn có thể sử dụng if(! $result). Sửa lỗi cho tôi nếu tôi sai
anestv

1
mysql_query (): Phần mở rộng mysql không được dùng nữa và sẽ bị xóa trong tương lai: sử dụng mysqli
Greg

165

Thông báo lỗi này được hiển thị khi bạn gặp lỗi trong truy vấn của mình khiến nó bị lỗi. Nó sẽ tự biểu hiện khi sử dụng:

  • mysql_fetch_array/mysqli_fetch_array()
  • mysql_fetch_assoc()/mysqli_fetch_assoc()
  • mysql_num_rows()/mysqli_num_rows()

Lưu ý : Lỗi này không xuất hiện nếu không có hàng nào bị ảnh hưởng bởi truy vấn của bạn. Chỉ một truy vấn có cú pháp không hợp lệ sẽ tạo ra lỗi này.

Các bước khắc phục sự cố

  • Hãy chắc chắn rằng máy chủ phát triển của bạn được cấu hình để hiển thị tất cả các lỗi. Bạn có thể làm điều này bằng cách đặt phần này ở đầu tệp hoặc trong tệp cấu hình của bạn : error_reporting(-1);. Nếu bạn có bất kỳ lỗi cú pháp nào, điều này sẽ chỉ ra cho bạn.

  • Sử dụng mysql_error(). mysql_error()sẽ báo cáo bất kỳ lỗi nào MySQL gặp phải trong khi thực hiện truy vấn của bạn.

    Sử dụng mẫu:

    mysql_connect($host, $username, $password) or die("cannot connect"); 
    mysql_select_db($db_name) or die("cannot select DB");
    
    $sql = "SELECT * FROM table_name";
    $result = mysql_query($sql);
    
    if (false === $result) {
        echo mysql_error();
    }
  • Chạy truy vấn của bạn từ dòng lệnh MySQL hoặc một công cụ như phpMyAdmin . Nếu bạn có một lỗi cú pháp trong truy vấn của bạn, điều này sẽ cho bạn biết đó là gì.

  • Hãy chắc chắn rằng trích dẫn của bạn là chính xác. Một trích dẫn bị thiếu xung quanh truy vấn hoặc một giá trị có thể khiến truy vấn không thành công.

  • Hãy chắc chắn rằng bạn đang thoát khỏi giá trị của bạn. Các trích dẫn trong truy vấn của bạn có thể khiến một truy vấn không thành công (và cũng khiến bạn mở để tiêm SQL). Sử dụng mysql_real_escape_string()để thoát đầu vào của bạn.

  • Hãy chắc chắn rằng bạn không trộn lẫn mysqli_*mysql_*chức năng. Chúng không giống nhau và không thể được sử dụng cùng nhau. (Nếu bạn định chọn một hoặc một thanh khác mysqli_*. Xem bên dưới để biết lý do.)

Lời khuyên khác

mysql_*chức năng không nên được sử dụng cho mã mới. Chúng không còn được duy trì và cộng đồng đã bắt đầu quá trình khấu hao . Thay vào đó, bạn nên tìm hiểu về các câu lệnh được chuẩn bị và sử dụng PDO hoặc MySQLi . Nếu bạn không thể quyết định, bài viết này sẽ giúp lựa chọn. Nếu bạn quan tâm để tìm hiểu, đây là hướng dẫn PDO tốt .


1
Đưa ra câu hỏi này ngày hôm nay stackoverflow.com/q/43804651/1415724 và những câu hỏi tương tự khác gần đây; Tôi nghĩ rằng có thể đáng để cập nhật câu trả lời của bạn để chứa nội dung như "Lỗi đó cũng có thể do không thực hiện truy vấn với mysql_query()/ mysqli_query($connection)v.v." ; suy nghĩ? Vì không có câu trả lời nào khác trong phần hỏi đáp này đề cập đến điều này.
Funk Bốn mươi Niner

111

Lỗi xảy ra ở đây là do sử dụng dấu ngoặc đơn ( '). Bạn có thể đặt truy vấn của bạn như thế này:

mysql_query("
SELECT * FROM Users 
WHERE UserName 
LIKE '".mysql_real_escape_string ($username)."'
");

Đó là sử dụng mysql_real_escape_stringđể ngăn ngừa tiêm SQL. Mặc dù chúng ta nên sử dụng phần mở rộng MySQLi hoặc PDO_MYQuery cho phiên bản nâng cấp của PHP (PHP 5.5.0 trở lên), nhưng đối với các phiên bản cũ hơn mysql_real_escape_stringsẽ thực hiện thủ thuật này.


5
Tại sao thêm nhiễu với nối chuỗi thay vì chỉ đặt biến trong chuỗi truy vấn?
Matteo Riva

1
@Matteo Riva Vâng, nhưng tôi nghĩ rằng đây là cách nhỏ hơn để tách các biến khỏi chuỗi. :)
nik

60

Như scompt.com đã giải thích , truy vấn có thể thất bại. Sử dụng mã này nhận được lỗi của truy vấn hoặc kết quả chính xác:

$username = $_POST['username'];
$password = $_POST['password'];

$result = mysql_query("
SELECT * FROM Users 
WHERE UserName LIKE '".mysql_real_escape_string($username)."'
");

if($result)
{
    while($row = mysql_fetch_array($result))
    {
        echo $row['FirstName'];
    }
} else {
    echo 'Invalid query: ' . mysql_error() . "\n";
    echo 'Whole query: ' . $query; 
}

Xem tài liệumysql_query() để biết thêm thông tin.

Lỗi thực tế là các dấu ngoặc đơn để biến $usernamekhông được phân tích cú pháp. Nhưng bạn thực sự nên sử dụng mysql_real_escape_string($username)để tránh tiêm SQL.


52

Đặt dấu ngoặc kép xung quanh $username. Các giá trị chuỗi, trái ngược với các giá trị số, phải được đặt trong dấu ngoặc kép.

$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '$username'");

Ngoài ra, không có điểm nào trong việc sử dụng LIKEđiều kiện nếu bạn không sử dụng ký tự đại diện: nếu bạn cần sử dụng kết hợp chính xác =thay vì LIKE.


1
Và nếu tên người dùng $ là: "'; DROP BẢNG;" ? Đó là lợi thế của việc sử dụng các câu lệnh được chuẩn bị và các giá trị ràng buộc, mà tôi nghĩ rằng người hỏi muốn giữ lại.
Hold OfferHunger 20/03/2016

42

Vui lòng kiểm tra một khi cơ sở dữ liệu được chọn không phải vì một số lần cơ sở dữ liệu không được chọn

Kiểm tra

mysql_select_db('database name ')or DIE('Database name is not available!');

trước khi truy vấn MySQL và sau đó chuyển sang bước tiếp theo

$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');

f($result === FALSE) {
    die(mysql_error());

40

Mã của bạn phải giống như thế này

$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM Users WHERE UserName LIKE '$username'";
echo $query;
$result = mysql_query($query);

if($result === FALSE) {
    die(mysql_error("error message for the user")); 
}

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

Sau khi thực hiện xong, bạn sẽ nhận được truy vấn được in trên màn hình. Hãy thử truy vấn này trên máy chủ của bạn và xem liệu nó có tạo ra kết quả mong muốn không. Hầu hết các lần lỗi là trong truy vấn. Phần còn lại của mã là chính xác.


3
Không sử dụng mã này. Nó là mở rộng cho các cuộc tấn công tiêm SQL.
Brad

34
$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');

Bạn xác định chuỗi bằng các trích dẫn đơn và PHP không phân tích các chuỗi phân tách trích dẫn đơn. Để có được phép nội suy biến, bạn sẽ cần sử dụng dấu ngoặc kép HOẶC nối chuỗi (hoặc kết hợp ở đó). Xem http://php.net/manual/en/lingu.types.opes.php để biết thêm thông tin.

Ngoài ra, bạn nên kiểm tra xem mysql_query đã trả về tài nguyên kết quả hợp lệ, nếu không thì fetch_ *, num_rows, v.v. sẽ không hoạt động trên kết quả vì đó không phải là kết quả! I E:

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');

if( $result === FALSE ) {
   trigger_error('Query failed returning error: '. mysql_error(),E_USER_ERROR);
} else {
   while( $row = mysql_fetch_array($result) ) {
      echo $row['username'];
   }
}

http://us.php.net/manual/en/feft.mysql-query.php để biết thêm thông tin.


2
Không sử dụng mã này, ngay cả khi bạn thêm dấu ngoặc kép. Nó là mở rộng cho các cuộc tấn công tiêm SQL.
Brad

33

Truy vấn này sẽ hoạt động:

$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '%$username%'");
while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

Vấn đề là các trích dẫn đơn, do đó truy vấn của bạn không thành công và trả về FALSE và vòng lặp WHILE của bạn không thể thực thi. Sử dụng% cho phép bạn khớp bất kỳ kết quả nào có chứa chuỗi của bạn (chẳng hạn như Một số tên người dùng- $ Tên người dùng-Một số).

Đây chỉ đơn giản là một câu trả lời cho câu hỏi của bạn, bạn nên triển khai các nội dung được đề cập trong các bài đăng khác: xử lý lỗi, sử dụng chuỗi thoát (người dùng có thể nhập bất cứ điều gì vào trường và bạn PHẢI đảm bảo rằng đó không phải là mã tùy ý), sử dụng PDO thay vì mysql_connect mà bây giờ là depricated.


28
$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '%$username%'") or die(mysql_error());

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

Đôi khi, ngăn chặn truy vấn như @mysql_query(your query);


2
Không sử dụng mã này. Nó là mở rộng cho các cuộc tấn công tiêm SQL.
Brad

27

Nếu bạn đã thử mọi thứ ở đây và nó không hoạt động, bạn có thể muốn kiểm tra đối chiếu cơ sở dữ liệu MySQL của mình. Của tôi đã được thiết lập để đối chiếu Thụy Điển. Sau đó, tôi thay đổi nó utf8_general_civà mọi thứ chỉ cần nhấp vào thiết bị.


25
$query = "SELECT Name,Mobile,Website,Rating FROM grand_table order by 4";

while( $data = mysql_fetch_array($query))
{
    echo("<tr><td>$data[0]</td><td>$data[1]</td><td>$data[2]</td><td>$data[3]</td></tr>");      
}

Thay vì sử dụng truy vấn WHERE, bạn có thể sử dụng truy vấn ORDER BY này. Nó tốt hơn nhiều so với điều này để sử dụng một truy vấn.

Tôi đã thực hiện truy vấn này và không nhận được lỗi như tham số hoặc boolean.


Hãy nhớ sử dụng htmlspecialchars()khi sử dụng dữ liệu tùy ý trong ngữ cảnh của HTML. Mặt khác, bạn có nguy cơ tạo HTML hợp lệ khi các ký tự dành riêng được sử dụng trong dữ liệu.
Brad

25

Hãy thử điều này, nó phải hoạt động, nếu không bạn cần in lỗi để chỉ định vấn đề của bạn

$username = $_POST['username'];
$password = $_POST['password'];

$sql = "SELECT * from Users WHERE UserName LIKE '$username'";
$result = mysql_query($sql,$con);

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

8
1) Mở rộng cho SQL tiêm, 2) không bao gồm xử lý lỗi gây ra lỗi trong trường hợp của OP.
lừa dối

+1. @deceze Có nó rộng mở. Nhưng không còn vì vậy mà mã của OP hoặc người trả lời được chấp nhận ;-) Và không phải là thiếu xử lý lỗi trong mã của OP gây ra lỗi ... đó là lỗi và câu trả lời này ít nhất là cố gắng giải quyết điều đó (bằng cách đặt một trích dẫn xung quanh chuỗi ký tự trong LIKEbiểu thức).
Sepster

1
+1 Vui lòng thêm khoảng trắng giữa THÍCH và '$ tên người dùng', phần còn lại có vẻ ổn trừ khi tiêm SQL. Tại sao không sử dụng = thay vì tên người dùng của nhà điều hành THÍCH phải được khớp chính xác
asim-ishaq

21

Có thể có hai lý do:

  1. Bạn đã mở kết nối tới cơ sở dữ liệu trước khi gọi hàm mysql_query chưa? Tôi không thấy điều đó trong mã của bạn. Sử dụng mysql_connect trước khi thực hiện truy vấn. Xemphp.net/manual/en/function.mysql-connect.php

  2. Biến $ username được sử dụng bên trong một chuỗi trích dẫn, vì vậy giá trị của nó sẽ không được đánh giá bên trong truy vấn. Truy vấn chắc chắn sẽ thất bại.

Thứ ba, cấu trúc của truy vấn có xu hướng tiêm SQL . Bạn có thể sử dụng các tuyên bố đã chuẩn bị để tránh mối đe dọa bảo mật này.


20

Hãy thử đoạn mã sau. Nó có thể hoạt động tốt.

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName ='$username'");

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

4
Mã này là đối tượng tiêm SQL và không nên được sử dụng.
Brad

15

Đi đến của bạn config.php. Tôi đã từng gặp vấn đề tương tự. Xác minh tên người dùng và mật khẩu, và cũng chọn sql cùng tên với cấu hình.


15

Không sử dụng hàm mysql_ * bị lỗi (depricated trong php 5.5 sẽ bị xóa trong php 7). và bạn có thể làm điều này với mysqli hoặc pdo

đây là câu hỏi chọn hoàn chỉnh

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 

$sql = "SELECT id, firstname, lastname FROM MyGuests";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {
        // code here 
    }
} else {
    echo "0 results";
}
$conn->close();
?>

Bài đăng của bạn không giải quyết các vấn đề được giải quyết bằng câu hỏi, đó là một truy vấn không hợp lệ và báo cáo lỗi không thường xuyên. Bài này lạc đề.
Paul Spiegel

14
<?php
    $username = $_POST['username'];
    $password = $_POST['password'];
    $result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '".$username."'");

    while($row = mysql_fetch_array($result))
    {
        echo $row['FirstName'];
    }
?>

Và nếu có một người dùng có một tên người dùng duy nhất, bạn có thể sử dụng "=" cho điều đó. Không cần phải thích.

Truy vấn của bạn sẽ là:

mysql_query("SELECT * FROM Users WHERE UserName ='".$username."'");

3
Mã này được mở rộng để tiêm SQL và không nên được sử dụng.
Brad

@AnujGarg Mã này nhận đầu vào trực tiếp và nối nó vào truy vấn. Ai đó có thể viết SQL của riêng họ vào dữ liệu bài đăng usernamevà nó sẽ được thực thi.
Brad

Vì vậy, những gì để sử dụng để ngăn chặn mã từ SQL tiêm?
Anuj Garg

14

Bao gồm một biến chuỗi kết nối trước truy vấn MySQL. Ví dụ,$connt trong mã này:

$results = mysql_query($connt, "SELECT * FROM users");

1
Điều này không giải quyết các vấn đề trong câu hỏi. Nó cũng sai và sẽ đưa ra một lỗi khác.
Paul Spiegel

12

Bất cứ khi nào bạn nhận được ...

"Cảnh báo: mysqli_fetch_object () hy vọng tham số 1 sẽ là mysqli_result, được đưa ra boolean"

... có thể là do có vấn đề với truy vấn của bạn. Các prepare()hoặc query()trả lại sức mạnh FALSE(một Boolean), nhưng thông báo lỗi chung chung này không để lại cho bạn nhiều trong cách manh mối. Làm thế nào để bạn tìm ra những gì là sai với truy vấn của bạn? Bạn hỏi !

Trước hết, hãy đảm bảo báo cáo lỗi được bật và hiển thị: thêm hai dòng này vào đầu (các) tệp của bạn ngay sau <?phpthẻ mở của bạn :

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

Nếu báo cáo lỗi của bạn đã được đặt trong php.ini, bạn sẽ không phải lo lắng về điều này. Chỉ cần đảm bảo rằng bạn xử lý lỗi một cách duyên dáng và không bao giờ tiết lộ nguyên nhân thực sự của bất kỳ vấn đề nào cho người dùng của bạn. Tiết lộ nguyên nhân thực sự cho công chúng có thể là một lời mời khắc vàng cho những người muốn làm hại trang web và máy chủ của bạn. Nếu bạn không muốn gửi lỗi đến trình duyệt, bạn luôn có thể theo dõi nhật ký lỗi máy chủ web của mình. Vị trí nhật ký sẽ thay đổi từ máy chủ này sang máy chủ khác, ví dụ, trên Ubuntu, nhật ký lỗi thường được đặt tại /var/log/apache2/error.log. Nếu bạn đang kiểm tra nhật ký lỗi trong môi trường Linux, bạn có thể sử dụngtail -f /path/to/log trong cửa sổ bảng điều khiển để xem lỗi khi chúng xảy ra trong thời gian thực .... hoặc khi bạn tạo chúng.

Khi bạn bình phương về báo cáo lỗi tiêu chuẩn, việc thêm kiểm tra lỗi trên kết nối cơ sở dữ liệu của bạn và các truy vấn sẽ cung cấp cho bạn nhiều chi tiết hơn về các sự cố đang xảy ra. Hãy xem ví dụ này trong đó tên cột không chính xác. Đầu tiên, mã trả về thông báo lỗi nghiêm trọng chung:

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
$query = $mysqli->prepare($sql)); // assuming $mysqli is the connection
$query->bind_param('s', $definition);
$query->execute();

Lỗi là chung chung và không hữu ích cho bạn trong việc giải quyết những gì đang xảy ra.

Với một vài dòng mã hơn, bạn có thể nhận được thông tin rất chi tiết mà bạn có thể sử dụng để giải quyết vấn đề ngay lập tức . Kiểm tra prepare()tuyên bố về tính trung thực và nếu nó tốt, bạn có thể tiến hành ràng buộc và thực thi.

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
if($query = $mysqli->prepare($sql)) { // assuming $mysqli is the connection
    $query->bind_param('s', $definition);
    $query->execute();
    // any additional code you need would go here.
} else {
    $error = $mysqli->errno . ' ' . $mysqli->error; // 1054 Unknown column 'foo' in 'field list'
    // handle error
}

Nếu có gì đó không ổn, bạn có thể đưa ra một thông báo lỗi sẽ đưa bạn trực tiếp đến vấn đề. Trong trường hợp này, không có foocột trong bảng, giải quyết vấn đề là tầm thường.

Nếu bạn chọn, bạn có thể bao gồm kiểm tra này trong một chức năng hoặc lớp và mở rộng nó bằng cách xử lý các lỗi một cách duyên dáng như đã đề cập trước đó.


2
Làm thế nào bạn có thể viết "Chỉ cần đảm bảo rằng bạn xử lý lỗi một cách duyên dáng và không bao giờ tiết lộ nguyên nhân thực sự của bất kỳ vấn đề nào cho người dùng của bạn." và echo $error;trong một bài?
Paul Spiegel

Cảm ơn những người đứng đầu @PaulSpiegel. Đã được một thời gian kể từ khi tôi viết hoặc xem lại câu trả lời và đã bỏ lỡ rằng tôi đã để lại tiếng vang trong đó.
Jay Blanchard

11
<?php
      $username = $_POST['username'];
       $password = $_POST['password'];

     $result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '".mysql_real_escape_string($username)."'")or die(mysql_error());
while($row=mysql_fetch_array($result))
  {
 echo $row['FirstName'];
 }
 ?>

11

Thử cái này

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysqli_query('SELECT * FROM Users WHERE UserName LIKE $username');

if($result){
while($row = mysqli_fetch_array($result))
{
    echo $row['FirstName'];
}
}

4
@panjehra mysql_ * hiện bị lỗi và sẽ bị xóa khỏi php 7. Sử dụng mysqli_ * thay vào đó
Manoj Kumar

9

Đầu tiên, hãy kiểm tra kết nối của bạn với cơ sở dữ liệu. Có kết nối thành công hay không?

Nếu xong, sau đó tôi đã viết mã này và nó hoạt động tốt:

if (isset($_GET['q1mrks']) && isset($_GET['marks']) && isset($_GET['qt1'])) {
    $Q1mrks = $_GET['q1mrks'];
    $marks = $_GET['marks'];
    $qt1 = $_GET['qt1'];

    $qtype_qry = mysql_query("
        SELECT *
        FROM s_questiontypes
        WHERE quetype_id = '$qt1'
    ");
    $row = mysql_fetch_assoc($qtype_qry);
    $qcode = $row['quetype_code'];

    $sq_qry = "
        SELECT *
        FROM s_question
        WHERE quetype_code = '$qcode'
        ORDER BY RAND() LIMIT $Q1mrks
    ";
    $sq_qry = mysql_query("
        SELECT *
        FROM s_question
        WHERE quetype_code = '$qcode'
        LIMIT $Q1mrks
    ");
    while ($qrow = mysql_fetch_array($sq_qry)) {
        $qm = $qrow['marks'] . "<br />";
        $total += $qm . "<br />";
    }
    echo $total . "/" . $marks;
}

2
Không sử dụng mã này. Nó là mở rộng cho các cuộc tấn công tiêm SQL.
Brad

9

Hãy chắc chắn rằng bạn không đóng cơ sở dữ liệu bằng cách sử dụng db_close () trước khi chạy truy vấn của bạn:

Nếu bạn đang sử dụng nhiều truy vấn trong tập lệnh ngay cả khi bạn bao gồm các trang khác có chứa truy vấn hoặc kết nối cơ sở dữ liệu, thì có thể tại bất kỳ nơi nào bạn sử dụng db_close () sẽ đóng kết nối cơ sở dữ liệu của bạn, vì vậy hãy chắc chắn rằng bạn không làm điều này sai trong kịch bản của bạn.


8

Nếu bạn không có bất kỳ Lỗi MySQL nào xuất hiện trong khi kiểm tra, hãy đảm bảo rằng bạn đã tạo đúng bảng cơ sở dữ liệu của mình. Điều này đã xảy ra với tôi. Tìm kiếm bất kỳ dấu phẩy hoặc dấu ngoặc kép không mong muốn.


7

Kiểm tra kết nối của bạn đầu tiên.

Sau đó, nếu bạn muốn tìm nạp giá trị chính xác từ cơ sở dữ liệu thì bạn nên viết:

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName =`$usernam`");

Hoặc bạn muốn tìm nạp LIKEloại giá trị thì bạn nên viết:

$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '%$username%'");

3
Mã này được mở rộng để tiêm SQL và không nên được sử dụng.
Brad

6

Bạn cũng có thể kiểm tra wether $resultcó bị lỗi như vậy không, trước khi thực hiện mảng tìm nạp

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');
if(!$result)
{
     echo "error executing query: "+mysql_error(); 
}else{
       while($row = mysql_fetch_array($result))
       {
         echo $row['FirstName'];
       }
}

3
Không sử dụng mã này. Nó là mở rộng cho các cuộc tấn công tiêm SQL.
Brad

Nhưng nếu mã hoạt động, tôi cảm thấy bạn nên chỉnh sửa mã và nhập các bộ lọc cần thiết thay vì chuyển mã.
dùng28864

Việc sử dụng đơn giản các bộ lọc sẽ không khắc phục những gì sai với mã này. Giải pháp tốt nhất là sử dụng các truy vấn được chuẩn bị / tham số hóa với PDO hoặc tương tự. Tôi không thấy bất kỳ điểm nào trong việc sửa nó, vì câu trả lời đúng đã được đăng ở đây. Lý tưởng nhất, câu trả lời này sẽ bị xóa. Tuy nhiên, bạn được hoan nghênh sửa câu trả lời của bạn và tôi sẽ vui vẻ bình chọn nếu nó đúng.
Brad

Chà, nếu bạn cảm thấy câu trả lời không đáng để xem xét, bạn có thể tiếp tục và đọc nó. Tuy nhiên, tôi nghĩ rằng toàn bộ quan điểm của cộng đồng này là chia sẻ và đóng góp kiến ​​thức. Nếu bạn có một cái gì đó để chia sẻ thay vì hiển thị và đưa mọi người đi.
dùng28864

2
Bạn đã đúng, toàn bộ quan điểm của cộng đồng này là chia sẻ kiến ​​thức. Đó là lý do tại sao thêm lời giải thích với downvote của tôi và giải thích thêm tại sao đề xuất bộ lọc của bạn không đủ. Tôi rất muốn thông báo cho bạn, cùng với bất kỳ ai khác tìm thấy câu trả lời của bạn, rằng đoạn mã trên không an toàn. Tốt hơn hết là mọi người nên học các phương pháp chính xác thay vì duy trì mã xấu. Và, tôi không thể xóa câu trả lời của bạn, tôi cũng vậy, nếu bạn chọn làm như vậy.
Brad

4

Thông thường xảy ra lỗi khi kết nối cơ sở dữ liệu của bạn không thành công, do đó hãy chắc chắn kết nối cơ sở dữ liệu của bạn hoặc bao gồm tệp cơ sở dữ liệu.

include_once(db_connetc.php');

HOẶC LÀ

// Create a connection
$connection = mysql_connect("localhost", "root", "") or die(mysql_error());

//Select database
mysql_select_db("db_name", $connection) or die(mysql_error());

$employee_query = "SELECT * FROM employee WHERE `id` ='".$_POST['id']."'";

$employee_data = mysql_query($employee_query);

if (mysql_num_rows($employee_data) > 0) {

    while ($row = mysql_fetch_array($employee_data)){
        echo $row['emp_name'];
    } // end of while loop
} // end of if
  • Thực hành tốt nhất là chạy truy vấn trong sqlyog và sau đó sao chép nó vào mã trang của bạn.
  • Luôn lưu trữ truy vấn của bạn trong một biến và sau đó lặp lại biến đó. Sau đó vượt qua mysql_query($query_variable);.

2
1) Bạn không biết nếu tôi có hoặc chưa bỏ phiếu cho bất kỳ câu trả lời nào ở đây, lên hay xuống. 2) Như tôi đã giải thích trong bình luận đầu tiên của tôi; câu trả lời của bạn không đề cập đến vấn đề ( boolean được chuyển cho mysql_fetch_array ) và bạn có lỗi cú pháp
Phil

2
Bạn có dấu ngoặc kép không chính xác trong cả hai ví dụ mã của bạn. Cú pháp tô sáng được áp dụng cho khối mã thứ hai của bạn là một sự cho đi đã chết mà có gì đó không ổn
Phil

4
Mã này là đối tượng tiêm SQL và không nên được sử dụng. @EngrZardari nếu bạn đang sử dụng mã này trên các hệ thống sản xuất của mình, chắc chắn bạn đã bị hack và nên khắc phục tình trạng mua bằng cách sử dụng các truy vấn được chuẩn bị / tham số hóa với PDO hoặc tương tự. Có những bot đã tự động kiểm tra các lỗ hổng như vậy.
Brad

1
@EngrZardari Về bạn "không có lỗi gì cả, tôi đã dán mã ở đây mà tôi hiện đang sử dụng." bình luận ở trên. Có một trích dẫn bị thiếu trong truy vấn mà tôi đã sửa. Điều đó sẽ ném một lỗi phân tích (PHP).
Funk Bốn mươi Niner

2

Hãy thử mã này nó hoạt động tốt

gán biến bài cho biến

   $username = $_POST['uname'];

   $password = $_POST['pass'];

  $result = mysql_query('SELECT * FROM userData WHERE UserName LIKE $username');

if(!empty($result)){

    while($row = mysql_fetch_array($result)){
        echo $row['FirstName'];
     }
}

3
Mã này là đối tượng của các cuộc tấn công tiêm SQL và không nên được sử dụng.
Brad

1

vì tên người dùng $ là một biến php, chúng ta cần chuyển nó thành chuỗi cho mysqli, vì vậy trong truy vấn bạn bắt đầu bằng một trích dẫn duy nhất, chúng tôi sẽ sử dụng trích dẫn kép, trích dẫn đơn và dấu chấm hết cho mục đích nối ("'. $ tên người dùng. '") nếu bạn bắt đầu với một trích dẫn kép, thì bạn sẽ đảo ngược các trích dẫn ('". $ tên người dùng. "').

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE "'.$username.'"');

while($row = mysql_fetch_array($result))
     {
      echo $row['FirstName'];
     }

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '".$username."' ");

while($row = mysql_fetch_array($result))
     {
      echo $row['FirstName'];
     }

nhưng việc sử dụng Mysql đã mất giá nhiều, thay vào đó hãy sử dụng PDO. Nó đơn giản nhưng rất an toàn


Nhưng sử dụng Mysql đã mất giá. bạn có thể sử dụng PDO thay thế. Hãy để tôi cung cấp cho bạn một đăng nhập mẫu.
Dennis Kiptugen 4/10/2015

2
Mật khẩu KHÔNG BAO GIỜ được lưu trữ ở dạng văn bản đơn giản, hãy sử dụng các ứng dụng được tích hợp sẵn mà PHP có để xử lý việc băm mật khẩu và xác minh mật khẩu băm!
SpacePhoenix
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.