Announcing Landmark jQuery Plugin That Will Alter the Face of the Internet
CakePHP Digest #10 - News Overload
News
CakeFest #3
The long awaited end to the CakeFest trilogy has finally been announced (don't worry, I'm sure there will be a prequel). The fun takes places in Germany this time, from July 9th to the 12th. CakeFest is divided into two parts. The first two days are for workshops (499€). The second part is the conference (199€). Put a badge on your website and you could get in to that for free. Proposals for talk at the conference are being accepted right now. Edit: I completely botched this sections in my two attempts.
New Cake 1.2 Released and Even Newer Cake 1.3 In Development
There is a new release of the 1.2 branch, which fixes a bunch of bugs. Also 1.3 is now rolling, with development moved over to Git and located at TheChaw. You can also check out the various branches that are in progress at the moment.
Within 24 hours of the announcement we had the first "Would you recommend us to use 1.3 for new development?" question. To save the Cake devs the trouble of having to answer this question repeatedly over the next few months I will provide an answer here that can be copied and pasted:
Yes, absolutely. CakePHP 1.2 is legacy at this point and won't receive any new features. All the cool development is happening on 1.3. In addition to any new development, you should port all your old projects over immediately, starting with the large mission critical ones.
Proving that only 99.99999% of people on the internet are douches, Nate was able to get the @cakephp Twitter account simply by asking. So if you prefer your Cake news in "instant" format, rather then "digest" format feel free to follow @cakephp. Thanks for cutting the legs off this blog post @cakephp...bastards.
Tickets and Commits
If you enjoy bug comment humor (and who doesn't?), check out this ticket (hat tip: @renan_saddam). Speaking of geek jokes, am I the only one who loves flow chart humor? Like this one of Ice Cube's "Today Was a Good Day", which kills me everytime.
In The Wild
edfriedland.com
Only a couple of new sites for this digest. First is edfriedland.com (via twitter), which is the site of bassist Ed Friendland, who presents the important question: If I'm writing my thoughts, isn't that technically quoting my brain and therefor shouldn't everything I write begin with a quotation mark?
davyvandenbremt.be
Also from Twitter is the home page of Davy Van Den Bremt, which promotes his Drupal development skills. I'll pause a moment for you to ponder that.
In The Blogs
Mini Cookbook
You know when you're at a coffee shop and you see a hot girl sitting in the corner trying to finish an important Cake app, only the wifi is broken and she can't pull up the CakePHP manual to figure out how ACL works? And she just wants to be done so that she can get blasted and hook up with some random guy and you're thinking "I'm a random guy." If only you had access to the Cookbook on your handheld mobile device. Thanks to m3nt0r you will never miss one of these opportunities again. The mobile version of the Cookbook works best on the iPhone, which is fine because if you're sporting anything else you don't really have a shot with that chick anyway.
Whitelist vs Blacklist
If you ever thought to yourself "man, I wish there was a series of blog posts covering the best way to implement field blacklisting in CakePHP's Model::save," then this is your week. First up is teknoid's quick way. m3nt0r countered by moving the functionality into AppMode by overriding the default save call. But that approached changed the parameters for Model::save, so cakebaker presented another approach showing how it is done in Rails.
Reverse Routing Cache
In a continuation off a couple of posts mentioned in the last digest, Renan Gonçalves posted a modified version of my code. If only one of us had commit access and could sneak this into the core code...
In The Groups
Summer of Everything But CakePHP
CakePHP was submitted as a mentor for Google's Summer of Code, but didn't make the cut. 150 projects were accepted, including the Derek Zoolander's Center for the Study of Complex Systems and Stuff. My favorite part of their description is "Note that we prefer students who will work on the project "above and beyound" the minimal agreed amount of effort..." Apparently "above and beyound" doesn't involve using spell check. And before you bitch at me for nitpicking this as a typo, note the "i" between the "o" and the "u" on your keyboard.
Uses
I thought this thread was interesting mostly for Miles J's statement that having poor performance from multiple models in a controller "only applies if you have like 10+ models in the $uses var." Look for a future post where I put this to the test. Mostly to make up for the fact that I completely wiffed and didn't mention $uses in my 8 Ways to Speed Up CakePHP Apps post.
In The Bakery
I'm pretty sure there wasn't anything new and if there was it must have not have been very interesting.
I'm Out!
Don't forget to subscribe to my feed or follow me on twitter.
As always if you think I missed something leave a comment. Or if you do something interesting and want it included in the next digest, send me an email.
8 Ways to Speed Up the Performance of CakePHP Apps
Intro
It's a not so well kept secret that CakePHP is slow. What isn't well know is that this is done by design. I could get in a lot of trouble by revealing this, but I'm willing to take that risk. I have records, a paper trail a mile long, showing members of the Cake dev team investing heavily in the stock of Dell, IBM, Cisco and other server companies. We've all heard the expression "hardware is cheap, and programmers are expensive." The Cake team figure out how to monetize that by making a framework that is fast to develop with, but slow to run. They want you to throw more hardware at it. Ingenious, right? Well I'm here to end all of that. Every time you use one of the tips in this article it's one less gold chain on the neck of a Cake developer.
Notes
- I assume you're already using the ContainableBehavior and have optimized+indexed your SQL queries.
- I used ab to benchmark each of these changes and compared to the base benchmark, which is the plain app with debug at 0. I'm not including the actually benchmark numbers since they will vary by the application and the machine. Instead I'll include the approximate change in terms of percentage increase.
- No, you can't see my sample app.
1) Set Debug to 0
A no brainer, right? Well there are plenty of posts on the google group that say otherwise. Before even thinking about tuning your Cake app make sure debug is 0.
Here's the difference. For the Cake engine to run it generates two cache sections.
The first is /tmp/cache/models. In there you'll find a file for every model your system containing the table schema. You know those "DESC table;" queries you see in the query output? That's what there for. Those queries go away when debug is 0.
The seconds cache is /tmp/cache/persistent. There are a couple different files in there that are used by Cake when running your app. The one that generally causes the most slow down to generate is cake_core_file_map. This file stores the paths to various classes in your app. To build the file Cake does a logical, but still time consuming, search of your directory tree looking for the right file.
So what is the difference between debug 0 and debug >0. Oh, about 2.73517104 years. When debug is >0 the cache lifetime on these files is 10 seconds. Switching debug to 0 pushes the expiration to 999 days.
<tangent>
This actually brings up an important question: if something is a "no brainer," do the people that still don't do it have less then no brain? If people without brains still figured it out, are there people walking around with black holes where there brain would be. Am I in danger of having my brain pulled into it, like light when it's slips past the event horizon?
</tangent>
Approximate Increase
+80% to 100%
2) Cache your slow queries/web service requests/whatever
The Cake cache lib is a great tool for caching single parts of your application. It handles all the gory work of writing to a file or tying into a memory based caching engine. All you need to do is figure out what to cache.
Let's say you have a query that has been indexed and optimized, but is still too slow. The Cookbook provides an example of how to wrap it with the cache lib so that you don't need to run it every request.
Or if you have a part of your site that is filled with data returned from a web service, like a recent tweets block (not a great example, since most of the Twitter widgets are JavaScript, but roll with me here). There really is no reason to make the call to the web service on every request. Just wrap it with the cache lib like the above example.
Approximate Increase
+0% to 1000000% Really depends on your app and what your caching.
3) View Caching
Think of this as entire page caching. The Cookbook covers the basics and since rendering the page still runs through PHP there is some flexibility for maintaining dynamic parts of the page. For example, if you were running a store you could cache the product pages, but still have a block showing the user's shopping cart.
Note
There's a section in the Cookbook mixed in here that covers the various caching engines CakePHP supports. However, at the moment (1.2.1.8004) view caching uses file based caching and is independent of the cache library described in #2 .
Approximate Increase
+130% to 160%
4) HTML Caching
This one is my own creation. It's based on the same principal of the Super Cache for WordPress. Basically it takes the rendered page and writes it to your webroot as straight HTML. The next time the page is hit your web server can serve it directly without even having to go to PHP.
There are obvious limitations for this, such as no dynamic content on the page, and the cache won't be automatically cleared. Still it's great for things like RSS feeds or something like popurls where the anonymous viewers all get the same page.
Approximate Increase
~60000% - This isn't hyperbole, that's the real increase.
5) APC (or some other opcode cache)
Wikipedia describes APC as "a free, open source framework that optimizes PHP intermediate code and caches data and compiled code from the PHP bytecode compiler in shared memory." Whatever. It makes shit fast. And you don't have to change any of your code. Fuck yea. Where do I sign up, right?
Approximate Increase
+25% to 100%
6) Persistent Models
This one isn't mentioned in the Cookbook (I'll add it in the next few days if no one beats me to it. I put it on my todo whiteboard, right below "figure out why putting computers in the clouds is more efficient then their traditional ground based counter parts"). This one is simple to turn on. In your controller (or AppController) add the attribute:
var $persistModel = true;
After a page refresh you'll notice two new files in /tmp/cache/persistent for each model included in the controller. One is the cache of the model and the other is a cache of the objects in the ClassRegistry. Like view caching mentioned above, this cache can only be saved on the file system.
Approximate Increase
+0% to 200%
How much this one helps depends on your application. If your controller only has one model and it isn't associated with any others you're not going to see much of a boost. In my demo app there was around 100% increase. There was one model in the controller, which was associated with 3 other models, which had associations of their own.
7) Store The Persistent Cache in APC
To turn enable this you need be using APC and set your "_cake_core_" cache to use APC. In your core.php put:
Cache::config('_cake_core_', array('engine' => 'Apc',
'duration'=> 3600,
'probability'=> 100,
));
This takes the cache files normally stored in /tmp/cache/persistent (not including the persistent models) and stores them in memory.
Approximate Increase
~25%
This is a hard one to measure. I tried enabling APC without opcode caching to measure just this change, but never found a setting that didn't provide a speed bump over the base setup.
8) Speed Up Reverse Routing
There are two methods for doing this. The first is described in a post by Tim at Debuggable.com. Tim's method only works for certain link types and breaks the reverse routing feature. Mine uses caching and made it to Hollywood week of CakePHP Idol where Nate (the Simon of the core team) called it "clever", but it was ultimately sent home when it forgot the lyrics to Kansas' "Dust in the Wind." Yes, I'm drinking and watching American Idol as I write this.
Approximate Increase
~50%
Like all of these tips, the actual increase depends on your app. If you don't use many custom routes and don't have many links on your page your not going to see much of a benefit.
The End
It's up to you now. Figure out which of these works best for you. Go forth and produce speedy CakePHP apps.
Wait, One More Thing
I'm sure I missed something. Leave your best tips in the comments. If I get enough I'll make a second post and claim credit for myself.
Watch Me Sign Up For Slicehost...The Boringest Screencast Ever
I'm telling you now that this is terribly boring. Don't watch it for the content. I would appreciate some comments on the screencasting part. How does it look? Is the audio too soft/high? What annoyed you more: my excessive "ums", "uhs", or "ahs"?
I'm going to shoot for some more interesting screencasts in the future and I have a pretty good post (almost) ready to go for tomorrow. But for now...
CakePHP Digest #9 - The One Where I Steal Everyone's Ideas
News
CakePHP 1.1 API
Awesome news for you Cake 1.1ers. You haven't been forgotten about . Just like all us Cake 1.2ers you have a brand new API...fine...I know it's the same 1.1 API from before, that disappeared for awhile, but is back now. I was just trying to make the devs stuck working on 1.1 apps feel better. Now they're all listening to "Light A Match" by The Beautiful Mistake on repeat.
Tickets and Commits
/pages/home
The issue mentioned in the last digest, where the default home page (/pages/home) may be accessible, was fixed. This doesn't help the 5.32 million Cake apps that are already released (figure may not be accurate), but going forward this won't be an issue anymore. @snookca commented that he "should use it to build a secret page just for the curious." I think this is a great idea. For those of us that don't use /pages/home for anything, let's start sneaking Easter Eggs in there for other Cake devs to find. You may be putting your job at risk, but there are some things more important than steady income and dammit this is one of them.
XSS Vulnerability
Another important change was the patch to fix a XSS vulnerability in the paginator helper (#6134). I'm still waiting for the moment when hack TV writers pick up the terms XSS or XSRF and use it as technobabble. Something like:
Jack: Come on Chloe, we're running out of time. They're through two subnets with the CIP device.
Chloe: I'm trying but the server is locked down with redundant firewalls. I think I can hack a backdoor node with an XSS attack.
Of course if this were to ever happen within two minutes this entry would appear on F*** My Life:
Today, I realized I've wasted my entire career trying to inform people on the importance of web security. I don't think anyone is listening. FML -- Chris S.
In The Wild
Just one site to mention this week: justrosters.com, a slick looking staff scheduling tool by the team at Marvel Internet Group. I was going to use this site to schedule which of my harem are on duty at any given moment, but then I realized that they're all on call 24/7 and this would just give them the false hope that they actually had time off.
In The Blogs
Rails Envy
CakeBaker pointed out a cool feature in Rails that allows you to install plugins directly from a Git repository. Seriously, do not blog about something and expect me to not to steal it. I just can't help myself. I spent an hour with Wireshark trying to reverse engineer the Git protocol so I could make this work for CakePHP. Finally I got smart and went to the Rails code to see how they did it, only to find that Rails is just running system, calling the command line git client. Weak.
More XSS
You can't get away from the XSS. @brian_dailey pointed out this article about how addons.mozilla.org combats XSS attacks.
Do Not Leave Your Door Unlocked - I Will Clean Out Your House
I told you I can't not steal blog ideas. Tim posted this article about avoiding the router when using $html->link() and how it can save up to half a second. Shortly after I took another shot at achieving the same goal using caching.
The ACL Beast
Neil Crookes posted a query that will grab all the ACL permissions at once. Be warned, this query is not for the faint of heart. It feeds on three whole cows a day and has already killed one handler. I swear as soon as I read Neil's article I went to work on another solution to this problem. I actually have it pretty well sorted out, but decided not to release it because I've already stolen like three of Neil's posts and didn't want to make that last step to being 100% of a dick. I'm content hanging out in the 95%-97% range.
Here's another solution by dr. Hannibal Lecter. Probably better then my half-assed attempt linked in the comments.
Everyone together: "requestAction, we are sorry we doubted you"
I saved this one for last. Everyone bashes requestAction. It's just a given that using it sucks the life out of any app and those that use it are clueless. Well, Mark Story may have just made us all look like idiots. He took the time to actually benchmark it and it turns out it isn't that bad. I downloaded his sample, checked it over and ran it myself. His numbers hold up pretty well. Is this the programming equivalent of finding out that Verbal Kint is actually Keyser Söze and he's just been playing us all along?
In The Groups
I mention at the beginning of a recent screencast how developers love to talk about their IDEs. Shortly after this tread appeared and ended up with 53 messages. Of the 52 respondents I think there were 47 different IDEs mentioned.
In The Bakery
Star Power
I thought this jQuery star rating code looked pretty good. Although, I'm surprised it was approved, because it literally has nothing to do with CakePHP. Yea, there is a block showing how to create a generice form with the FormHelper, but the entire star rating part is front end jQuery.
Datasource Love
I love datasources. There I said it. Whenever my boss asks me if some code should go in a component, model, controller... I always answer datasource. I now practice the skinny controller, skinny model, fat datasource pattern. It's complete illogical, but do not even try to stop me. Anyway, if your looking to include some Twitter in your app you should probably check out this datasource.
Dropping Logs
I can't say I'm on board with the way this code tries to write the SQL log to a file. If I were going to do it, I'd probably steal the way the DebugKit does it. That way you don't have to change your DB driver and it works more then just one database. I know my version still outputs the SQL at the bottom...cut me some slack. I wrote this in 5 minutes.
I'm Out!
And on that note don't forget to subscribe to my feed or follow me on twitter.
As always if you think I missed something leave a comment. Or if you do something interesting and want it included in the next digest, send me an email.


