Connecting to the Betfair API with php and Bflib

chris (2010-07-25 00:51:21)
13973 views
15 replies

Connecting to the Betfair API with php and Bflib
Updated July 18th 2011

This is the first of a series of tutorials designed to help you get started with writing bots and applications using the Betfair API. These tutorials use the php programming language and make heavy use of the bflib Betfair API library. Before you get started, you will need to download the bflib source code from it's home on github. The project page is here and the 'download source' link is in the top-right, just under the 'search' box.

Extract the source code onto your local filesystem. If your bot/app will have a web front-end, you will need to put the source code into a directory which is accessible from your web docroot. Your bot can run headless - in which case, you can extract the bflib source code into any convenient location.

chris@osx-lx-vm:/export$ tar -zxvf planetguru-bflib-c2b3a8f.tar.gz
chris@osx-lx-vm:/export$ mv planetguru-bflib-c2b3a8f bflib

Now you need to make sure that you update the vendorConstants class file with your own username and password. In the example above, this would be under /export/bflib/classes/vendorConstants.class.php. If you are doing this for the first time, move the vendorConstants.class.php.sample to vendorConstants.class.php and then edit the file so that your username and password are correct and include your vendorId if you have one. If you don't have a vendorId, use the productID 82 and the vendorid 0, as shown below.

class vendorConstants {

	/**
	* bdp developer credentials. You should change the USERNAME and
	* PASSWORD to match your own username and password on betfair.
	* Remember that your account will need to be active, with recent transactions and
	* cleared funds in order for the SOAP APIs to allow you to authenticate
	*
	*/
	const USERNAME     = 'yourusernamehere';
	const PASSWORD     = 'yourpasswordhere';
	const PRODUCTID    = 82;
	const VENDORID     = 0;
	const LOCATIONID   = 0;
	const IPADDRESS    = 0;

	public function __construct(){}
}

Great - now we're all set up to try a very simple app - just to check that your account works. This application is headless, so has no web page or UI. All it does is return all of the top-level event types offered on betfair.

Here is a walkthrough of how I get this app working. First I create a new directory to house my application. I'm going to call it betfair-test:

chris@osx-lx-vm:/export$ mkdir betfair-test
chris@osx-lx-vm:/export$ cd betfair-test/
chris@osx-lx-vm:/export/betfair-test$ mkdir classes
chris@osx-lx-vm:/export/betfair-test$ mkdir cli

Now I am going to create two files. One will be a simple class file for my demo application class. The second will be the executable which I run to actually use the application. The class file should live in the 'classes' directory (created above) under the name testApp.class.php and the executable should live in the 'cli' directory - it doesn't matter what this one is called. First, this is what the source code for the testApp.class.php application class should look like:

<?php
/**
* Test use of the 'bflib' Betfair API connection library.  This just requests a list of 
* top-level event types and displays their names.  This is the simplest of requests which
* can be made against the Betfair API and demonstrates that you have a working connection
*/

class testApp {
        private $context = '';

        /**
        * construct testApp object
        *
	*  @param none
	*  @return none
        */
        public function __construct(){
                /* directly set the 'context' since this mini app isn't going to do anything else */
                $this->context = 'getAllEventTypes';
        }

        /**
        * Instantiate a betfairController object, passing through the 'context'
        * and then grab the soapresponse after the API call is made.
        *
	*  @param none
	*  @return none
        */
        public function run(){
                /* some methods are just page displays and don't need to talk to betfair */
                $this->bflib = new betfairController();
                $soapResult = array();
                $soapResult = $this->scheduleRequest();
                foreach($soapResult->Result->eventTypeItems->EventType as $eventType){
                        print("n".$eventType->name);
                }
        }

        /**
        *  Tell the betfairController class which API verb/method we are going to use and ask it to set up the request object
        *  Then run the controller and  capture the soapResponse object that comes back
        *
	*  @param none
	*  @return none
        */
        public function scheduleRequest(){
                /* set the bflib context as this context */
                $this->bflib->setContext($this->context);

                /* call the bflib->constructRequestData method to set up the soap data */
                $this->bflib->constructRequestData($this->context);

                /* run the bflib->execute and bflib->prepareResponseData requests and capture the soapResult which comes back */
                $soapResponse = $this->bflib->run();

                return($soapResponse);
        }
}
?>

This file needs to be saved in your 'cli' directory with the name betfair-test.

What you see here is really a helicopter view of the basic request cycle which occurs every time a message is sent to Betfair. The betfairController class handles the incoming request from this application class. Based on the context, it constructs arrays of request data, which are then passed into the low-level betfairDialogue class. The controller can also exposes an itemId member variable, which is used to pass in the ID of whatever the thing is you want to perform an action upon.


