Recently there was a posting on the CakePHP mailing list from someone complaining that CakePHP’s native web service support didn’t work, mainly because he couldn’t figure out how to get it to work. So, I took up the challenge and sent out an email to the list showing that you can indeed use them. Might I add that until I tried this, I had never built a web service with CakePHP before. I found that by turning on the debug mode and actually following the instructions that were in the error messages (best undocumented feature of CakePHP if you ask me) I was able to build it. Oh yeah, a big shout-out to Samuel DeVore for his near-simultaneous reply to the original message showing an ever simpler example than mine. Which I promptly stole and used it in this example. :)
This example works with the latest stable version of CakePHP (1.1.10.3825) running on a Gentoo Linux box with PHP 5.1.2 and Apache 2. It’s my understanding that the native web service stuff was originally built for Cake 1.2 (not released yet) and back-ported to Cake 1.1. Perhaps some key parts are missing, hence the need for some hackery mentioned below.
First, open up /app/config/core.php and turn on support for internal web services:
1
2
3
4
5
/**
* The define below is used to turn cake built webservices
* on or off. Default setting is off.
*/
define('WEBSERVICES', 'on');
Now, you have to understand that CakePHP won’t magically spit out your content as XML, or SOAP, or as REST or whatever. The internal web services support provides built-in URLs for spitting out your content in whatever alternate format you want. This concept will become clear as we continue on here. Basically it lets you do the following:
- mydomain/controller/action for regular content
- mydomain/xml/controller/action to spit out your content formatted as XML
Okay, so first thing I did was create a test controller:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/**
* Test controller for built-in web services
*
* @author Chris Hartjes
*
*/
class TestController extends AppController
{
var $name = 'Test';
var $uses = "";
var $components = array('xml');
function index()
{
$message = "This is a test of built-in web services";
$this->set('message', $message);
}
}
?>
You need to create an XML component and put it in /app/controllers/components/xml.php
1
2
3
4
5
6
7
8
<?php
class XMLComponent extends Object
{
// Blank for now as we're not doing anything weird
}
?>
1
2
3
4
5
6
7
8
<?php
class XmlHelper extends Helper
{
// blank for now
}
?>
Now we need to generate a bunch of thtml files to display our output. Of course, we have to create the default view for our action in the controller. Put this in /app/views/test/index.thtml
1
2
Content generated via regular view<br />
< ?php echo $message ?>
1
< ?php echo $content_for_layout ?>
1
2
3
4
< ?php e('<?xml version="1.0" encoding="utf-8" ?>' . "\n"); ?>
<foo>
<bar>< ?php echo $message ?></bar>
</foo>
So, now when we go to mydomain/test we get the following output generated:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CakePHP Web Services Test</title>
<link rel="stylesheet" type="text/css" href="/css/cake.generic.css" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head>
<body>
<div id="container">
<div id="content">
Content generated via regular view<br />
This is a test of built-in web services </div>
<div id="footer">
</div>
</div>
</body>
</html>
1
2
3
4
<?xml version="1.0" encoding="utf-8" ?>
<foo>
<bar>This is a test of built-in web services</bar>
</foo>
Like I said before, a lot of hoops to jump through and hopefully those go away when CakePHP 1.2 comes out.