Query Database with php Error

Evening,

I am learning php ,mysql and I have a bit of a problem.

I have a Database (hst_working) with a table (hst_workings)
I know not the best naming conventions.

The table has the following fields: date, time, tid, origin, destination haulage1,haulage2,note

I have found some code that I have managed to understand
index.php

< html>
<body>
< form action="search.php" method="post">
Search < input type="text" name="search"><br>
< input type ="submit">
< /form>
< /body>
< /html  >

search.php

<?php
$search = $_POST['search'];

$servername = "localhost";

$username = "root";

$password = "";

$db = "hst_working";

$conn = new mysqli($servername, $username, $password, $db);

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

$sql = "select * from hst_workings where origin like '%$search%'";

$result = $conn->query($sql);

if ($result->num_rows > 0){

while($row = $result->fetch_assoc() ){

    echo $row["date"]."  ".$row["tid"]."  ".$row["origin"]."<br>";

}

} else {

    echo "0 records";

}

$conn->close();

?>

I get these errors:

Warning: Undefined array key “date” in C:\xampp\htdocs\testsite\search.php on line 22
Warning: Undefined array key “tid” in C:\xampp\htdocs\testsite\search.php on line 22
Warning: Undefined array key “origin” in C:\xampp\htdocs\testsite\search.php on line 22

I cannot see what I’m doing wrong.

Can I get some advice please?

Thanks in advance,

What is the actual database table definition? You either have a capitalization difference, a spelling difference, some extra character(s) as part of the column names, or perhaps more than one database and the wrong one is being used.

Here’s a bunch of programming practices that will help secure, simplify, and improve the User eXperience (UX) of this code -

  1. The form processing code and form should be on the same page. The code for any page should be laid out in this general order - 1) initialization, 2) post method form processing, 3) get method business logic - get/produce data needed to display the page, 4) html document.
  2. A search form should be a get method form. A get request is used when determining what will be displayed on a page. A post method request is used when performing an action on the server.
  3. The form should be ‘sticky’ and populate the field value with any existing field value so that the user doesn’t need to keep reentering the value over and over should they want to make a minor change in what is being searched for.
  4. You need to validate the resulting web page at validator.w3.org
  5. Don’t copy variables to other variables for nothing. This is just a waste of typing.
  6. You need to trim user entered data, mainly so that you can detect if all white-space characters were entered, then validate it before using it. If data isn’t valid, don’t use it and instead setup and display an error message for the user.
  7. The database connection code should be in a separate .php file that gets required when needed.
  8. You should not use the root database user, with no password for your applications. Create a specific user with a password, that only has the permissions needed for the application.
  9. Modern php (php8+) uses exceptions for database statement errors by default. When using exceptions for errors, no discrete error handling logic will get executed upon an error and should be removed, simplifying the code.
  10. You should list out the columns you are SELECTing in a query. This is so that you only select the data that you need and forces you to think about what you are doing with the data on the page.
  11. Don’t put external, unknown, dynamic values directly into sql query statements, where any sql special character in a value can break the sql query syntax, which is how sql injection is accomplished. Use a prepared query instead. If it seems like using the mysqli extension is overly complicated and inconsistent when dealing with prepared queries, it is. This would be a good time to switch to the much simpler and better designed PDO extension.
  12. Any dynamic value that you output in a html context needs to have htmlentities() applied to it, right before or as it is being output, to prevent any html entity in a value from being able to break the html syntax.
  13. When the code for a ‘false’ conditional branch is much shorter than the ‘true’ conditional branch, your code will be clearer and easier to read if you invert the condition being tested and put the shorter code first.
  14. There’s generally no need to close database connections in your code since php destroys all resources when your code ends.

Thanks for the reply.

A awful lot to look through and in depth.

I changed from the * to the field names and it worked (as in point 10).

When I used to (many many many years ago) do the odd it of VB coding we used use to use the * to select all the fields. Then be able to use them as needed.

I am using sql/php on my local machine with xampp not over networks hence not using a username or password as I want the code to work locally before I need to get it online,

Thanks again,

That would indicate that there is a capitalization difference between the actual column names and what the php code is using.

In a query, the column names are not case-sensitive. However, the letter-case that you SELECT determines the associative index names that php must use. When you use *, the letter-case is what the column definition is. When you listed out the columns, you probably used what you were using in the php code, and they therefore match. I recommend that you only use lower-case letters in identifiers so that you don’t need remember what letter-case you defined them as.

Here’s what the code would look like with the points that were made -

<?php

// 1) initialization,

// this example uses the much simpler and better designed PDO extension
require 'pdo_connection.php';

$errors = []; // array to hold user/validation errors

// 2) post method form processing,

// 3) get method business logic - get/produce data needed to display the page,

// detect (see php's null coalescing operator) and trim the input
$search = trim($_GET['search']??'');

// validate the input
if($search === '')
{
	// you need to decide what to do if the input is not valid
	// either setup and display an error message (which is what is shown here) or use a default value or action, such as matching all values (leave the WHERE term out of the query)
	$errors['search'] = 'Please enter a search term';
}
else
{
	// a query that can match more then one row needs an ORDER BY term so that the rows will be in a desired order
	$sql = "SELECT date, tid, origin
	FROM hst_workings
	WHERE origin like ?
	ORDER BY date
	";
	
	$stmt = $pdo->prepare($sql);
	$stmt->execute([ "%$search%" ]);
	$result = $stmt->fetchAll();
}

// 4) html document.
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Search example</title>
</head>
<body>

<?php
// display any errors
if(!empty($errors))
{
	echo '<p>'.implode('<br>',$errors).'</p>';
}
?>

<form>
<label>Search <input type="text" name="search" value="<?=htmlentities($search)?>"></label><br>
<input type ="submit">
</form>

<?php
// produce the output
if(empty($result))
{
    echo "<p>0 records</p>";
}
else
{
	echo "<p>Your search found ".count($result)." records</p>";
	foreach($result as $row)
	{
		// apply htmlentities to all elements in row
		$row = array_map('htmlentities',$row);
		echo $row["date"]."  ".$row["tid"]."  ".$row["origin"]."<br>";
	}
}
?>
</body>
</html>

Here’s typical PDO connection code -

$DB_HOST = ''; // database host name or ip address
$DB_USER = ''; // database username
$DB_PASS = ''; // database password
$DB_NAME = ''; // database name
$DB_ENCODING = 'utf8mb4'; // db character encoding. set to match your database table's character set. note: utf8 is an alias of utf8mb3/utf8mb4

$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // set the error mode to exceptions - this is the default setting now in php8+
			PDO::ATTR_EMULATE_PREPARES => false, // run real prepared queries
			PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC // set default fetch mode to assoc
			];

$pdo = new pdo("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=$DB_ENCODING",$DB_USER,$DB_PASS,$options);
Sponsor our Newsletter | Privacy Policy | Terms of Service