Some Design considerations

The next version of the bflib library will move away from the itemId principal within the controller, introducing a 'subjects' class, which can represent either an integer ID, or an array of IDs, or a collection of objects. This will allow one/many-to-many type operations to occur (eg bulk bet placement). It's always worth knowing that the itemId/subjects object at the betfairController level is a facade to and object of the same name within the betfairDialogue class. The former provides a home for any business logic around request data preparation and perhaps bubbling back into helper classes within the application framework before passing the assembled request down to the dialogue handler to be sent over the wire.

Now all I need is an executable to instantiate the application class which I have created. It looks like this:

<?php

/**
* Define autoload classpath and require it in.
*
* @param $class The class to be loaded
* @return none
*/
function __autoload( $class ){
	$classpath = '../classes/'.$class.'.class.php';
	if (file_exists( $classpath )){
		require_once($classpath);
		return;
	}
	$classpath = '/export/bflib/classes/'.$class.'.class.php';
	if (file_exists( $classpath )){
		require_once($classpath);
		return;
	}
}

$testApp = new testApp();
$testApp->run();

?>

I included a specific autoload method to point down the two class paths which I'm using for this application. In doing so, I have enforced a convention whereby a class is always found within a file which bears it's name in the format <classname>.class.php. This arguably put a bit more structure around php's potentially shappy management of classnames. It will also feel more familier to folks with a java background.

Something else which is worth knowing is the location of the betfairLogger's log destination. Currently this is set to /tmp/betfair-api-log within the vendorConstants.class.php configuration file. If you are having trouble getting this thing to work, then your log file is a good place to check for error codes returned from betfair. The logger functionality is new and does not yet have a toggle - The platform also doesn't yet watch for specific error codes within an exception handling framework. This is in-plan.

Okay - so now let's run the app and see what we get:

chris@osx-lx-vm:/export/betfair-test/cli$ php -e betfair-test 
PHP Warning:  Xdebug MUST be loaded as a Zend extension in Unknown on line 0

Poker Room
Yahoo Racing
Soccer
Tennis
Golf
Cricket
Rugby Union
Boxing
Horse Racing
Motor Sport
Soccer Euro 2000
Special Bets
Cycling
Rowing
Rugby League
Darts
Athletics
Greyhound Racing
Financial Bets
Snooker
American Football
Olympics - Sydney 2000
Baseball
Basketball
Hockey
Ice Hockey
Sumo Wrestling
Australian Rules
Gaelic Football
Hurling
Pool
Test Only
Chess
2002 Winter Olympics
Trotting
Commonwealth Games
Poker
Winter Sports
Handball
Volleyball
Politics
Bridge
Exchange Poker
International Rules
Table Tennis
Floorball
Netball
Yachting
Swimming
Gaelic Games
Internal Markets
Olympics 2004
Bowls
Bandy
Badminton
GAA Sports
Backgammon
Soccer - Euro 2004
Exchange Roulette
Exchange Blackjack
Fishing
Exchange Casino
Tradefair Test
Cross Sport Accumulators
Featured Markets
Ten Pin Bowling
Exchange Card Racing
Surfing
Canoeing
Equestrian
Water Polo
Fussball
Exchange Omaha Hi
Combat Sports
Olympics 2008
Roller Hockey
Polo
Harness Racing
Pelota
Horse Racing - Virtual
Squash
Futsal
Beach Volleyball
Exchange Hi Lo
Exchange Baccarat
Tradefair
Casino
Mixed Martial Arts
Exchange Gameschris@osx-lx-vm:/export/betfair-test/cli$

And bingo! we have a working connection to betfair's soap endpoint and our first request has worked.

In future articles I will dive into some more complex examples and demonstrations, including price monitoring, bet placement and UI development. I'll come back and link those articles in when they emerge :) Meanwhile, why not check out the Second Tutorial in this series, which focusses on coding a betfair application with market navigation and a simple user interface - Second betfair tutorial here

Follow me on Twitter: http://twitter.com/planet_guru


christo

Digg it! Submit to Slashdot Add to Blinklist Del.icio.us Add to Newsvine Add to Technorati Add it to Google Bookmarks
comment
vlado
2010-07-28 18:06:38

Great class

Cool man, great work, really looking forward to next article.
reply icon
Jose Manuel Villar Alarcon
2010-08-26 00:26:15

Good article

I would like than you contact with me about our API, and the possibility of connect by PHP web services.

