"Non numeric" error

Hi, the scenario is:
I run an apartment complex, someone comes in to pay their rent. I fill in an html form
to record payment(update “payments” database table) and print a receipt.
I hope u will look at it and offer advice. I hope to combine both
the payment and receipt. I don’t understand the “non numeric” error and I’m obviously doing
my echoes wrong as the receipt# is not displayed on the receipt(instead of the value in the
“numberstbl” it displays “receiptno”.


the code:

<!DOCTYPE html><html>
<head>
<title>rent payment and receipt</title>
</head>
<body><center>
<?php
echo "<center>";echo date('m/d/y');echo "</center>";
// Include config file
require_once "getpayments.php";

//MySqli Select Query$results = $conn->query("SELECT rentdue FROM payments");

$unit=$_POST['unit']; $rentpaid=$_POST['rentpaid'];
$hudpay=$_POST['hudpay']; $datepaid=$_POST['datepaid'];

$unit='unit'; $rentpaid='rentpaid'; $rentdue='rentdue'; $hudpay='hudpay';
$prevbal='prevbal'; $latechg='latechg'; $datepaid='datepaid'; $prev="0.00"; $late="0.00";

// if no pay or part pay add $10 to latechg and amount not paid to prevbal
if ($rentpaid < $rentdue)
{ $latechg = $latechg + "10.00"; $prevbal = $rentdue - $rentpaid; }
// if payment = rentdue
elseif ($rentpaid == $rentdue)
 { $prevbal = $prev; $latechg = $late; }

// if over-payment subtract over-payment from prevbal
elseif ($rentpaid > $rentdue )
{ 
$prevbal = $rentpaid  - $rentdue; $latechg = $late; } // ***  29 non numeric both *** 

//MySqli Select Query
$results = $conn->query("SELECT receiptno FROM numberstbl");
$receiptno='receiptno';
?>
<b><?php echo $_POST["receiptno"]; ?>
<!--<img src="apt-pic.jpg" alt="apartment" height=250 width=800><br> -->
For:<SELECT name="options">
<option value="#990033" style="background-color: Violet;">Rent payment</option>
<option value="#003300" style="background-color: Aquamarine;">Background Check</option>
<option value="#6600cc" style="background-color: Pink;">Security Deposit Payment</option>
<option value="#003300" style="background-color: Aquamarine;">Damages Payment</option>
<option value="#990033" style="background-color: Violet;">Late Charges Payment</option>
<option value="#003300" style="background-color: Aquamarine;">Court Costs Payment</option>
<option value="#6600cc" style="background-color: Pink;">NSF Payment</option>
<option value="#990033" style="background-color: Violet;"> </option>
</SELECT><br>

<input type="text" size = 25 STYLE="color: #000000; background-color: #D4AAFF;" name="Name" value="Business Name -">
<input type="text" size = 25 STYLE="color: #000000; background-color: #D4D4FF;" name="Addy1" value="Business address -">
<input type="text" size = 25 STYLE="color: #000000; background-color: #D4AAFF;" name="Addy2" value="City, State, Zip"><br>

<b> unit paying is: <?php echo $_POST["unit"]; ?> -
Amount paid is: <?php echo $_POST["rentpaid"]; ?> -
Amount due is: <?php echo $rentdue; ?></b><br> // *** line 54 ****

<b>Sign here</b><input type="text" size=75 name="sign"><br>
<input type="text" size=25 name="thanks" readonly value="We Thank You:" STYLE="color:
#000000; font-weight: bold; background-color: #ffccff;" onFocus="this.value=''"><br>

<?php
/* Perform a query, check for error */
if(!empty($_POST["update"]))
   {
$sql = "UPDATE payments SET
rentpaid='$rentpaid', hudpay='$hudpay', prevbal='$prevbal', latechg='$latechg', datepaid='$datepaid' 
where unit = '$unit'";
if ($conn->query($sql) === TRUE) { echo "ng"; } 
else { echo "Error updating record: " . $conn->error; }
    }
