Jump to content

Recommended Posts

I am getting the exact same error over and over again, and I have no idea why:

 

Quote

PHP Warning: Undefined variable $total in C:\inetpub\wwwroot\pages\poll\includes\functions.php on line 27

Consider the code

 

function calculateResults($pollObj) {
		$conn = null;
		$stmt = null;
		$rs = null;
		$total = 0;
		global $resultsCalcArray;
		try {
			$pollId = stripHTML(cleanXSS($pollObj->id));
			$conn = new PDO(DB_CONNECTION_STR, MYSQL_DB_USER, MYSQL_DB_PASSWORD, MYSQL_DB_PDO_OPTIONS);
			$stmt = $conn->prepare(RESULTS_SQL);
			$stmt->execute([$pollId, $pollId, $pollId]);
			$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
			if (!is_null($rs)) {
				foreach ($rs as $row) {
					if (!empty($row['kount'])) {
						$total += (int) $row['kount'];
						array_push($resultsCalcArray, $row['kount']);
					}
				}
			}
			
			$_SESSION['total'] = $total;
			if ($total > 0) {							// TO PREVENT DIVIDE BY ZERO ERROR
				$resultsCalcArray = array_map(function($votes) {
												 return round($votes / $total) * 100;
											  }, $resultsCalcArray);
			}
			
		} catch (Exception $e) {
			$msg = ERROR_MESSAGE . ' calculateResults() ' . date('Y-m-d H:i:s') . ' ' . $e->getMessage();
			toLogDB($msg);
			error_log($msg, 0);						
			throw $e;
			$hasErrors = true;
		} finally {
			if (!is_null($rs)) {
				$rs = null;
			}
			 
			if (!is_null($stmt)) {
				$stmt = null;
			}
									
			if (!is_null($conn)) {
				$conn = null;
			}
		}
	}

I honestly don't know what I did wrong here, but it is completely failing the entire code within the function inside array_map(), and I have no idea why.

Help appreciated and needed.

Thanks

To include a variable that is defined externally to the map function you need "use()"

    $calcArray = [ 34, 56, 82 ];
    
    $total = 10;
    
    $calcArray = array_map (
                    function($v) use ($total) {
                        return round($v / $total);
                    },
                    $calcArray
                 );
                 
    echo '<pre>' . print_r($calcArray, 1) . '</pre>';

Alternatively, you can use this syntax...

    $calcArray = [ 34, 56, 82 ];
    
    $total = 10;
    
    $calcArray = array_map (
                    fn($v) => round($v / $total),
                    $calcArray
                 );
                 
    echo '<pre>' . print_r($calcArray, 1) . '</pre>';

See https://www.php.net/manual/en/functions.arrow.php

the anonymous function has local variable scope, like any php function. you can add use ($total) to the definition to make the variable available inside the function -

$resultsCalcArray = array_map(function($votes) use ($total) {

 

as to the posted code -

  1. the input call-time parameter should only be the $id and you should only call this function after you have validated the $id.
  2. this function should also have an existing pdo connection as an input call-time parameter. it is the wrong responsibility for this function to make a database connection.
  3. there's no point is defining and initializing $conn, $stmt, and $rs.
  4. don't use the global keyword to get data into or out of a function. this is not general purpose and results in spaghetti code that is hard to debug problems in. all input data to a function should be supplied as call-time parameters and the function should return the result it produces to the calling code.
  5. if you set the default fetch mode to assoc when you make the database connection, you won't need to specify it in each fetch statement.
  6. fetchAll() won't ever return a null, so the !is_null() test will never fail and should be removed.
  7. since you are only operating on the 'kount' column, that is the only thing the query should SELECT.
  8. if you have some reason to select other columns, you can build (or add to) the $resultsCalcArray from just the 'kount' column by using array_column().
  9. you can directly get the total of the $resultsCalcArray 'kount' values by using array_sum().
  10. no in-line code after the throw $e; statement will ever get executed and should be removed.
  11. there's generally no point in freeing up result sets, closing prepared query handles, or closing database connections in your code, at all, and there's certainly no point in doing this inside a function, since all those things get destroyed when the function call ends.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.