Welcome to my newest tutorial – using PHP to get your latest online Fifa results which you could post on your social networking sites, put on your website (like I have at the top of my sidebar) or even create online friendship leader boards and such like.
So, how did I achieve this? I can tell you first off that it requires no direct interaction with the EA or PS3 servers, but uses something much more simple.
Before we do anything you first need to check that the relevant PHP modules are installed on your server. If you use XAMPP as a local testing server then the most recent version (1.7.7 at time of writing) comes with everyone installed as default. The PHP module that you need is IMAP (http://www.php.net/manual/en/book.imap.php). You can check your installation details by loading up a PHP file containing the function phpinfo(); like so:
<?php phpinfo(); ?>
If the module is indeed installed then you should see something somewhat similar to this:
Image may be NSFW.
Clik here to view.
If you don’t see the IMAP module then you don’t have it installed. Read through the installation guide on the PHP manual website for instructions.
The next step is to go into your online settings on your Fifa 12 game. Unfortunately I only have a Playstation 3 since my Xbox had the red ring of death twice so I can only give instructions for this console. I’m sure the Xbox 360 version is fairly similar though. On the PS3 if you boot up the game then go to Online Modes > My Fifa 12 Online > Online Settings > Match Reports then ensure that Forward End-of-Game Stats is set to Yes. You will now receive match reports by email after every online game you play. We will use PHP to read your emails and then extract the match statistics ready to use. Cool, right?
Now comes the fun part, the development side of things. Open up a blank PHP file in the code editor of your choice. Personally I prefer Adobe Dreamweaver but that’s because I learnt using it and it’s just been perfect for my needs. Call this file something like read_mail.php because this is the script that will do all the leg-work.
It really depends what you want to do with the data which dictates how the script will be laid out. If we assume that the data will be inserted into a database then we can use it freely and at any time we like. With this in mind here is an example table structure:
CREATE TABLE IF NOT EXISTS `fifa` ( `id` int(11) NOT NULL AUTO_INCREMENT, `email_id` varchar(50) NOT NULL, `timestamp` int(10) NOT NULL, `venue` enum('Home','Away') NOT NULL, `opponent` varchar(30) NOT NULL, `result` enum('W','D','L') NOT NULL, `home_team` varchar(40) NOT NULL, `away_team` varchar(40) NOT NULL, `home_score` smallint(2) NOT NULL, `away_score` smallint(2) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 ;
The first line would of course then be the database connection. Anyone who regularly develops using this scripting language will know exactly how to do this and will know the code inside out so I’m not going into considerable detail but here is the basic way of doing it:
<?php // FIFA settings $fifa_username = "YOUR_PSN_HANDLE"; // MySQL database settings - change to suit your settings $database = array ( "host" => "DATABASE_HOST", "user" => "DATABASE_USERNAME", "pass" => "DATABASE_PASSWORD", "database" => "DATABASE_NAME" ); // email account settings - change to suit your details $email = array ( "host" => "EMAIL_HOST", "user" => "EMAIL_ADDRESS", "pass" => "EMAIL_PASSWORD", ); // connect to the MySQL server using the settings provided $db = mysql_connect ( $database['host'], $database['user'], $database['pass'] ); // select the database to connect to mysql_select_db ( $database['database'] ); // array of club words (for later matching strings to club names) - add clubs as required $club_words = array ( "Arsenal", "Chelsea", "Manchester", "United", "City", "Liverpool", "Tottenham", "PSG", "Olympique", "Lyon", "Marseille", "Milan", "AC", "Fiorentina", "Juventus", "Lazio", "Roma", "Ajax", "PSV", "Porto", "SL", "Benfica", "Celtic", "Rangers", "Real", "Madrid", "FC", "CF", "Barcelona", "Valencia", "Inter", "Bayern", "Munich", "Munchen", "München", "Argentina", "Spain", "England", "France", "Holland", "Netherlands", "Germany", "Italy", "Brazil", "Uruguay", "Portugal" ); ?>
The code above simply sets the settings which we will use in the script then connects to the database. You will need to change the bits in capital letters to suit the settings of your database and email account. Again, it is very basic and doesn’t contain any error checking or connection errors. I’m not going into huge detail i’m just aiming to show you how it’s done. You will also see an array of club names. This is used because later on we split the body of the email by each word and some clubs contain two words, such as Real Madrid, FC Barcelona, Manchester United, etc.
The next step is to connect to our email account using the email settings provided into the array. We will also sort the emails that are found in the inbox and count them up ready for use. We do this in the following way:
<?php // connect to the email account using the settings provided $mbox = imap_open ( "{" . $email['host'] . ":143/novalidate-cert}INBOX", $email['user'], $email['pass']); // sort the inbox list of emails by retrieval date - reversed $sorted_mbox = imap_sort ( $mbox, SORTDATE, 1 ); // get the total amount of email messages in the inbox $totalrows = imap_num_msg ( $mbox ); ?>
OK, so we have managed to connect to our database and our email account. Let’s not forgot to close those two connections at the end of the script otherwise we could potentially end up with lots of open connections waiting to be used. Not only will this form an eventually large queue, it could cause slowness, downtime and even affect other websites if using a shared server. Let’s not do that if we can help it. To close the connections stick the following to lines at the end of the script, bearing in mind we are about to add more code before this.
<?php // close the email connection imap_close ( $mbox ); // close the database connection mysql_close ( $db ); ?>
The next lot of code is in a big block because we will begin looping the email messages in our inbox. We will use a simple for loop to do this for each item in the inbox. I have commented each line to walk you through the process but be aware this bit is quite complex due to the pattern matching and string replacing. The basics of the code below is:
- Loop through each email message in the inbox folder.
- Get the email headers so that we have an ID, correct email to open (we only want the EA ones) and also a timestamp of when the email was received.
- Check that the message contains an ID.
- Get that ID found and save it into a variable ($id).
- Pattern match against the subject to see if it contains “now see the stats!” – the generic EA match report subject.
- Get the body content, strip tags and split it down into an easy, manageable block of text.
- Split the list into an array of words from the string.
- Get the timestamp that the email was received on.
- Check whether the game was played at home or away.
- Get the home team’s name and the opponent’s username.
- Get the away team’s name.
- Find out the final score of the match.
- Query if this email record already exists in the database.
- If it doesn’t, insert the record.
<?php // loop through each email message for ( $i = 0; $i <= $totalrows; $i++ ) { // get the message headers $headers = @imap_fetchheader ( $mbox, $sorted_mbox[$i] ); // check that the email message contains an ID (for unique matching) if ( preg_match ( "/id ([A-z0-9\-]+)/i", $headers, $matches ) ) { // retrieve the id that was matched in the expression $id = $matches[1]; // search for an email sent with the subject required (from EA) if ( preg_match ( '/Subject: (.*)/m', $headers, $matches ) && preg_match ( '/now see the stats!/', $matches[1] ) ) { // get the body of the email message and strip any HTML tags to leave us with plain text $body = strip_tags(imap_body ( $mbox, $sorted_mbox[$i] )); // split the string so that we only have a block that we can work on $body = substr ( $body, stripos ( $body, "H=" ), stripos ( $body, "©" ) ); // remove any new line characters $body = str_replace ( "\n", "", $body ); // remove any spaces with a pipe symbol so that we can explode the string by each seperate word $body = preg_replace ( "/\s+/", "|", $body ); // remove the funny characters in the string $body = str_replace ( "=|", "", str_replace ( "=20", "", $body ) ); // get an array of words by exploding by the pipe - also remove blank array elements $items = array_filter ( explode ( "|", $body ) ); // set the array for stats collection $stats = array(); /* BEGIN DATA COLLECTION */ // pattern match for a timestamp (when the email was received) preg_match ( "/t=([0-9]+)/", $headers, $matches ); $timestamp = $matches[1]; // get the venue (home or away) by searching for the whereabouts of the username if ( $items[0] == "HOME" && ( $items[2] == $fifa_username || $items[3] == $fifa_username ) ) { $stats['venue'] = "Home"; } else if ( ( $items[6] == "AWAY" || $items[7] == "AWAY" ) && ( $items[7] == $fifa_username || $items[8] == $fifa_username || $items[9] == $fifa_username || $items[10] == $fifa_username ) ) { $stats['venue'] = "Away"; } // get the opponent played against $stats['home']['team'] = $items[1]; // if the venue is away - get the opponent from the home side of the stats if ( $stats['venue'] == 'Away' ) { $stats['opponent'] = $items[2]; } // check if the word following the club name is also a club word (for clubs with 2 words, like FC Barcelona or Real Madrid) if ( in_array ( $items[2], $club_words ) ) { // append the second word to the club name $stats['home']['team'] .= ' '.$items[2]; // check the venue is away - set the opponent as the next array element because the club name is multiple words if ( $stats['venue'] == 'Away' ) { $stats['opponent'] = $items[3]; } } // loop through each array element - getting the key and the value pair foreach ( $items as $key => $item ) { // check if the current item in the loop is the away team marker if ( $item == 'AWAY' ) { // the name of the away team must be the next element after the away team marker $stats['away']['team'] = $items[($key+1)]; // check for the location of the venue - the opponent must be 2 (or possibly 3) items further on because the team name was after the marker if ( $stats['venue'] == 'Home' ) { $stats['opponent'] = $items[($key+2)]; } // check if the element following on from the club name is also part of the name (like Manchester UNITED or Inter MILAN) if ( in_array ( $items[($key+2)], $club_words ) ) { // if it was also part of the name, append this onto the end of the club name $stats['away']['team'] .= ' '.$items[($key+2)]; // check the location of the venue for the opponent's username if ( $stats['venue'] == 'Home' ) { $stats['opponent'] = $items[($key+3)]; } } } // look for the score marker (the hyphen between 1-0, 1-2, 6-0, etc) if ( $item == '-' ) { // the home team's score must be to the left of this marker - the away team's to the right $stats['home']['score'] = (int) trim($items[($key-1)]); $stats['away']['score'] = (int) trim($items[($key+1)]); } // define the result based on the score line if ( ( $stats['venue'] == 'Home' && ( $stats['home']['score'] > $stats['away']['score'] ) ) || ( $stats['venue'] == 'Away' && ( $stats['home']['score'] < $stats['away']['score'] ) ) ) { $stats['result'] = 'W'; } // check for a draw? else if ($stats['home']['score'] == $stats['away']['score'] ) { $stats['result'] = 'D'; } // else the result must have been a loss else { $stats['result'] = 'L'; } } /* END DATA COLLECTION */ /* BEGIN DATABASE INTERACTION */ // query for this ID in the FIFA database table $query = mysql_query ( "SELECT id FROM fifa WHERE email_id = '".$id."' LIMIT 1", $db ); // check if a record already exists in this table if ( mysql_num_rows ( $query ) < 1 ) { // insert the database record mysql_query ( "INSERT INTO fifa ( email_id, timestamp, venue, opponent, result, home_team, away_team, home_score, away_score ) VALUES ( '".$id."', ".$timestamp.", '".$stats['venue']."', '".$stats['opponent']."', '".$stats['result']."', '".$stats['home']['team']."', '".$stats['away']['team']."', '".$stats['home']['score']."', '".$stats['away']['score']."' )", $db ); } /* END DATABASE INTERACTION */ } } } // end loop ?>
The code above can be quite confusing and difficult to follow which is why I have split it down into steps above. The full, final script can be seen below:
<?php // FIFA settings $fifa_username = "YOUR_PSN_HANDLE"; // MySQL database settings - change to suit your settings $database = array ( "host" => "DATABASE_HOST", "user" => "DATABASE_USERNAME", "pass" => "DATABASE_PASSWORD", "database" => "DATABASE_NAME" ); // email account settings - change to suit your details $email = array ( "host" => "EMAIL_HOST", "user" => "EMAIL_ADDRESS", "pass" => "EMAIL_PASSWORD", ); // connect to the MySQL server using the settings provided $db = mysql_connect ( $database['host'], $database['user'], $database['pass'] ); // select the database to connect to mysql_select_db ( $database['database'] ); // array of club words (for later matching strings to club names) - add clubs as required $club_words = array ( "Arsenal", "Chelsea", "Manchester", "United", "City", "Liverpool", "Tottenham", "PSG", "Olympique", "Lyon", "Marseille", "Milan", "AC", "Fiorentina", "Juventus", "Lazio", "Roma", "Ajax", "PSV", "Porto", "SL", "Benfica", "Celtic", "Rangers", "Real", "Madrid", "FC", "CF", "Barcelona", "Valencia", "Inter", "Bayern", "Munich", "Munchen", "München", "Argentina", "Spain", "England", "France", "Holland", "Netherlands", "Germany", "Italy", "Brazil", "Uruguay", "Portugal" ); // connect to the email account using the settings provided $mbox = imap_open ( "{" . $email['host'] . ":143/novalidate-cert}INBOX", $email['user'], $email['pass']); // sort the inbox list of emails by retrieval date - reversed $sorted_mbox = imap_sort ( $mbox, SORTDATE, 1 ); // get the total amount of email messages in the inbox $totalrows = imap_num_msg ( $mbox ); // loop through each email message for ( $i = 0; $i <= $totalrows; $i++ ) { // get the message headers $headers = @imap_fetchheader ( $mbox, $sorted_mbox[$i] ); // check that the email message contains an ID (for unique matching) if ( preg_match ( "/id ([A-z0-9\-]+)/i", $headers, $matches ) ) { // retrieve the id that was matched in the expression $id = $matches[1]; // search for an email sent with the subject required (from EA) if ( preg_match ( '/Subject: (.*)/m', $headers, $matches ) && preg_match ( '/now see the stats!/', $matches[1] ) ) { // get the body of the email message and strip any HTML tags to leave us with plain text $body = strip_tags(imap_body ( $mbox, $sorted_mbox[$i] )); // split the string so that we only have a block that we can work on $body = substr ( $body, stripos ( $body, "H=" ), stripos ( $body, "©" ) ); // remove any new line characters $body = str_replace ( "\n", "", $body ); // remove any spaces with a pipe symbol so that we can explode the string by each seperate word $body = preg_replace ( "/\s+/", "|", $body ); // remove the funny characters in the string $body = str_replace ( "=|", "", str_replace ( "=20", "", $body ) ); // get an array of words by exploding by the pipe - also remove blank array elements $items = array_filter ( explode ( "|", $body ) ); // set the array for stats collection $stats = array(); /* BEGIN DATA COLLECTION */ // pattern match for a timestamp (when the email was received) preg_match ( "/t=([0-9]+)/", $headers, $matches ); $timestamp = $matches[1]; // get the venue (home or away) by searching for the whereabouts of the username if ( $items[0] == "HOME" && ( $items[2] == $fifa_username || $items[3] == $fifa_username ) ) { $stats['venue'] = "Home"; } else if ( ( $items[6] == "AWAY" || $items[7] == "AWAY" ) && ( $items[7] == $fifa_username || $items[8] == $fifa_username || $items[9] == $fifa_username || $items[10] == $fifa_username ) ) { $stats['venue'] = "Away"; } // get the opponent played against $stats['home']['team'] = $items[1]; // if the venue is away - get the opponent from the home side of the stats if ( $stats['venue'] == 'Away' ) { $stats['opponent'] = $items[2]; } // check if the word following the club name is also a club word (for clubs with 2 words, like FC Barcelona or Real Madrid) if ( in_array ( $items[2], $club_words ) ) { // append the second word to the club name $stats['home']['team'] .= ' '.$items[2]; // check the venue is away - set the opponent as the next array element because the club name is multiple words if ( $stats['venue'] == 'Away' ) { $stats['opponent'] = $items[3]; } } // loop through each array element - getting the key and the value pair foreach ( $items as $key => $item ) { // check if the current item in the loop is the away team marker if ( $item == 'AWAY' ) { // the name of the away team must be the next element after the away team marker $stats['away']['team'] = $items[($key+1)]; // check for the location of the venue - the opponent must be 2 (or possibly 3) items further on because the team name was after the marker if ( $stats['venue'] == 'Home' ) { $stats['opponent'] = $items[($key+2)]; } // check if the element following on from the club name is also part of the name (like Manchester UNITED or Inter MILAN) if ( in_array ( $items[($key+2)], $club_words ) ) { // if it was also part of the name, append this onto the end of the club name $stats['away']['team'] .= ' '.$items[($key+2)]; // check the location of the venue for the opponent's username if ( $stats['venue'] == 'Home' ) { $stats['opponent'] = $items[($key+3)]; } } } // look for the score marker (the hyphen between 1-0, 1-2, 6-0, etc) if ( $item == '-' ) { // the home team's score must be to the left of this marker - the away team's to the right $stats['home']['score'] = (int) trim($items[($key-1)]); $stats['away']['score'] = (int) trim($items[($key+1)]); } // define the result based on the score line if ( ( $stats['venue'] == 'Home' && ( $stats['home']['score'] > $stats['away']['score'] ) ) || ( $stats['venue'] == 'Away' && ( $stats['home']['score'] < $stats['away']['score'] ) ) ) { $stats['result'] = 'W'; } // check for a draw? else if ($stats['home']['score'] == $stats['away']['score'] ) { $stats['result'] = 'D'; } // else the result must have been a loss else { $stats['result'] = 'L'; } } /* END DATA COLLECTION */ /* BEGIN DATABASE INTERACTION */ // query for this ID in the FIFA database table $query = mysql_query ( "SELECT id FROM fifa WHERE email_id = '".$id."' LIMIT 1", $db ); // check if a record already exists in this table if ( mysql_num_rows ( $query ) < 1 ) { // insert the database record mysql_query ( "INSERT INTO fifa ( email_id, timestamp, venue, opponent, result, home_team, away_team, home_score, away_score ) VALUES ( '".$id."', ".$timestamp.", '".$stats['venue']."', '".$stats['opponent']."', '".$stats['result']."', '".$stats['home']['team']."', '".$stats['away']['team']."', '".$stats['home']['score']."', '".$stats['away']['score']."' )", $db ); } /* END DATABASE INTERACTION */ } } } // end loop // close the email connection imap_close ( $mbox ); // close the database connection mysql_close ( $db ); ?>
Believe it or not this is actually only pulling the basic information such as home team, away team, venue, opponent, the score and the result. The script I use is even more complex and pulls the possession percentages for each team, passing accuracy, tackling, shots (on and off target), cards (reds and yellows) and lots more.
You can also download the final code here. I hope this was readable enough and any problems, questions or nags you have can be posted below in the comments section.