Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

fetch(PDO::FETCH_ASSOC) fails when it is called on a mysqli_result. PDO and mysqli are different database APIs: choose one and use its connection, result methods, constants and error handling consistently. If your result is from mysqli, call fetch_assoc(); if you want PDO fetch modes such as PDO::FETCH_ASSOC or PDO::FETCH_UNIQUE, create and query the database through PDO.

Identify the API mismatch

The characteristic error is similar to Call to undefined method mysqli_result::fetch(). That message means the query returned a mysqli result object, but the code attempted to use PDO’s fetch() method and constants on it. As a rule, do not combine the two APIs.

Connection and result Fetch code Fetch-mode constants
PDO $stmt->fetch(), $stmt->fetchAll() PDO::FETCH_ASSOC, PDO::FETCH_UNIQUE
mysqli $result->fetch_assoc() Use mysqli’s result methods; PDO constants do not apply

If the project uses mysqli

$result = $mysqli->query('SELECT id, pageheader, pagecontent FROM pages');

while ($row = $result->fetch_assoc()) {
    echo htmlspecialchars($row['pageheader'], ENT_QUOTES, 'UTF-8');
}

Keep the connection, query execution, result iteration and error handling in mysqli. Replacing only fetch() with a PDO constant will not convert a mysqli result into a PDO statement.

If the project uses PDO

$pdo = new PDO($dsn, $username, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

$stmt = $pdo->query(
    'SELECT id, pageheader, pagecontent FROM pages'
);

while ($row = $stmt->fetch()) {
    echo htmlspecialchars($row['pageheader'], ENT_QUOTES, 'UTF-8');
}

Setting PDO::ATTR_DEFAULT_FETCH_MODE makes ordinary fetches associative without repeating PDO::FETCH_ASSOC on every call. You can still pass an explicit mode when a particular result needs a different shape.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create an array keyed by id with PDO

For a menu or lookup table keyed by page id, select the key column first and use fetchAll(PDO::FETCH_UNIQUE). The first selected column becomes each array key; the remaining selected columns become that key’s row value.

$stmt = $pdo->query(
    'SELECT id, pageheader, pagecontent FROM pages ORDER BY id'
);

$pages = $stmt->fetchAll(PDO::FETCH_UNIQUE);

foreach ($pages as $id => $page) {
    $url = 'index1.php?id=' . rawurlencode((string) $id);
    echo '<a href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '">'
       . htmlspecialchars($page['pageheader'], ENT_QUOTES, 'UTF-8')
       . '</a>';
}

With that query, a row such as id = 7 is available as $pages[7], while its values remain in $pages[7]['pageheader'] and $pages[7]['pagecontent']. If id is not the first selected column, another column will become the key instead.

Validate the requested page

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);

if ($id === false || $id === null || !isset($pages[$id])) {
    http_response_code(404);
    exit('Page not found');
}

$page = $pages[$id];
echo htmlspecialchars($page['pagecontent'], ENT_QUOTES, 'UTF-8');

This check prevents an absent or invalid id from becoming an undefined-array-key notice. For a large table, retrieving one page with a parameterized query is usually more efficient than loading every page into memory.

Why generated links may appear broken

Database fetching and navigation are separate problems. When a link does not work, inspect the HTML the browser received rather than only the PHP source. Use the browser’s View Source command and verify the rendered href, filename and query-string value.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check the target filename

In the discussed example, links generated while the active script was index1.php pointed to index.php. Changing the target to the active filename restored the intended navigation:

$url = 'index1.php?id=' . rawurlencode((string) $id);

Also check that the server route actually contains that file and that the id parameter name matches the code reading $_GET.

Check the rendered element and CSS

  • Confirm that each anchor has a complete opening tag, a quoted href and a closing tag.
  • Confirm that the generated id is present and is the id you expect.
  • If the source is correct but clicks do nothing, inspect CSS for an element covering the anchor or a rule such as pointer-events: none.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Use one query or separate menu and content queries?

A single keyed result can work for a small, fixed page set: load the rows, loop over them for the menu, then select the requested row by id. As the site grows, separate queries are easier to maintain.

One combined query

  • Convenient when the complete page list is small.
  • Allows immediate menu generation and in-memory lookup.
  • Consumes more memory as the number or size of pages increases.

Separate queries

  1. Run a query for the menu fields, such as id and pageheader.
  2. Read and validate the requested id.
  3. Run a parameterized content query for that id.
$menu = $pdo->query(
    'SELECT id, pageheader FROM pages ORDER BY pageheader'
)->fetchAll();

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);

$contentStmt = $pdo->prepare(
    'SELECT pageheader, pagecontent FROM pages WHERE id = :id'
);
$contentStmt->execute(['id' => $id]);
$page = $contentStmt->fetch();

This split prevents menu pagination or search from accidentally omitting the page requested in the URL, and it avoids transferring full page content merely to draw navigation.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A practical troubleshooting checklist

  1. Inspect the object returned by the query and establish whether it is PDO or mysqli.
  2. Use only that API’s methods and constants.
  3. For PDO associative rows, set PDO::ATTR_DEFAULT_FETCH_MODE or pass PDO::FETCH_ASSOC.
  4. For an id-keyed PDO array, select id first and call fetchAll(PDO::FETCH_UNIQUE).
  5. Validate the requested id before reading the array or displaying content.
  6. View the browser’s generated source and correct any filename, query-string or malformed-anchor error.
  7. Inspect CSS only after confirming that the HTML and target URL are correct.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.