/* Perform a query, check for error */
if(!empty($_POST["update"]))
   {
$sql = "UPDATE numberstbl SET 
receiptno = $receiptno + 1 where id=1";
if ($conn->query($sql) === TRUE) { echo "ng"; } 
else { echo "Error updating record: " . $conn->error; }
$conn->close();
 }
?>
</center></body></html>

errors:
06/30/21

Warning: A non-numeric value encountered in C:\xampp\htdocs\property\payment.php on line 29

Warning: A non-numeric value encountered in C:\xampp\htdocs\property\payment.php on line 29

Notice: Undefined index: receiptno in C:\xampp\htdocs\property\payment.php on line 37

unit paying is: apt1 - Amount paid is: 530.00 - Amount due is: rentdue
// *** line 54 ****

Hi @ckguitarz and a warm welcome to the SP Forums.

Please start and finish your script with three backticks on a separate line of highlight the script and select the </> from the top menu.

Basically the errors are due to accepting $_POST` variable strings and applying them to functions that require integer parameters.

One method of preventing the errors is to use PHP cast

// adjustments
$unit = (integer) $_POST[‘unit’]; 
$rentpaid = (float) $_POST[‘rentpaid’];
$hudpay  = (float) $_POST[‘hudpay’];
$datepaid = (string) $_POST[‘datepaid’];
1 Like

I don’t understand these lines. In the first, you get some values from your HTML form:

$unit=$_POST['unit']; $rentpaid=$_POST['rentpaid'];
$hudpay=$_POST['hudpay']; $datepaid=$_POST['datepaid'];

and then a couple of lines later, you overwrite them with strings.

$unit='unit'; $rentpaid='rentpaid'; $rentdue='rentdue'; $hudpay='hudpay';
$prevbal='prevbal'; $latechg='latechg'; $datepaid='datepaid'; $prev="0.00"; $late="0.00";

As you’ve assigned the string "rentpaid" to the variable $rentpaid, then of course it’s not a number.

It only gets into line 29 because the string "rentpaid" is “greater than” the string "rentdue", based on the ASCII values of the characters in the string.

In this line

$latechg = $latechg + "10.00";

why do you put quotes around the amount you want to add as a surcharge? You’re telling PHP to concatenate the string “10.00” to the end of the variable here. Once the variable contains a number, if you want to add 10 to it, leave off the quotes.

When you get down to your updating queries, you also need to use Prepared Statements instead of concatenating variables into the query strings like that. In your final update query, I don’t believe you want to use the variable $receiptno in the query at all, if it’s doing what I think it’s doing. But I wouldn’t handle the receipt number as you do - I’d just have the receipt transaction table have an auto-incrementing unique id and use that as the receipt number. I don’t see anywhere that you have a transaction table, and I think you should from an accounting point of view, not from a database design.

This section is a bit strange, too:

$results = $conn->query("SELECT receiptno FROM numberstbl");
$receiptno='receiptno';
?>
<b><?php echo $_POST["receiptno"]; ?>

You run a query to retrieve the receipt number, then you set $receiptno to be a string containing "receiptno". At the top of the receipt, you display a form variable called “receiptno”, and get an error because there isn’t a form variable of that name. Surely you want to run a fetch() on the database query and get the receipt number from there?

I suspect you might run into difficulties with that approach if more than one person is issuing a receipt at the same time, just because of the delay between retrieving and displaying the receipt number, and updating it to the next one. Another reason that an auto-incrementing row-id on the transaction table would work better IMO.

2 Likes

type or paste code here

-----------------------------------------------------------------------
the code:
<!DOCTYPE html><html>
<head>

<STYLE TYPE="text/css">
.blue {background-color: #ccffff;}
.tan {background-color: #FFD4FF;}
h1.centered-cell {text-align: center;font-size: 1.1em;}
</STYLE>

</head>
<body><center><b><font size=+1>Rent Payment</b><p>

<?php
echo "<center>";echo date('m/d/y');echo "</center>";
$id="''";

// Include config file
require_once "getprerentdb.php";

//MySqli Select Query
$results = $mysqli->query("SELECT * FROM payments");

$unit=$_POST['unit'];
$rentpaid=$_POST['rentpaid'];
$hudpay=$_POST['hudpay'];
$datepaid=$_POST['datepaid'];

$prevbal='prevbal'; $latechg='latechg'; $prev=0; $late=0; $rentdue='rentdue';

// if no pay or part pay add $10 to latechg and amount not paid to prevbal
if ($rentpaid < $rentdue)
{ $latechg = $latechg + 10.00; 
$prevbal = $rentdue - $rentpaid; } // line 32

/* ************************************************************** */
// ****latechg, 10.00, prevbal, rentdue, rentpaid are all decimal *****
/* ************************************************************** */

// if payment = rentdue
elseif ($rentpaid == $rentdue)
 { $prevbal = $prev; $latechg = $late; }

// if over-payment subtract over-payment from prevbal
elseif ($rentpaid > $rentdue )
{ 
$prevbal = $rentpaid  - $rentdue; $latechg = $late; }

// ---------------------------------------
//      while($row = mysqli_fetch_array($results))  {
// ----------------------------------------

/* Perform a query, check for error */
   if(!empty($_POST["update"]))
   {
$mysqli->query("Update payments SET
 rentpaid = '$rentpaid', datepaid = '$datepaid', hudpay = '$hudpay'
where unit = '$unit'");
}
//}
?>     
</center></body></html>
---------------------------------------------
result:
Rent Payment

07/01/21

Warning: A non-numeric value encountered in C:\xampp\htdocs\property\payment.php on line 32

Warning: A non-numeric value encountered in C:\xampp\htdocs\property\payment.php on line 33

You still have this line

$prevbal='prevbal'; $latechg='latechg'; $prev=0; $late=0; $rentdue='rentdue';

and then a couple of lines later, you use $rentdue as if it’s a number when it is not, and you try to add 10 (now not in quotes) to a string that contains "latechg".

if ($rentpaid < $rentdue)  // is your number less than the string "rentdue"? Yes, all digits are below "r" in ASCII.
{ $latechg = $latechg + 10.00;   // you cannot add the value 10 to the string "latechg"
$prevbal = $rentdue - $rentpaid; } // you cannot subtract the number in `$rentpaid` from the string "rentdue"
// ****latechg, 10.00, prevbal, rentdue, rentpaid are all decimal *****

No, they are not. rentpaid might be, but latechg, prevbal and rentdue all contain strings.

I used:

$unit = (string) $_POST[‘unit’]; 
$rentpaid = (float) $_POST[‘rentpaid’];
$hudpay  = (float) $_POST[‘hudpay’];
$datepaid = (string) $_POST[‘datepaid’];

as was suggested and I got:

Rent Payment

07/02/21

Warning: Use of undefined constant �unit� - assumed ‘�unit�’ (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\property\payment.php on line 23

Notice: Undefined index: �unit� in C:\xampp\htdocs\property\payment.php on line 23

Warning: Use of undefined constant �rentpaid� - assumed ‘�rentpaid�’ (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\property\payment.php on line 24

Notice: Undefined index: �rentpaid� in C:\xampp\htdocs\property\payment.php on line 24

Warning: Use of undefined constant �hudpay� - assumed ‘�hudpay�’ (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\property\payment.php on line 25

Notice: Undefined index: �hudpay� in C:\xampp\htdocs\property\payment.php on line 25

Warning: Use of undefined constant �datepaid� - assumed ‘�datepaid�’ (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\property\payment.php on line 26

Notice: Undefined index: �datepaid� in C:\xampp\htdocs\property\payment.php on line 26

Before assigning the variables, try displaying the $_POST parameters:

echo ‘<pre>’; // adds line feeds
print _r($_POST);

Edit:

Also amend this string value to the correct float value.

$rentdue='rentdue';

Wherever you got those lines of code from to put into your file, they were ‘published’ and now contain smart/curly quotes, which are not recognized in php source code. You will need to delete all the quotes that look like ‘ or ’ and replace them with straight ascii single-quotes '

Next, by definition, all $_POST data are strings, so there’s no point in casting a string to a string.

I really thank you for your response. I have been trying to make sense of this and the
several forums seem to think I already know what I’m asking of. And the manuals are worse.
I’m studying the prepared statements now. I obviously misunderstood the concept of the
auto-incrementing id. All my tables use auto-incrementing id(primary). No matter, I
can’t successfully define “variables rentdue and receiptno”. My revised code follows.



 <!DOCTYPE html><html>
<head>
<title>rent payment and receipt</title>
</head>
<body><center>
<?php
echo "<center>";echo date('m/d/y');echo "</center>";
// Include config file
$link = mysqli_connect("localhost", "root", "", "prerentdb");
// Check connection
if($link === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); }

//MySqli Select Query
$results = $link->query("SELECT unit, rentpaid, rentdue, prevbal, latechg, FROM payments");
$unit = $_POST['unit'];  
$hudpay = $_POST['hudpay']; 
$rentpaid = $_POST['rentpaid'];
$hudpay  =  $_POST['hudpay'];
$datepaid=$_POST['datepaid'];
//MySqli Select Query
$results = $link->query("SELECT receiptno FROM numberstbl"); 

// if no pay or part pay add $10 to latechg and amount not paid to prevbal
if ($rentpaid < $rentdue)// undefined rentdue line 24
{ $latechg = $latechg + 10.00; $prevbal = $rentdue - $rentpaid; }

// if payment = rentdue
elseif ($rentpaid == $rentdue)// undefined rentdue line 28
 { $prevbal = 0.00; $latechg = 0.00; }

// if over-payment subtract over-payment from prevbal
elseif ($rentpaid > $rentdue )// undefined rentdue line 32
{ 
$prevbal = $rentpaid  - $rentdue; $latechg = 0.00; }// undefined rentdue line 34
// ---------------------------------------
      while($row = mysqli_fetch_array($results))  {
// ----------------------------------------
/* Perform a query, check for error */
if(!empty($_POST["update"]))
   {
$sql = "UPDATE payments SET
rentpaid='$rentpaid', hudpay='$hudpay', prevbal='$prevbal', latechg='$latechg', datepaid='$datepaid' 
where unit = '$unit'";
if ($link->query($sql) === TRUE) { echo "updated"; } 
else { echo "Error updating record: " . $conn->error; }
    } 
?>

<img src="apt-pic.jpg" alt="apartment" height=250 width=800><br> 
<b><?php echo $receiptno; ?>// undefined receiptno line 50
For:<SELECT name="options">
<option value="#990033" style="background-color: Violet;">Rent payment</option>
<option value="#003300" style="background-color: Aquamarine;">Background Check</option>
<option value="#6600cc" style="background-color: Pink;">Security Deposit Payment</option>
<option value="#003300" style="background-color: Aquamarine;">Damages Payment</option>
<option value="#990033" style="background-color: Violet;">Late Charges Payment</option>
<option value="#003300" style="background-color: Aquamarine;">Court Costs Payment</option>
<option value="#6600cc" style="background-color: Pink;">NSF Payment</option>
<option value="#990033" style="background-color: Violet;"> </option>
</SELECT><br>

<input type="text" size = 25 STYLE="color: #000000; background-color: #D4AAFF;" name="Name" value="Business Name -">
<input type="text" size = 25 STYLE="color: #000000; background-color: #D4D4FF;" name="Addy1" value="Business address -">
<input type="text" size = 25 STYLE="color: #000000; background-color: #D4AAFF;" name="Addy2" value="City, State, Zip"><br>

<b> unit paying is: <?php echo $_POST["unit"]; ?> -
Amount paid is: $<?php echo $_POST["rentpaid"]; ?> -
Amount due is: $<?php echo $rentdue; ?></b><br>// undefined rentdue line 68

<b>Sign here</b><input type="text" size=75 name="sign"><br>
<input type="text" size=25 name="thanks" readonly value="We Thank You:" STYLE="color:
#000000; font-weight: bold; background-color: #ffccff;" onFocus="this.value=''"><br>

<?php

/* Perform a query, check for error */
if(!empty($_POST["update"]))
   {
$sql = "UPDATE numberstbl SET 
receiptno = $receiptno + 1 where id=1";
if(mysqli_query($link, $sql)){ echo "updated"; }
else { echo "ERROR: Could not able to execute $sql. " . mysqli_error($link); }

$link->close();
 }
	  }
?>
</center></body></html>

You don’t define $rentdue anywhere in your code. You have a query:

$results = $link->query("SELECT unit, rentpaid, rentdue, prevbal, latechg, FROM payments");

where you seem to be selecting all payment records, when I suspect that you only want to retrieve the information for a specific unit, so you need to look at the WHERE clause similar to how you have used it in your UPDATE query a bit later on.

But, while you execute the query, you don’t retrieve the results from it. Read up on fetch() to see how to get some results and then assign those results to PHP variables which you can then use in your calculations.

The same problem is causing your undefined $receiptno - you run a query to get the receipt number from the table, but you never fetch the results and put them into a PHP variable. You then display a variable that doesn’t exist.

I can’t really go into much more detail because I use PDO rather than mysqli, but there is a full example on how to select values from a table and retrieve them in the documentation page:

PHP: mysqli_stmt::fetch - Manual

1 Like

There are at least two functional problems in the last posted code -

  1. There’s an sql syntax error in the first SELECT query, but you don’t know this since there is no consistent error handling for the database statements. You ALWASY need error handling for statements that can fail. For database statements that can fail - connection, query, prepare, and execute, the easiest way of adding error handling, without adding logic at each statement, is to use exceptions for errors and in most cases let php catch and handle the exception, where php will use its error related settings to control what happens with the actual error information (database statement errors will ‘automatically’ get displayed/logged the same as php errors.) You would then remove all the existing database error handling logic, since it won’t get executed upon an error, cleaning up and simplifying the code.
  2. There’s no form at all, so none of the $_POST data will exist. Since a lot of the code using $_POST data isn’t testing if a form was summitted first, you are getting php errors just because the page was requested.

If you were doing this for real -

  1. You would have a database table for the unique rental unit information.
  2. You would have a database table for the unique renter information.
  3. You would have a database table for the unit renter history information, with an id, unit id, renter id, start date, and end date (which is set to a maximum value in the row for the current renter.) The id from this table establishes a unit_renter id (account) that you would use to store any related data, such as status records, communications records, payment records, …
  4. You would have a database table for the category (payment option) choices. You would build the select/option menu dynamically from the database table information. The select/option menu would submit the choice id, not a color code. You would include this submitted id in the records you insert into the payment accounting table.
  5. You would have a database table for the payment accounting, where you would INSERT a row for each transaction that adds or subtracts an amount for each unit_renter id (account). To get the current total for any unit_renter, you would SUM() the plus/minus amounts in a query. If you want a receipt number to display/print, you would get the last insert id from the insert query for this table.

The operation of the page would then consist of using a select/option menu for selecting the unit, which would find the latest ‘open’ unit_renter row, a select/option menu for selecting the payment category, entering the amount, and submitting the data.

Next, your code should be laid out in this general order -

  1. Initialization - get/create things your page needs for it to work - session_start, required files, database connection, …
  2. Post method form processing - process any post method form data.
  3. Get method business logic - get/produce data needed to display the dynamic content on the page.
  4. Html document.

Note: you should use css to style the output, not repetitive in-line style rules.

Lastly, your post method form processing code should -

  1. Detect if a post method form was submitted before referencing any of the form data.
  2. Keep the input data as an array and operate on elements in the array throughout the rest of the code.
  3. Trim all the input data, mainly so that you can detect if all white space characters were entered.
  4. Validate all inputs, storing validation error messages in an array using the field name as the array index. To display the errors, you would test and display the content of this array at the appropriate point in the html document.
  5. If there are no errors (the array holding the error messages is empty), use the submitted form data.
  6. After successfully completing the form processing code, redirect to the exact same url of the current page to cause a get request for that page. If you want to display a one-time success message or the just inserted data for printing a receipt, use a session variable to indicate what you want to do after the redirect, then test, display, and clear the session variable at the appropriate point in the html document.
2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.