An OOP version of a GPS NMEA Sentence. See the output of the example codes from under the below class definition.

<?php
/**
 * A class for generating and validating objects which represent GPS NMEA Sentences
 *
 * @author Jim Auldridge
 * @link http://www.codepedia.com/1/The+GPRMC+Sentence
 * @link http://www.codepedia.com/1/Calculating+and+Validating+NMEA+Checksums
 */
class GPS_NMEA_Sentence
{
  protected 
$Sentence;
  protected 
$Data;
  protected 
$Internal_Checksum;
  protected 
$Calculated_Checksum;

  protected 
$Valid_Command_Words = array( 'GPRMC' );

  protected 
$CommandWord 'GPRMC';
  protected 
$SatelliteDerivedTime '';
  protected 
$SatelliteFixStatus '';
  protected 
$LatitudeDecimalDegrees '';
  protected 
$LatitudeHemisphere '';
  protected 
$LongitudeDecimalDegrees '';
  protected 
$LongitudeHemisphere '';
  protected 
$Speed '';
  protected 
$Bearing '';
  protected 
$UTCDate '';

  protected 
$Valid false;

  protected 
$in_error false;
  protected 
$error_str '';

  
/**
   *
   * @access public
   * @param OPTIONAL STRING $GPS_NMEA_Sentence
   * @return void
   */
  
public function __construct$GPS_NMEA_Sentence null )
  {
    if( ! 
is_null$GPS_NMEA_Sentence ) )
    {
      
$this->setSentence$GPS_NMEA_Sentence );
    }
  }
  
/**
   *
   * @access public
   * @param STRING $GPS_NMEA_Sentence
   * @return GPS_NMEA_Sentence
   */
  
public function setSentence$GPS_NMEA_Sentence )
  {
    if( 
is_string$GPS_NMEA_Sentence ) && ! empty( $GPS_NMEA_Sentence ) )
    {
      
$this->Sentence $GPS_NMEA_Sentence;
    }
    else
    {
      
$this->setError__METHOD__ 'received non-string or empty value.' );
    }

    
$this->resetStatuses();
    
$this->parseSentence();
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setCommandWord$value )
  {
    
$this->CommandWord $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setSatelliteDerivedTime$value )
  {
    
$this->SatelliteDerivedTime $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setSatelliteFixStatus$value )
  {
    
$this->SatelliteFixStatus $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setLatitudeDecimalDegrees$value )
  {
    
$this->LatitudeDecimalDegrees $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setLatitudeHemisphere$value )
  {
    
$this->LatitudeHemisphere $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setLongitudeDecimalDegrees$value )
  {
    
$this->LongitudeDecimalDegrees $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setLongitudeHemisphere$value )
  {
    
$this->LongitudeHemisphere $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setSpeed$value )
  {
    
$this->Speed $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setBearing$value )
  {
    
$this->Bearing $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @param STRING $value
   * @return GPS_NMEA_Sentence
   */
  
public function setUTCDate$value )
  {
    
$this->UTCDate $value;
    return 
$this;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getSentence()
  {
    return ( ! 
$this->inError() && $this->isValid() ) ? $this->Sentence '';
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function __toString()
  {
    return 
$this->getSentence();
  }
  
  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getCommandWord()
  {
    return 
$this->CommandWord;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getSatelliteDerivedTime()
  {
    return 
$this->SatelliteDerivedTime;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getSatelliteFixStatus()
  {
    return 
$this->SatelliteFixStatus;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getLatitudeDecimalDegrees()
  {
    return 
$this->LatitudeDecimalDegrees;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getLatitudeHemisphere()
  {
    return 
$this->LatitudeHemisphere;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getLongitudeDecimalDegrees()
  {
    return 
$this->LongitudeDecimalDegrees;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getLongitudeHemisphere()
  {
    return 
$this->LongitudeHemisphere;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getSpeed()
  {
    return 
$this->Speed;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getBearing()
  {
    return 
$this->Bearing;
  }

  
/**
   *
   * @access public
   * @return STRING
   */
  
public function getUTCDate()
  {
    return 
$this->UTCDate;
  }

  
/**
   *
   * @access public
   * @return OBJECT $this
   */
  
public function parseSentence()
  {
    if( ! 
$this->inError() )
    {
      
$this->extractDataFromSentence();
      
$this->calculateChecksum();
      
$this->extractWordsFromData();
      
$this->extractInternalChecksum();
      
$this->Valid = !! ( $this->compareChecksums() && $this->validCommandWord() );
    }

    return 
$this;
  }

  
/**
   *
   * @access public
   * @return OBJECT $this
   */
  
public function writeSentence()
  {
    if( ! 
$this->inError() )
    {
      
$this->Data sprintf(
        
'%s,%s,%s,%s,%s,%s,%s,%s,%s,%s',
        
$this->CommandWord,
        
$this->SatelliteDerivedTime,
        
$this->SatelliteFixStatus,
        
$this->LatitudeDecimalDegrees,
        
$this->LatitudeHemisphere,
        
$this->LongitudeDecimalDegrees,
        
$this->LongitudeHemisphere,
        
$this->Speed,
        
$this->Bearing,
        
$this->UTCDate
      
);

      
$this->calculateChecksum();
      
$this->Internal_Checksum $this->Calculated_Checksum;
      
$this->Valid = !! ( $this->compareChecksums() && $this->validCommandWord() );
      
$this->Sentence sprintf(
        
'$%s*%s',
        
$this->Data,
        
$this->Internal_Checksum
      
);
    }

    return 
$this;
  }
  
/**
   *
   * @access public
   * @return BOOLEAN
   */
  
public function isValid()
  {
    return 
$this->Valid;
  }

  
/**
   *
   * @access public
   * @return BOOLEAN
   */
  
public function inError()
  {
    return 
$this->in_error;
  }

  
/**
   *
   * @access public
   * @return MIXED
   */
  
public function getErrorStr()
  {
    return 
$this->in_error $this->error_str null;
  }

  
/**
   *
   * @access protected
   * @return void
   */
  
protected function setError($error_str)
  {
    
$this->in_error true;
    
$this->error_str $error_str;
  }

  
/**
   *
   * @access public
   * @return OBJECT $this
   */
  
public function resetStatuses()
  {
    
$this->Valid false;
    
$this->in_error false;
    
$this->error_str '';
  }

  
/**
   *
   * @access protected
   * @return void
   */
  
protected function extractDataFromSentence()
  {
    if( ! 
$this->inError() )
    {
      
preg_match'/^\$([^*]+)\*/'$this->Sentence,$GPS_NMEA_Data );
      if( 
is_array$GPS_NMEA_Data ) && ! empty( $GPS_NMEA_Data[1] ) )
      {
        
$this->Data $GPS_NMEA_Data[1];
      }
      else
      {
        
$this->setError__METHOD__ ' could not extract data from $Sentence property.');
      }
    }
  }

  
/**
   *
   * @access protected
   * @return void
   */
  
protected function extractWordsFromData()
  {
    static 
$wordnames = array(
      
'CommandWord',
      
'SatelliteDerivedTime',
      
'SatelliteFixStatus',
      
'LatitudeDecimalDegrees',
      
'LatitudeHemisphere',
      
'LongitudeDecimalDegrees',
      
'LongitudeHemisphere',
      
'Speed',
      
'Bearing',
      
'UTCDate'
    
);

    if( ! 
$this->inError() )
    {
      
$words explode','$this->Data );

      for( 
$i 0$i count$wordnames ); $i++ )
      {
        
$this->$wordnames[$i] = empty( $words[$i] ) ? '' $words[$i];
      }
    }
  }

  
/**
   *
   * @access protected
   * @return void
   */
  
protected function extractInternalChecksum()
  {
    if( ! 
$this->inError() )
    {
      
preg_match'/\*([^,]+)(?:,|$)/'$this->Sentence$GPS_NMEA_Internal_Checksum );

      if( 
is_array$GPS_NMEA_Internal_Checksum ) && ! empty( $GPS_NMEA_Internal_Checksum[1] ) )
      {
        
$this->Internal_Checksum $GPS_NMEA_Internal_Checksum[1];
      }
      else
      {
        
$this->setError__METHOD__ ' could not extract internal checksum from $Sentence property.');
      }
    }
  }

  
/**
   *
   * @access protected
   * @return void
   */
  
protected function calculateChecksum()
  {
    if( ! 
$this->inError() )
    {
      
$Calculated_Checksum 0;
      for( 
$i 0$i strlen$this->Data ); $i++ )
      {
        
$Calculated_Checksum = ( $Calculated_Checksum ord$this->Data[$i] ) );
      }
      
$this->Calculated_Checksum dechex$Calculated_Checksum );
    }
  }

  
