The below code defines a function for taking an entire GPS NMEA Sentence and verifying its intergrity. Below the function definition are three GPS NMEA Sentences, 2 of which are good and 1 of which is bad. The three are then run through the function and statuses are output to the screen. See it work or See the lesser commented/styled version. Or check out the full OOP version.

<?php
/**
 * Verify integrity of a GPS NMEA Sentence by extracting the data and the internal checksum, calculating the checksum of the data, and comparing it to the internal checksum
 *
 * @param STRING $GPS_NMEA_Sentence --The GPS NMEA sentence we are checking
 * @return BOOL --True if integrity is good, false if not
 * @author Jim Auldridge
 * @link http://www.codepedia.com/1/The+GPRMC+Sentence
 * @link http://www.codepedia.com/1/Calculating+and+Validating+NMEA+Checksums
 * @link http://www.tigoe.net/pcomp/code/category/code/processing/127
 * @link http://wiki.forum.nokia.com/index.php/NMEA_(GPS)_Location_Viewer
 */
function GPS_NMEA_Sentence_Integrity($GPS_NMEA_Sentence)
{
  
//Assume failure...
  
$return_value false;
  
//Sanity check on input
  
if(is_string($GPS_NMEA_Sentence))
  {
    
//Extract Data and Internal Checksum
    
preg_match('/^\$([^*]+)\*/',   $GPS_NMEA_Sentence$GPS_NMEA_Data              );
    
preg_match('/\*([^,]+)(,|$)/'$GPS_NMEA_Sentence$GPS_NMEA_Internal_Checksum );
    
//Ensure extractions got what we needed
    
if
    (
      
is_array($GPS_NMEA_Data)              &&
      !empty(
$GPS_NMEA_Data[1])             &&
      
is_array($GPS_NMEA_Internal_Checksum) &&
      !empty(
$GPS_NMEA_Internal_Checksum[1])
    )
    {
      
//Simplify extracted data
      
$GPS_NMEA_Data $GPS_NMEA_Data[1];
      
$GPS_NMEA_Internal_Checksum $GPS_NMEA_Internal_Checksum[1];
      
//Start calculating checksum, begin at 0
      
$Calculated_Checksum 0;
      
//Loop for length of data string
      
for($i=0;$i<strlen($GPS_NMEA_Data);$i++)
      {
        
//Adding to checksum the XOR of the current value of checksum and the
        //ASCII code of the current char of the data string for this iteration
        
$Calculated_Checksum = ($Calculated_Checksum ord($GPS_NMEA_Data{$i}));
      }
      
//Convert our calculated checksum to hex
      
$Calculated_Checksum dechex($Calculated_Checksum);
      
//Compare it to the internal checksum and set return accordingly
      
$return_value = !!($GPS_NMEA_Internal_Checksum===$Calculated_Checksum);
    }
  }
  
//Return the BOOL value
  
return $return_value;
}


//Two Good Sentences
$GPS_Serial_Output_1 '$GPRMC,030748.000,A,4553.0146,N,07352.1516,W,0.25,0.00,171107,,,A*76,AUTO';
$GPS_Serial_Output_2 '$GPRMC,155123.000,A,4043.8432,N,07359.7653,W,0.15,83.25,200407,,*28';
//And a third that is bad
$GPS_Serial_Output_3 '$GPRMC,155213.000,A,4053.8432,N,07359.7653,W,0.15,83.25,200407,,*49';

//Checking them all:
echo '<p>Checking Sentence 1: <strong>'.(GPS_NMEA_Sentence_Integrity($GPS_Serial_Output_1) ? 'Good' 'Bad').'</strong></p>';
echo 
'<p>Checking Sentence 2: <strong>'.(GPS_NMEA_Sentence_Integrity($GPS_Serial_Output_2) ? 'Good' 'Bad').'</strong></p>';
echo 
'<p>Checking Sentence 3: <strong>'.(GPS_NMEA_Sentence_Integrity($GPS_Serial_Output_3) ? 'Good' 'Bad').'</strong></p>';
?>