Question

Understanding "expects parameter 1 to be resource" in PHP MySQL Queries

phpmysql

Question

I am trying to select data from a MySQL table in PHP, but I get an error like this:

mysql_fetch_array() expects parameter 1 to be resource, boolean given

My code looks like this:

$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'];
}

Why does this error happen, and how should I correctly query the database and fetch rows?

Short Answer

By the end of this page, you will understand why functions like mysql_fetch_array(), mysql_fetch_assoc(), and mysql_num_rows() fail when they receive false instead of a query result. You will learn how to detect query errors, fix SQL string issues, and use modern PHP database APIs such as mysqli or PDO with prepared statements.

Concept

The error means your fetch function expected a query result resource (or result object in newer APIs), but your query actually failed and returned false.

In old PHP mysql_* functions:

  • mysql_query() returns a resource when the SQL query succeeds.
  • It returns false when the SQL query fails.
  • Functions like mysql_fetch_array() only work on a successful query result.

So this error is usually not the real problem. The real problem happened earlier, when mysql_query() failed.

In your example, this line is the likely cause:

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

There are two important issues here:

  • The PHP variable is placed directly into SQL without proper quoting.
  • User input is being inserted into SQL unsafely, which creates an SQL injection risk.

For a string value, SQL usually needs quotes:

WHERE UserName = 'alice'

But your query becomes something like:

SELECT * FROM Users WHERE UserName LIKE alice

That is invalid unless alice is a column name, not a string value.

There is also a broader issue: the mysql_* extension is deprecated and removed in modern PHP. Real code should use:

  • mysqli
  • PDO

These APIs support prepared statements, which safely separate SQL code from user data.

Why this matters in real programming:

  • Prevents runtime errors when database queries fail
  • Makes debugging easier
  • Protects applications from SQL injection
  • Produces code that works on modern PHP versions

Mental Model

Think of mysql_query() like ordering a package.

  • If the order succeeds, you get a box back.
  • If the order fails, you get nothing useful, just a failure signal.
  • mysql_fetch_array() is like trying to open the box.

If there is no box because the order failed, trying to open it causes an error.

So the key idea is:

  1. Send the query
  2. Check whether it succeeded
  3. Only then fetch rows

Another way to think about it:

  • Query function = make the request
  • Fetch function = read the returned rows
  • Error message = you tried to read rows from a failed request
Take Quiz

Syntax and Examples

Old mysql_* style (for understanding the error)

This style is outdated, but it helps explain the problem:

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

if ($result === false) {
    die(mysql_error());
}

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

What this does:

  • Runs the query
  • Checks if it failed
  • Only fetches rows if the query succeeded

Why your original query breaks

Broken example:

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

Problems:

  • $username is not quoted as a string
  • LIKE is usually used with patterns such as %john%
  • Directly inserting $_POST data is unsafe

Better modern approach with mysqli

$username = $_POST['username'];

$mysqli = new mysqli("localhost", "my_user", "my_password", "my_database");

if ($mysqli->connect_error) {
    die("Connection failed: " . $mysqli->connect_error);
}