/**
   *
   * @access protected
   * @return void
   */
  
protected function compareChecksums()
  {
    
$return_value false;
    if( ! 
$this->inError() )
    {
      if( 
$this->Internal_Checksum === $this->Calculated_Checksum )
      {
        
$return_value true;
      }
      else
      {
        
$this->setError__METHOD__.' found checksum mismatch.' );
      }
    }
    return 
$return_value;
  }

  
/**
   *
   * @access protected
   * @return void
   */
  
protected function validCommandWord()
  {
    
$return_value false;
    if( ! 
$this->inError() )
    {
      if( isset( 
$this->CommandWord ) && in_array$this->CommandWord$this->Valid_Command_Words ) )
      {
        
$return_value true;
      }
      else
      {
        
$this->setError__METHOD__ ' detected empty or incorrect CommandWord in $Sentence property.');
      }
    }

    return 
$return_value;
  }
}


/* ***** EXAMPLES ********* */

//Two valid GPS NMEA Sentence Strings
$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';

//
$oGPS_NMEA_Sentence = new GPS_NMEA_Sentence;

$oGPS_NMEA_Sentence->setSentence($GPS_Serial_Output_1);
echo 
'<h1>'$oGPS_NMEA_Sentence'</h1>';
echo 
"\n\n<pre>\n";var_dump($oGPS_NMEA_Sentence);echo "\n</pre>\n\n";

$oGPS_NMEA_Sentence->setSentence($GPS_Serial_Output_2);
echo 
'<h1>'$oGPS_NMEA_Sentence'</h1>';
echo 
"\n\n<pre>\n";var_dump($oGPS_NMEA_Sentence);echo "\n</pre>\n\n";

$oGPS_NMEA_Sentence->setSentence($GPS_Serial_Output_3);
echo 
'<h1>'$oGPS_NMEA_Sentence'</h1>';
echo 
"\n\n<pre>\n";var_dump($oGPS_NMEA_Sentence);echo "\n</pre>\n\n";



//Make a new empty GPS NMEA Sentence Object
$brandNew = new GPS_NMEA_Sentence();
//Set some properties on it and write the sentence property
$brandNew->setLatitudeHemisphere('E')->setLongitudeHemisphere('S')->writeSentence();
//dump out the object to see what it looks like
echo "\n\n<pre>\n";var_dump($brandNew);echo "\n</pre>\n\n";
//echo the sentence property
echo $brandNew->getSentence().'<br />';
//Make a new sentence with the otput string of the original to see if it validates
$testingBrandNew = new GPS_NMEA_Sentence($brandNew->getSentence());
//Dump it and see what we got
echo "\n\n<pre>\n";var_dump($testingBrandNew);echo "\n</pre>\n\n";