this is my email: jmvalarcon@b-markets.com

Regards
reply icon
vlado
2010-09-05 22:19:50

Hi, I just want to ask if you are still working on this, and if so, when do you think next update will be out?

Thanks...
reply icon
chris
2010-09-06 01:12:01

Hi, I just want to ask if you are still working on this, and if so, when do you think next update will be out?

Thanks...


Hi Vlado

Yes, I'm still working on this - planning another update during the next week or so, which will demonstrate how to put a front-end onto your application


reply icon
vlado
2010-09-06 01:43:58

Hi, I just want to ask if you are still working on this, and if so, when do you think next update will be out?

Thanks...


Hi Vlado

Yes, I'm still working on this - planning another update during the next week or so, which will demonstrate how to put a front-end onto your application




Cool, really looking forward for update!
reply icon
chris
2010-09-08 03:55:36

Second betfair application tutorial here
reply icon
peter
2010-10-17 19:06:15

Error Msg

Hello,

when running the test PHP file it tells me:

peter@pc5:~/work/bflib/cli$ php test.php

PHP Fatal error: Cannot access private property betfairController::$context in /home/peter/work/bflib/classes/testApp.class.php on line 48

I copied your two files and only changed my login credentials. Whats going wrong here?

Thx, Peter
reply icon
chris
2010-10-18 20:44:02

Hello,

when running the test PHP file it tells me:

peter@pc5:~/work/bflib/cli$ php test.php

PHP Fatal error: Cannot access private property betfairController::$context in /home/peter/work/bflib/classes/testApp.class.php on line 48

I copied your two files and only changed my login credentials. Whats going wrong here?

Thx, Peter


Hi Peter..

I'll get back during this week. I'm pretty stacked at the moment. If you manage to fix it in the meantime, feel free to comment back.

thanks

reply icon
Josef Kindermann
2010-11-18 18:58:16

sam problem

Hello,

when running the test PHP file it tells me:

peter@pc5:~/work/bflib/cli$ php test.php

PHP Fatal error: Cannot access private property betfairController::$context in /home/peter/work/bflib/classes/testApp.class.php on line 48

I copied your two files and only changed my login credentials. Whats going wrong here?

Thx, Peter


i got the same problem. Running this script online on my provider's webserver.
Greetings
reply icon
chris
2010-12-19 04:02:13

Resolved

That error is now resolved. I have updated the article to reflect a small change in the testApp.class.php file. You will also need to download the bundle again, because there is a small change in the bflib/classes/betfairController.class.php file.

Have fun.


reply icon
klabor
2011-04-05 21:10:18

klabor bee utility - easy to use client for betfai

It's great article Chris!
After reading it I've decided to build command-line utility klabor bee which give
possibility communicate with betfair datafeed from command-line without programming.

Possibly it will be interesting as well. More info on klabor.com
reply icon
Hugo
2011-07-25 22:22:39

Doesn't work for me

I can't get this example runnig on my computer. I've tried a lot of ways but still doesn't work.

I've tried to put all the files in the /var/www/bflib and run it in firefox and still not working.

Any help?
reply icon
chris
2011-07-27 19:37:09

I can't get this example runnig on my computer. I've tried a lot of ways but still doesn't work.

I've tried to put all the files in the /var/www/bflib and run it in firefox and still not working.

Any help?


Yes - you have used different paths to the ones given in the example. If you are placing the bflib bundle under /var/www, then you will need your testApp.class.php to reflect that in the paths is searches within the autoload method. That means you probably need to add a section like this:

$classpath = '/var/www/bflib/classes/'.$class.'.class.php';
if (file_exists( $classpath )){
	require_once($classpath);
	return;
}


Hope that helps

reply icon
anonymous
2011-07-28 04:42:03

Hi Chris

I have followed your instructions and test run betfair-test.php and I received this error message:

Fatal error: Maximum execution time of 30 seconds exceeded in C:\wamp\www\bf\classes\betfairDialogue.class.php on line 116

What it means? How to solve this problem. Thanks in advance.

Regards,
Kevin
reply icon
Kevin
2011-07-28 04:57:00

Undefined variable: sessionToken

Hi Chris,

After I run betfair-test.php, I got this error message:

Notice: Undefined variable: sessionToken in C:\wamp\www\bf\classes\betfairController.class.php on line 56

Fatal error: Call to undefined function apc_fetch() in C:\wamp\www\bf\classes\betfairCache.class.php on line 56

I have installed apc.dll already, how to solve this problems?

Thanks.
reply icon