$stmt = $mysqli->prepare("SELECT FirstName FROM Users WHERE UserName = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();

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

Why this is better:

  • Uses modern PHP
  • Safely binds user input
  • Avoids SQL injection
  • Makes the string quoting automatic

If you really need pattern matching with LIKE

$username = $_POST['username'];
$pattern = "%" . $username . "%";

$stmt = $mysqli->prepare("SELECT FirstName FROM Users WHERE UserName LIKE ?");
$stmt->bind_param("s", $pattern);
$stmt->execute();
$result = $stmt->get_result();

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

Use LIKE when you want partial matches, not exact matches.

Step by Step Execution

Consider this modern example:

$username = "alice";

$stmt = $mysqli->prepare("SELECT FirstName FROM Users WHERE UserName = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();

Step by step:

  1. "alice" is stored in $username.

  2. PHP prepares this SQL:

    SELECT FirstName FROM Users WHERE UserName = ?
    
  3. bind_param("s", $username) tells MySQL:

    • there is one parameter
    • it is a string (s)
    • its value is alice
  4. MySQL safely combines the SQL and the value.

  5. execute() runs the query.

  6. get_result() gives you a result set.

  7. fetch_assoc() returns one row as an associative array, for example:

    ["FirstName" => "Alice"]
    
  8. You can then print:

    echo $row['FirstName'];
    

Now compare that with the old failing pattern:

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

If $username is alice, the final SQL becomes:

SELECT * FROM Users WHERE UserName LIKE alice

That is invalid SQL for a string comparison, so mysql_query() returns false. Then this line fails:

mysql_fetch_array($result)

because $result is false, not a valid query result.

Real World Use Cases

This concept appears anywhere PHP code reads from a database.

Login and account lookup

Applications often query users by:

  • username
  • email
  • ID

If the query fails and the code fetches rows anyway, you get the same resource/result error.

Search features

When building search forms with LIKE, developers often:

  • forget to add % wildcards
  • forget to quote strings
  • build SQL unsafely from user input

Admin dashboards

Dashboards fetch rows for:

  • user lists
  • orders
  • reports
  • inventory

A bad query can break the page unless the result is checked before fetching.

API endpoints

Backend APIs often query data and return JSON. A failed query should return a controlled error response instead of calling fetch methods on a failed result.

Data import scripts

Scripts that process CSV or external data may run many queries. Proper error checking helps you identify exactly which query failed.

Take Quiz

Real Codebase Usage

In real projects, developers rarely call a query and immediately fetch rows without checks.

Common patterns

Guard clause after query execution

$result = $mysqli->query($sql);
if ($result === false) {
    throw new Exception($mysqli->error);
}

This stops execution early if the query failed.

Prepared statements for all user input

$stmt = $mysqli->prepare("SELECT * FROM Users WHERE UserName = ?");
$stmt->bind_param("s", $username);

This is the standard safe pattern.

Validation before querying

if (empty($_POST['username'])) {
    die('Username is required');
}

Validation prevents pointless or broken queries.

Fetching rows by intent

  • fetch_assoc() when you want named columns
  • fetch_row() when numeric indexes are enough
  • one-row fetch for a single record
  • looped fetch for multiple rows

Error logging instead of showing raw database errors to users

In production code, developers often log database errors internally rather than printing them directly:

if ($result === false) {
    error_log($mysqli->error);
    die('Database query failed');
}

This avoids exposing sensitive details.

Common Mistakes

1. Not checking whether the query succeeded

Broken code:

$result = mysql_query($sql);
$row = mysql_fetch_array($result);

If $result is false, the fetch call fails.

Better:

$result = mysql_query($sql);
if ($result === false) {
    die(mysql_error());
}

2. Forgetting quotes around string values

Broken code:

$username = 'alice';
$sql = "SELECT * FROM Users WHERE UserName = $username";

This produces invalid SQL.

Correct idea:

$sql = "SELECT * FROM Users WHERE UserName = 'alice'";

But in practice, use prepared statements instead of manual quoting.

3. Using LIKE when = is enough

Broken idea:

WHERE UserName LIKE ?

Use = for exact username matches.

Use LIKE only when you need patterns such as:

WHERE UserName LIKE '%ali%'

4. Inserting raw $_POST values into SQL

Broken code:

$sql = "SELECT * FROM Users WHERE UserName = '$username'";

Even though it has quotes, this is still unsafe if $username came from user input.

Use prepared statements.

5. Using removed mysql_* functions in modern PHP

Functions like these are obsolete:

  • mysql_query()
  • mysql_fetch_array()
  • mysql_fetch_assoc()
  • mysql_num_rows()

Use mysqli or PDO instead.

6. Assuming a query that returns zero rows is the same as a failed query

These are different:

  • failed query → returns false
  • successful query with no matches → returns a valid result with zero rows

Example:

$result = $stmt->get_result();

if ($result->num_rows === 0) {
    echo "No users found.";
}

That is not an error. It just means nothing matched.

Comparisons

ConceptWhat it meansWhen to use
Query failureSQL is invalid, connection issue, table/column problemCheck errors immediately
Zero rows returnedQuery worked, but matched nothingHandle as a normal case
=Exact matchUsername, ID, email
LIKEPattern matchSearch boxes, partial text
mysql_*Old removed PHP APIOnly useful for understanding legacy code
mysqliModern procedural/OOP MySQL APIGood default for PHP + MySQL
PDODatabase abstraction APIGood when portability or named parameters are useful

= vs LIKE

OperatorExampleMeaning
=UserName = 'alice'Must match exactly
LIKEUserName LIKE 'ali%'Matches patterns

mysqli vs PDO

APIStrengthExample use
mysqliDirect MySQL-focused APIPHP app using only MySQL
PDOWorks with multiple database systemsApp that may use different DB engines

fetch_assoc() vs fetch_row()

MethodReturnsBest for
fetch_assoc()Associative arrayReadable code using column names
fetch_row()Numeric arraySimple positional access
fetch_array()Both associative and numeric indexesFlexible, but often unnecessary
Take Quiz

Cheat Sheet

Quick rules

  • A fetch function needs a successful query result.
  • If the query fails, the result is usually false.
  • Always check the query result before fetching.
  • Prefer mysqli or PDO, not mysql_*.
  • Use prepared statements for user input.
  • Use = for exact matches and LIKE for patterns.

Old error pattern

$result = mysql_query($sql);
if ($result === false) {
    die(mysql_error());
}

Safe mysqli pattern

$stmt = $mysqli->prepare("SELECT FirstName FROM Users WHERE UserName = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();

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

LIKE pattern example

$pattern = "%" . $search . "%";
$stmt = $mysqli->prepare("SELECT * FROM Users WHERE UserName LIKE ?");
$stmt->bind_param("s", $pattern);

Common checks

if ($result === false) {
    // query failed
}
if ($result->num_rows === 0) {
    // query succeeded, but no rows matched
}

Main cause of the original error

  • Invalid SQL
  • Unquoted string values
  • Unsafe interpolation of user input
  • Fetching from false

FAQ

Why does mysql_fetch_array() say it expected a resource?

Because mysql_query() failed and returned false instead of a valid query result.

What does “boolean given” mean in this error?

It means the fetch function received false, which is a boolean value, not a database result.

How do I find the actual SQL error in old PHP code?

Check the return value of mysql_query() and print mysql_error() if it is false.

Should I use LIKE for usernames?

Usually no. For exact username matching, use =. Use LIKE only for partial matches.

Why is direct use of $_POST in SQL dangerous?

It can allow SQL injection, where a user changes the meaning of your SQL query.

What should I use instead of mysql_* functions?

Use mysqli or PDO with prepared statements.

Is zero rows the same as a query error?

No. Zero rows means the query worked but found no matching data. A query error means the SQL failed to execute.

Can I still fix the old code without rewriting everything?

You can debug it by checking query errors, but long term you should migrate to mysqli or PDO.

Take Quiz

Mini Project

Description

Build a simple user lookup form in PHP that searches for a user by username and displays the matching first name. This project demonstrates safe database querying, result checking, and row fetching using mysqli prepared statements.

Goal

Create a PHP script that accepts a username, queries the Users table safely, and prints the user's first name or a helpful message if no match is found.

Requirements

  • Accept a username from a form submission using POST.
  • Validate that the username is not empty.
  • Query the Users table using a prepared statement.
  • Display the matching FirstName values.
  • Show a message when no users are found.
  • Handle database errors safely.
Take Quiz

Keep learning

Related questions

View more