During our early phases with WePay, we’re considering development using a framework such as CakePHP. I’m not fundamentally opposed to using frameworks, but it’s important to understand the tradeoffs. They’re a good way to get up and running quickly, but you’re forced to use certain conventions that may or may not be good - and due to the way that most work, you’re usually making a massive tradeoff from performance to get up and running quickly (I think it should be obvious to developers why every page load running an EXPLAINDESCRIBE query that’s cached for no more than thirty seconds should be somewhat of a performance concern). While I may tend to err on the side of premature optimization, there are still some things that just violate best practices. Web apps like PHPMyAdmin using EXPLAINDESCRIBE on every page load makes perfect sense, that tends not to be the case on a web app that you’d like to see scale out to millions of users eventually (Hi, Twitter!).
(Yes, I know that there are caching adjustments you can make in order to negate this once your main app development is done. Fixing performance can be relatively easy if you know what you’re doing, or at least know where to look. But is it wrong to be nervous about variables being that dynamic? I think not, though it’s certainly a matter of opinion.)
Anyways, back on topic - one of the main points that Bill brought up in his arguments for using a framework is that it forces us to follow certain coding conventions and standards which should make maintainability less of an issue down the road. A very valid point, and certainly a good way to do things, if the code supports it. However, code conventions and standards aren’t exactly PHP’s strongest point: a very large amount of its core code-base (especially the earlier stuff) is the very definition of inconsistency and esoteric naming conventions. Is it array_search($needle, array $haystack) or array_search(array $haystack, $needle)? What about array_keys($search_value, array $array) vs array_keys(array $array, $search_value)? (The former, then the latter). How about the approximately 183 different string manipulation functions, each of which following some sort of C naming convention under the assumption that a function name that made sense would call sudo rm -rf /.
Don’t get me wrong - it’s still a very powerful language for what I do on a daily basis, and any real limitations I’ve encountered have been on my end rather than PHP’s. It just means that even after working with it for nearly a decade, I still have to hit the documentation much more often than seems natural (granted, if TextMate had a more powerful syntax completion engine (CodeSense, IntelliSense - whatever you want to call it), this would largely be a non-issue; I hear that’s coming in TextMate 2.0 but that’s beside the point). Thankfully, most of the newer built-in functionality follows some sort of logical naming conventions.
Back to frameworks. It makes sense on the surface, right? Define a model as class somename extends AppModel in models/somename.php, define your controller methods as class SomenamesController extends AppController and function action() in controllers/somenames_controller.php, and your views as viewname.ctp in views/somename/, and let the built-in routing functions figure out what gets called where, when, and how. The issue is that while you should follow naming conventions, you don’t really have to in order for things to work properly.
Wait, what?
Why would one even describe naming conventions if you don’t have to follow them? “Hi, there. I’d really prefer if you did things my way. It doesn’t take you any extra effort whatsoever. But if you really feel the need to go off and do it your own way, I don’t mind wasting a ton of time trying to figure out what the hell you were thinking and do it your way.”
Yeah, that doesn’t seem to make sense to me either. I suppose that really is the PHP way - let people know how they should do things, but try to recover from things if the programmer needs to defy conventions. It’s just too damn forgiving. Coders are used to fixing mistakes - trigger a program-aborting error and make them fix the mistake, rather than issue a (hidden by default, in most installations) warning and continue on your merry way.
I’d like to briefly examine CakePHP’s Controller::set (cake/libs/controller/controller.php:652) method here, as it so clearly illustrates the issue.
function set($one, $two = null) {
$data = array();
if (is_array($one)) {
if (is_array($two)) {
$data = array_combine($one, $two);
} else {
$data = $one;
}
} else {
$data = array($one => $two);
}
foreach ($data as $name => $value) {
if ($name === 'title') {
$this->pageTitle = $value;
} else {
if ($two === null && is_array($one)) {
$this->viewVars[Inflector::variable($name)] = $value;
} else {
$this->viewVars[$name] = $value;
}
}
}
}
Shall we step through things? A typical function, accepting two arguments, the latter being optional. It’s used to make variables available to views without excessive futzing with scope and digging into object properties (by use of the extract function). Makes enough sense. It’s basically just building an associative array. My issue here is that its excessive flexibility on inputs is unnecessary, adds complexity, and reduces the need to follow any one set of conventions. In fact, it allows three: set($key, $value), set(array $keys, array $values), and set(array $associativeArray). Each are valid (less so on the second of the three, IMO), but the mere fact that three are allowed is my major concern. Either of these approaches seems far better:
function set($key, $value) {
$this->viewVars[$key] = $value;
}
or
function set(array $associativeArray) {
foreach ($associativeArray as $key => $value) {
$this->viewVars[$key] = $value;
}
// Alternately: $this->viewVars = array_merge($this->viewVars, $associativeArray);
}
Simple, no? The exception with a key of “title” should be processed at runtime by View::_render() (where this data is eventually used) if it deserves an exception at all. Either option forces you to use a SINGLE convention throughout your code, rather than picking from whichever seems the most appropriate of three at any given time.
So, that’s my rant for the day. If you’re going for consistency, be consistent and enforce it. If you’re not going to enforce it, then don’t even claim to require it. It’s one thing if you need to maintain some level of backwards compatibility (though this should ideally be done via wrapper/abstraction methods), but that shouldn’t be the case for frameworks which are built so for sites with a 0-byte codebase. Forcing MVC for site operation is a good thing when appropriate, and I intend to employ a similar approach to what CakePHP has implemented in my own code (albeit through slightly different means).
Writing code in a way that you don’t need to reinvent the wheel is a good thing. But what engineer in his/her right mind would provide three different sets of mounting points for that wheel just because some companies want to use agreed-upon metric bolts while one wants to use a coarse-threaded imperial bolt and one other wants to use a fine-thread of the same diameter. Yes, you can do it - but it will wreak havoc on your structural stability.
And now that the requisite car analogy is out of the way, I’m done. Go outside already, it’s a beautiful day.
Edit: Realized I mistakenly ranted about using EXPLAIN when it should have been DESCRIBE up at the top of the post. Serves me right for not proofreading.
So, I’ve been following along Stanford’s iPhone Development class on iTunes U (iTunes link), and something covered early is how Objective-C allows you to use “dot notation” for getters and setters provided you follow naming conventions: object.propertyName runs the [object propertyName] getter, and object.propertyName = someValue runs the [object setPropertyName: someValue] setter. Tricky, eh?
I wanted something similar in my PHP calls. Of course it’ll be “arrow notation” rather than “dot notation”, but the same concept applies. Naturally, if you have public properties in your object it’s a non-issue, but if you’re like me, all of your properties have a protected or private visibility and are only accessible through getter and setter methods. The reason to do so in my case is very important - my abstracted save() method only makes a database call if $this->hasBeenChanged is true (to prevent unnecessary DB calls, among other things), and all of my setters call the appropriately named $this->markAsChanged() method. If I were to set the values directly through public visibility, this wouldn’t work at all.
But there’s a trick: PHP’s magic methods for getters and setters, __get($var) and __set($var, $value). Here’s where the naming convention thing comes into play: you can use $var passed to the magic methods in order to run the setters through a little string concatenation.
public function __set($variable, $value) {
if (method_exists($this, $method = 'set' . $variable)) {
$this->$method($value);
}
} // function __set
What this does is that when you call $object->someProperty = 'someValue';, PHP first checks to see whether $someProperty exists in the object as a public member, and if so will set the value. Since it’s not, it will call __set('someProperty', 'someValue'); if you have it defined. What we’ve done is define it in such a way that it will attempt to call $object->setsomeProperty('someValue'); if it exists (PHP’s function and method calls are not case sensitive; I do, however, use upperCamelCase for my naming conventions. Thankfully, the lack of case sensitivity here allows us to not worry about capitalizing the first letter of the method name). To shorten things somewhat, I assign a value to $method right in the method_exists() call, since you’re not allowed to run $this->set$variable($value); - you’ll get a fatal error at runtime.
I keep my __get($var) method a little more simple, since I (at least in this project) don’t care if you read the values at random; only writing could be problematic if done wrong. So I keep it as simple as possible here:
public function __get($variable) {
return isset($this->$variable) ? $this->$variable : null;
} // function __get
A little ternary notation combined with the isset() function gets the job done quite easily. However, if you have explicit getter methods, there’s no reason you couldn’t modifiy the above __get($var) code accordingly:
// Objective-C [object property]/[object setProperty:value] notation
public function __get($var) {
if (method_exists($this, $var)) {
return $this->$var();
}
return null; // Or whatever you want the default to be if the property doesn't exist; you could throw an exception here if you prefer.
} // function __get
// My own $obj->getProperty()/$obj->setProperty($value) notation:
public function __get($var) {
if (method_exists($this, $method = 'get' . $var)) {
return $this->$method();
}
return null; // Again, set "fail" value/action to taste
} // function __get
I just switched over to a new theme for the blog: Sharp, available at ThemeForest. A bit snazzier, I think. A few tweaks made, mostly to the code sections. People with newer browsers that support CSS3’s @font-face rule should get snippets in Panic Sans, which I extracted from my copy of Coda, in a slightly smaller than default size and with better overflow handling. I’ll assume everything still looks decent in IE, but I don’t have easy access to a Windows machine and honestly don’t give a damn since I focus primarily on back-end code where I can (and do) set requirements to use standards-compliant browsers.
Now on to a quick tip… PHP coders who also use jQuery might enjoy this. If you’re writing OO PHP and have setters for protected/private class members, use return $this; instead of return true; (or a return-less void) at the end of your setter method. It mimics jQuery’s “chainability” concept by returning the modified object. So you can go from this:
$user->setName('Eric');
$user->setPassword('password');
$user->setStatus('admin');
To this:
$user->setName('Eric')->setPassword('password')->setStatus('admin');
Small change, but I find it a bit more readable and there’s no discernable performance impact. And while I haven’t looked into it in any detail, I’m pretty sure this is (more or less) how PHP’s SimpleXML class works.
Just took delivery of a new LumoPro LP120 strobe - the flash designed by Strobists for Strobists. I’ll probably post more details (and photos!) later, but first impressions:
Features
Nice, compact size. About the same as my Canon 580EX II, significantly smaller than the Vivitar 285HV. The head size is also comparable to the 580EX II, so you should have no problems with using any small-flash accessories - a nice change from the 285’s giant head that doesn’t fit anything properly.
4 triggering methods - awesome. Hotshoe, PC cord, 3.5mm socket, optical slave. Haven’t tested the hotshoe, but the other three all work very reliably so far. No problems with the optical trigger at short range, which is all I’ve tried so far. I expect it’ll mostly be fired by a Paul C Buff CSRB unless I’m out of triggers, in which case I’ll go with the optical trigger.
Head moves 90º clockwise, 180º CCW, 90º vertically. 4 (manual) zoom positions: 28, 35, 50, and 85mm. Like the Vivitar, it doesn’t lock into any of the positions, just clicks into place. 180º in both directions would have been nice, but I don’t envision it being a problem. Pretty much identical movement range as a Canon 430 I think. It also includes a wide-angle diffuser that you can pop in, which I’ll probably lose promptly. (more…)
A quick heads-up for changes I’ve noticed so far when upgrading from jQuery 1.2.6+UI1.5.x to 1.3+UI1.7:
UI.tabs() now expects to be run on a wrapper element containing both the tabs and their respective panels. Previously I would have something like this:
<ul id="nav">
<li><a href="#tab1">Tab 1</a></li>
<li><a href="#tab2">Tab 2</a></li>
</ul>
<div id="tab1">Tab 1 content</div>
<div id="tab2">Tab 2 content</div>
<script type="text/javascript">
jQuery("#nav").tabs();
</script>
Since UI1.7, I need the following structure:
<div id="tabs_wrapper">
<ul id="nav">
<li><a href="#tab1">Tab 1</a></li>
<li><a href="#tab2">Tab 2</a></li>
</ul>
<div id="tab1">Tab 1 content</div>
<div id="tab2">Tab 2 content</div>
</div>
<script type="text/javascript">
jQuery("#tabs_wrapper").tabs();
</script>
Minor change, but previously I had ul#nav in div#top and the panels in div#middle, so I needed to do some minor restructuring for UI1.7 compatibility.
Also another minor tweak: UI.dialog.overlay seems to have been shifted from a settable javascript property to styles in div.ui-widget-overlay that’s created for modal dialogs (perhaps non-modal dialogs as well; I haven’t tested).
Old version:
<script type="text/javascript">
jQuery("#dialog").dialog({
autoOpen: false,
modal: true,
resizable: false,
draggable: false,
overlay: {
background-color:'#000',
opacity:0.75
}
});
</script>
New version:
<script type="text/javascript">
jQuery("#dialog").dialog({
autoOpen: false,
modal: true,
resizable: false,
draggable: false
});
</script>
<style type="text/css">
.ui-widget-overlay {
background-color:#000;
opacity:0.75;
}
</style>
If I find other changes (that don’t appear to be documented at docs.jquery.com) I’ll post them up here.
Quick TextMate snippet for you, this one for dealing with all of the browser-specific CSS3 properties that you have to use because the spec is still in draft form. border-radius comes to mind, as does the border-image property I’ve been playing around with recently. There are tons more; check out www.css3.info for details.
I have the following bound to Tab Trigger “-” in TextMate, with the following scope: source.css meta.scope.property-list
-webkit-$1: $2;
-moz-$1: $2;
-o-$1: $2;
-icab-$1: $2;
-khtml-$1: $2;
-ms-$1: $2;
$1: $2;
$0
Very quick and handy way to drop in all of the browser-specific prefixes (that I’m aware of), plus the finalized version for future compatibility, in one fell swoop. -{tab}border-radius{tab}3px potentially gives me a 3px border radius across all browsers, though obviously support is mixed between different browsers and the various properties. As you might expect, the -ms- prefix is almost never used, though it looks like they’ll try to use it for css3 properties still in draft spec in IE8. The good thing with CSS3 is that it’s almost entirely to add graphical flair to a page, so it tends to degrade very gracefully if the property isn’t supported in a browser (as compared to, say, doing absolutely anything in IE6).
Also, this should work fine in e, the Windows TextMate counterpart, as well as any other text editors that support TM’s snippet syntax. Of note, the meta.scope.property-list part of the snippet scope restricts this specifically to the area between braces of an element property, so it won’t fire off anywhere with a CSS scope (embedded in HTML or an external file). Interestingly, there are only a couple of CSS properties in the default TextMate bundle that behave that way; most of the CSS snippets can be triggered even if you’re not in an element’s property list. Oh well.
- Enter your password to view comments
- February 19 2009
Just found out that there’s one more kind of annoyingly long Amazon link, and my previously-posted Applescript to create short affiliate links needed an update. Here’s the excerpt - if you’re using Applescript, you should be able to figure out where it goes.
else if link contains "/detail/-/" then
-- http://www.amazon.com/exec/obidos/tg/detail/-/B00009R6UA/ref=pd_luc_mri?_encoding=UTF8&m=ATVPDKIKX0DER&v=glance
set startLength to the offset of "/detail/-/" in link
set startLength to startLength + 10
set endCutoff to startLength + 9
set asin to the text startLength thru endCutoff of link as text
I won’t go into the details about why get/set methods are handy when doing object-oriented programming in general, but here’s another TextMate snippet that should speed things up when using them in PHP5. Handles the tabbing and camelCasing of method names automatically:
See note below - this has formatting errors
public function set${1/./\u$0/}(\$$1) {
\$this->$1 = \$$1;
return true;
} // function set${1/./\u$0/}
${2:public function get${1/./\u$0/}() {
return \$this->$1;
\} // function get${1/./\u$0/}}
I have my snippet bound to “getset” (tab trigger) in textmate, so getset⇥body will yield the following:
public function setBody($body) {
$this->body = $body;
return true;
} // function setBody
public function getBody() {
return $this->body;
} // function getBody
I also have it configured so that tabbing a second time will highlight the entire getter method, in case you don’t want it available for whatever reason (the code I’m writing has a big getAll-type method and individual getters would be highly redundant). Enjoy :)
Edit - sorry, something’s screwing up the formatting here - I think it’s being a little too aggressive with stripslashes() or something on display, as I see it properly in the editor window. See the attached screenshot of the snippet - keep an eye out for some extra backslashes escaping a few characters. Should be coming in a sec. Wordpress attachments hate me these days. Someday I’ll do a proper reinstall and deal with all of the cruft.

Page 1 of 22 1 2 3 4 5 » ... Last »