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:
-
/**
-
* The define below is used to turn cake built webservices
-
* on or off. Default setting is off.
-
*/
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:
-
?php
-
-
/**
-
* Test controller for built-in web services
-
*
-
* @author Chris Hartjes
-
*
-
*/
-
-
class TestController extends AppController
-
{
-
var $name = 'Test';
-
var $uses = "";
-
-
function index()
-
{
-
$message = "This is a test of built-in web services";
-
$this->set('message', $message);
-
}
-
}
-
-
?>
Those of you who are observant about CakePHP will notice that I've dragged in a component to be used. Currently, you need to create a component *and* a helper to make the web service stuff work. This is hackish, and hopefully goes away.
You need to create an XML component and put it in /app/controllers/components/xml.php
-
<?php
-
-
class XMLComponent extends Object
-
{
-
// Blank for now as we're not doing anything weird
-
}
-
-
?>
and then create an XML helper, placing that in /app/views/helpers/xml.php
-
<?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
-
Content generated via regular view<br />
Next is the XML stuff. There are two files we need to create. One is /app/views/layouts/xml/default.thtml, which simply tells CakePHP to use whatever data is passed into it.
and then we create /app/views/test/xml/index.thtml to spit out our data in XML
-
<?php e('<?xml version="1.0" encoding="utf-8" ?>' . "\n"); ?>
-
<foo>
-
<bar><?php echo $message ?></bar>
-
</foo>
I believe the e(blah) function is a built-in helper for CakePHP.
So, now when we go to mydomain/test we get the following output generated:
-
<!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">
-
<title>CakePHP Web Services Test</title>
-
<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>
and when we go to mydomain/xml/test we get the following output generated
-
<?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.


e(blah) is a shortcut for echo from cakePHP's global functions
you can find some more fun ones at http://manual.cakephp.org/chapter/constants
Sam D
Hey Sam, thanks for pointing that out. I just didn't know where to look to find that info.
Chris Hartjes' Blog: Using CakePHP?s Native Web Service Support
Hm, why do you create XMLComponent and Xmlhelper?
Hi Daniel,
I created XMLComponent and XMLHelper because CakePHP 1.1x complains that they don't exist if I try to use the built-in web services support. As mentioned in the post, Sam thinks that this requirement will go away in 1.2x
It is my bad, I should have read it more carefully
Excellent post. This is just what I was looking for.
I had figured out the part about the dummy helper and component, but then I started thinking "this can't be right" but alas, you have verified it.
Best regards,
Noah
It helps (at least in Firefox) to set the content type header as follows:
$ cat app/views/layouts/xml/default.thtml | nl
1
Oops, didn't escape my HTML:
$ cat app/views/layouts/xml/default.thtml | nl
1 <?
2 // this just tells Cake to spit out whatever data is passed to it
3 header('Content-type: text/xml;');
4 echo $content_for_layout; ?>
One thing I bumped into: when You globally defined layout in AppController (to override layout in all controllers, in my case $layout='f') You should create /views/layouts/xml/f.thtml instead of .../default.thtml. (with this little mistake Cake won't suggest what layout is missing - it gets confused).
Cheers
ps. Thanks for that little tutorial - its really helpful
Thanks !!
I am new in cake .
I want to show CJ 's coupons. How will i do it in cake 1.1v ?
@subham
I would recommend moving up to Cake 1.2 now that it is final, as web service support has gotten even better. I don't know if any of this would work in 1.1 anyway as I haven't used 1.1 in more than two years.
I tried this sample but doesnt seem to work for me.. I get this error XMLController not found error.
Can someone help?
Thanks,
Bharani