I’ve been hating on web comments for quite a while now… I’m sure a lot of you have. For the most part they’re either fucking worthless, stupid or just flat out mean.

Anywho… a video’s been going around the interwebs today about this exact topic and it’s pretty damn great. My favorite part is when they parody youtube comments/commenters.

Enjoy…

  • Digg
  • del.icio.us
  • Facebook
  • Reddit
  • Twitter
Tagged: ,

OK – so last time I wrote about serialization and how json_encode()
and other “external” serializers do not include any private members in the serialized
string they return. Pretty simple but useful. This time I want to talk about transient data; data that shouldn’t be there.

The “problem” is that in PHP you can arbitrarily add new members/fields to an object. There’s nothing stopping you from doing something like
$user->someRandomAssField = $someOtherVariableEvenAnArrayOrObject. These new, on-the-fly members get assigned public scope… so, for example, json_encode() will include that data in the serialized string (so will XML_Serializer, serialize etc). Here’s an example:


<?
class User
{
    public  
$username null;
    private 
$password null;
    
    public function 
__construct($username$password
    {
        
$this->username $username;
        
$this->password $password;
    }
}    

$u = new User('phatduckk''secretPassword*&^');

// we should have ->username in the json st but not ->password
echo json_encode($u), "\n";

// now let's add more stuff to it that isn't declared as a member in
// the class definition
// this shit's transient yo!
$u->friend      = new User('joey''((((secret))))');
$u->randomStuff = array(
    
'bla'   => bla,
    
'hello' => array(1,2,3)
);

echo json_encode($u), "\n";
?>

The output looks like this:

arin:blog Arin$ php transientData.php
{“username”:”phatduckk”}
{
  ”username”:”phatduckk”,
  ”friend”:{“username”:”joey”},
  ”randomStuff”:{“bla”:”bla”,”hello”:[1,2,3]}
}

Whoops – we’ve got shit that we don’t want/need. There’s a ton of reason why this could happen; Sometimes you want this data for internal use (tho I dunno why you wouldn’t make it a proper member of the class) but for the most part its stray shit that got tacked onto an object. Really it just comes down to control. As the author of the API it’s your job to determine what info is exposed to the public & unfortunately (in this case) PHP makes it way too easy for this to happen: no warnings, nothing. So how do we get rid of it?

Getting rid of this stuff’s pretty easy using PHP’s magic methods. This is one of the only cases where I actually like using the magic methods as a solution… usually I consider them evil magic. Read up on magic methods if you dunno what they are then check out the remainder of this post…

So let’s modify the User class above and add some magic so that these transient fields aren’t serialized/encoded via json_encode() (and XML_Serializer etc).

First thing is to add a private dictionary to the class. “Dictionary”, “hash”, “associative array”… whatever you wanna call it… its a key/value lookup.


<?
class User
{
    public  
$username   null;
    private 
$password   null;
    private 
$dictionary = array();
    
    public function 
__construct($username$password
    {
        
$this->username $username;
        
$this->password $password;
    }
}    
?>

So that’s simple… we’ve got a new member which is private (protected would work fine too). Now it’s time to sprinkle in some magic and see where that gets us:


<?
class User
{
    public  
$username   null;
    private 
$password   null;
    private 
$dictionary = array();
    
    public function 
__construct($username$password
    {
        
$this->username $username;
        
$this->password $password;
    }
    
    public function 
__get($key)
    {
        return (isset(
$this->dictionary[$key])) 
            ? 
$this->dictionary[$key]
            : 
null;
    }
    
    public function 
__set($key$value)
    {
        
$this->dictionary[$key] = $value;
    }    
}

$u = new User('arin''secret');
$u->randomStuff  'this is hellza cool';
$u->moreDumbCrap = array(123);

// var_dump to see what's "really" in this object
echo "THE VAR DUMP\n";
var_dump($u);

// now check it out as json
echo "\nJSON_ENCODE\n";
echo 
json_encode($u), "\n";
?>

arin:blog Arin$ php transientData.php

THE VAR DUMP
object(User)#1 (3) {
  ["username"]=>
  string(4) “arin”
  ["password:private"]=>
  string(6) “secret”
  ["dictionary:private"]=>
  array(2) {
    ["randomStuff"]=>
    string(19) “this is hellza cool”
    ["moreDumbCrap"]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
    }
  }
}

JSON_ENCODE
{“username”:”arin”}

You can see from the var_dump that the transient data (aka “random shit”) is all stored in
the private $dictionary member. And, right after that you see a json_encode()‘ed
version of the same instance of a User… and, woot, the transient data ain’t there. We got rid of it with some PHP magic. Kinda cool huh?

One random thing I like about this solution is that most uses of magic methods (that I’ve seen) are to get data or to proxy requests to a child element; It’s kinda cool to use __get and __set in a pseudo-backwards way: as a means to getting rid of data.

I should note that I’ve only used json_encode() in the example above but the same would apply to XML_Serializer.

Anywho… that’s it. Again, pretty easy stuff. Next time I’ll either write about sets of data (which I lied and said I’d do this time) or something else… um, maybe the data access layer.

  • Digg
  • del.icio.us
  • Facebook
  • Reddit
  • Twitter
Tagged: , ,

A friend called me while I was driving home from work asked for some input about writing API’s and I thought I’d blog about it. There’s obviously no “right” way; there’s a ton of valid approaches – I’m just outlining what I’ve liked/learned in my experience.

My whole philosophy is that exposing your API to the public should be easy… theoretically you’re using it internally with your site aren’t you? I mean, there’s obviously some mechanism for the devs to access data and spit it out to the browser right? Exposing that to the public shouldn’t be a big deal.

First off let’s assume, you probably want to offer your data in JSON and XML. Some API’s will return serialized PHP too but JSON and XML and the “must have” variants since they’re supported by most/all(?) modern languages whereas serialized PHP’s probably not well suited for a Java client.

One of the most important things to think about is your data model. This is the data that a public API consumer’s gonna get. Implied there is that there’s some stuff that you really don’t want the public to have access to; whether for privacy reasons (address etc) or for site security reasons (password etc). Handling this “keep info away from the public API consumers” issue has an pretty obvious solution… PHP5+ has member visibility built in.

So, what’s this mean? Let’s take a look at a simple object….


<?
class User {
    public    
$username  null;
    private   
$password  null;
    protected 
$something null;
    
    public function 
setPassword($password) {
        
$this->password $password;
    } 
    
    public function 
getPassword() {
        return 
$this->password;
    }
}

?>


So, this is pretty basic shit but I wanna bring attention to the private & protected members in the User class. Sure, it may be annoying to call $u->getPassword() instead of $u->password but that’s a lame excuse. There’s some nice benefits to properly specifying members’ visibility… one of them being that “outside” serializers don’t have access to non-public members. Here’s what I mean…


<?
$u 
= new User();
$u->username 'Arin';
$u->setPassword('secret');

echo "JSON\n";
echo 
json_encode($u), "\n";

echo "\nXML SERIALIZER\n";
require_once 
'XML/Serializer.php';
$options = array ( 
    
'addDecl'  => TRUE,
    
'encoding' => 'UTF-8'
    
'indent'   => '  ',
    
'mode'     => 'simplexml',
); 

$serializer = &new XML_Serializer($options); 
$status $serializer->serialize($u);
echo 
$serializer->getSerializedData(), "\n";
?>

Running this lil script gives us:

arin@skook.local:~/Desktop > php test.php
JSON
{“username”:”Arin”}

XML SERIALIZER
<?xml version=”1.0″ encoding=”UTF-8″?>
<User>
<username>Arin</username>
</User>

The only member we see post-serialization is $username cuz it’s the only one declared public. Pretty basic shit right? But, it’s a non-obvious benefit… you have a built in way of hiding data within objects before spitting ‘em out thru your API. It’s a nice ‘n neat solution… I mean, what else would you do? Hand construct or sanitize each endpoint’s output? Would you regex out sensitive data? That would suck…

So that’s the first thing I wanted to talk about… having your data models “ready” to be serialized helps a ton. Next time I’ll write about sets of data (an array of Users for example).

  • Digg
  • del.icio.us
  • Facebook
  • Reddit
  • Twitter
Tagged:

I just emailed Joe the steps I’ve used to get PHP, MySQL, Memcached and Apache working on my OS X machine. He’s the 3rd person in 2 days who’s ask me about how i setup PHP on my Mac so I figured other people would be interested too. So I elaborated upon the steps I sent to Joe in order to post em here for public consumption… hopefully this’ll help a few folks out.

There’s a bunch of solutions to get this stuff set up with a quick double click or a few commands in your terminal but I like things to be “my way”. So, if you’re interested read on.

The Easier Stuff

The first thing is to install MacPorts. This makes things quite a bit easier. Also, Mysql comes pre-packaged & I don’t bother compiling it myself. So grab that over here & install that too.

Recompiling Apache

I’ve found it necessary to recompile Apache as 32 bit only. Some PHP extensions didn’t like having a 64bit Apache around. This has been my experience so your mileage may vary. Anywho download Apache and unzip it somewhere. Personally I keep src in ~/Dev/open-src.

Shut down your stock install of Apache in System Preferences -> Sharing -> Web. Next, fire up your terminal and cd into the unzipped source folder. When you’re in the terminal run the following:

$ CFLAGS="-arch i386"
$ ./configure --enable-layout=Darwin --enable-mods-shared=all
$ make
$ sudo make install

This should only take a couple minutes & has always gone smoothly for me. Now let’s restart Apache and see if it works:

$ sudo apachectl restart

Hopefully you don’t have any errors show up:

  1. Cruise by http://localhost to make sure stuff shows up
  2. run sudo apachectl stop and make sure nothing shows up at http://localhost (server is “off”)
  3. run sudo apachectl start and make sure http://localhost is back up

If you get an error about apr or apr-util:

  1. take /opt/local out of your PATH (export PATH=<whatever it is now minus /opt/local)
  2. cd back to the Apache source
  3. make clean
  4. make
  5. sudo make install

Compiling PHP

Download the PHP source over at http://www.php.net/downloads.php, toss it next to the Apache source, unzip the tar (I guess “untar” is more appropriate) and finally cd into the source folder.

Now open another terminal window cuz you’re going to need to install some stuff via MacPorts as well. What you need from MacPorts depends on what you wanna build into PHP. Usually I enable stuff like GD, MySQLi, freetype, pdo etc. This is my config. and you may want more stuff & I’ll try n help w/ that in a bit.

Here’s all the shit I have installed via Macports:

arin@Halloween.local:~  > port installed
The following ports are currently installed:
 apr @1.3.3_0 (active)
 apr-util @1.3.4_0 (active)
 apr-util @1.3.4_1
 autoconf @2.62_0 (active)
 automake @1.10.1_0 (active)
 bzip2 @1.0.5_1 (active)
 cclient @2007_0 (active)
 cyrus-sasl2 @2.1.21_0+kerberos (active)
 db46 @4.6.21_1 (active)
 expat @2.0.1_0 (active)
 fontconfig @2.6.0_0+macosx (active)
 freetype @2.3.7_1 (active)
 gettext @0.17_3 (active)
 gperf @3.0.3_0 (active)
 help2man @1.36.4_1 (active)
 ImageMagick @6.4.7-2_0+q16 (active)
 jpeg @6b_3 (active)
 libevent @1.4.8_0 (active)
 libiconv @1.12_0 (active)
 libpng @1.2.32_0 (active)
 libtool @1.5.26_0 (active)
 libxml2 @2.7.2_1+darwin_9 (active)
 m4 @1.4.11_0 (active)
 memcached @1.2.6_0 (active)
 ncurses @5.6_0 (active)
 ncursesw @5.6_1 (active)
 neon @0.28.3_0 (active)
 openssl @0.9.8i_0 (active)
 p5-locale-gettext @1.05_0 (active)
 perl5.8 @5.8.8_3+darwin_9 (active)
 pkgconfig @0.23_1 (active)
 readline @5.2.012_1 (active)
 serf @0.2.0_0 (active)
 sqlite3 @3.6.4_0 (active)
 subversion @1.5.3_0 (active)
 tiff @3.8.2_2+darwin_9+macosx (active)
 zlib @1.2.3_1 (active)

You probably don’t need some of this at all, ever, but I listed them all just in case. I’d recommend you start with:

  • bzip2
  • expat
  • fontconfig
  • freetype
  • gettext
  • gperf
  • ImageMagick
  • jpeg
  • libevent
  • libiconv
  • libpng
  • libtool
  • libxml2
  • memcached
  • openssl
  • sqlite3
  • tiff
  • zlib

So for each of those:

$ sudo /opt/local/bin/port install <INSERT_PORT_NAME_HERE>

After all that’s done it’s time to compile PHP itself. I put PHP in /usr/local/php<version>. So for PHP 5.2.8 I install it to /usr/local/php5.2.8. You’ll see this is a few of the .configure options below. You’ll also see that I enable an ini directory and also designate that same dir as the location for the main php.ini. This is how I like it… adjust as you please. So cd to the un-tar‘ed PHP source folder and run the following commands:

$ ./configure \
  --with-apxs2=/usr/sbin/apxs \
  --prefix=/usr/local/php5.2.8 \
  --with-config-file-scan-dir=/usr/local/php5.2.8/php.d \
  --with-config-file-path=/usr/local/php5.2.8/php.d \
  --disable-posix \
  --enable-cli \
  --with-mysql=/usr/local/mysql \
  --with-mysqli=/usr/local/mysql/bin/mysql_config \
  --with-jpeg-dir=/opt/local/include \
  --with-png-dir=/opt/local/include \
  --enable-gd-native-ttf \
  --with-freetype-dir=/usr/local/php5.2.8 \
  --with-zlib \
  --enable-pdo \
  --with-pdo-sqlite \
  --with-sqlite=shared \
  --enable-sqlite-utf8 \
  --with-pdo-mysql=shared,/usr/local/mysql \
  --with-xsl \
  --enable-soap \
  --enable-mbstring \
  --with-zlib-dir=/usr \
  --with-ldap \
  --with-xmlrpc \
  --with-iconv-dir=/usr \
  --with-libxml-dir=shared,/usr/local/php5.2.8 \
  --with-curl \
  --with-gd \
  --enable-gd-native-ttf \
  --with-jpeg-dir=/usr/local/lib \
  --with-png-dir=/usr/X11R6 \
  --with-freetype-dir=/usr/X11R6 \
  --with-xpm-dir=/usr/X11R6 \
  --enable-sockets \
  --with-pear=/usr/local/php5.2.8/

$ make
$ sudo make install

…And hopefully that works out for you ;)

Tourbleshooting… No, It’s Not Science

OK – so if you run into problems during ./configure you’re going to have to carefully look at the message and see what’s missing. For example: if it’s bitching about sqlite then make sure you have installed it via MacPorts using the command /opt/local/bin/port installed. If you don’t see it there, install it. Then run .configure but tack on --with-sqlite=/opt/local/include. Again, if that doesn’t work try the same thing with --with-sqlite=shared… if that doesn’t work try it with --with-sqlite. It can get pretty annoying. The jist is that the compiler needs to know how to find the header files. MacPorts makes this stuff pretty easy cuz you wont have to compile xyz yourself… it just does it & tacking on xxxxx=/opt/local/include usually does the trick. Sometimes you might have to resort to copying the .h file from /opt/local/include to /usr/include. I’ve had it go smooth and I’ve had it be a bitch.

You can follow the above “tip” if you want to add stuff as well. Usually just give .configure the switch, watch it break, see what it wants, install it via MacPorts, add the switch back with xxx=/opt/local/include and move on to the next one. Like I said, it’s not science but you’ll eventually get it working.

PECL Extensions

These always go well for me. Here’s what I’ve got installed:

arin@Halloween.local:/usr/local  > which php
/usr/local/php5.2.6/bin//php
arin@Halloween.local:/usr/local  > php -m
[PHP Modules]
apc
ctype
curl
date
dom
filter
gd
gettext
hash
iconv
imagick
imap
json
ldap
libxml
mbstring
memcache
mysql
mysqli
pcre
PDO
pdo_mysql
pdo_sqlite
Reflection
session
SimpleXML
soap
sockets
SPL
standard
tokenizer
xdebug
xml
xmlreader
xmlrpc
xmlwriter
xsl
Zend Debugger
zlib

[Zend Modules]
Xdebug

Some of these are as a result of the PHP compilation but a bunch of them, especially APC, memcache & imagick, were installed via pecl.

You should have pecl installed in your PHP’s bin directory. In the example above the line --prefix=/usr/local/php5.2.8 means that that’s where this install of PHP is. So in there you’ll see a bin folder in there with php, pear & pecl. So, feel free to add /usr/local/php5.2.8 to your $PATH. Anyways… go nuts and install all the pecl extensions you want. If for some reason you don’t have pecl go to http://pear.php.net/go-pear for info on how to install pecl and pear.

Anywho… once that’s settled just go on and type in:

$ sudo pecl install memcache
$ sudo pecl install apc
$ sudo pecl install imagick

Memcached

Just install this via MacPorts… this one’s easy. Woot

You’re Done

Now that I typed all this shit out it does seem like a bit much but it’s really not that bad. Getting the flow of installing a port then modifying .configure was my “ah ha” moment. Once you “get” that you’ll eventually breeze through. Just make sure to keep notes. I’ve kept notes the first time I went thru this and it’s helped a ton. The first compile I did took me hours of fucking w/ this and tring that till I had my “ah ha” (aka “duh”) moment. I’ve gone thru this process 3 times since and every situation is different, but the notes I compiled the first time w/ my .configure options etc greatly reduced the time it took to do it again. It’s kind of like snowboarding… at about your third trip to the slopes you’ll be able to get down a run w/o falling :)

Good luck.

  • Digg
  • del.icio.us
  • Facebook
  • Reddit
  • Twitter
Tagged:
January 3rd, 2009

Software I Paid For in 2008

Most of the software I use is free. When I’m on the computer for long stretches at a time I’m usually writing code or just tooling around the web; I don’t really “need” any paid-for software. The only real exception I can think of is Photoshop.

But, this past year, I did pay for a few pieces of software that provided enough value for me to ditch open source alternatives & open up my wallet. They are: TaskPaper, Versions & Things.

TaskPaper

TaskPaper is my new favorite piece of software. It’s a simple to-do app and, for me at least, is easily worth the $25 price tag. I personally treat it as a todo-list + personal wiki + structured notes to self repository/manager. It’s super simple to use, saves everything as plain text & is pretty great in general. Check out this video for a quick little run thru of the app:

classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
codebase="http://www.apple.com/qtactivex/qtplugin.cab"> pluginspage="http://www.apple.com/quicktime/download/">

Things

Things is another todo (GTD) type of app that I love. I use it as well as TaskPaper and have some weird mental reason for why I use one over the other. For me Things is more “formal”. It’s more organized and way less loose than TaskPaper. So, I never use Things for quick notes or anything like that & use it solely to organize deliverables, bugs & tasks into projects.

Usually I’ll take a whole sprint and create an “Area” out of that, break each chunk of work into a project (ex: change how xyz works) and then add specific tasks to that project (ex: migrate DB stuff, revamp xyz ui to use AJAX etc etc.

So, that’s my approach to using Things. Here’s another screencast that gives you more nuts n bolts info about the app. It’s kinda boring but does a good job and showing off the app’s features.

classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
codebase="http://www.apple.com/qtactivex/qtplugin.cab"> pluginspage="http://www.apple.com/quicktime/download/">

Versions

Versions is a pretty decent, gui-based SVN app. I’m comfortable w/ the command line stuff but for browsing the repository Versions is way more efficient. Sure, you can use it to update, commit and all that good stuff but I never bother w/ that. My main use for it, like I said, is to browse a repo, check timelines, hunt down rev numbers, view diffs and all the housekeeping/hunting stuff. While browsing a repo, you can double click a file to view it’s content; that’s an obvious and basic feature but, you can also use it to view diffs in your diff tool of choice (Araxis Megre, FileMegre etc).

It’s nothing revolutionary but it does save me enough time to justify the price tag.

TextMate

I did purchase TextMate as well…. but, I don’t like it. It’s got a huge fanbase & they’re getting something out of it that I’m not. When writing tons of code (an actual project) I use an IDE and for small, quick scripts I turn to Smultron which is pretty nice & free. Maybe I haven’t explored enough but I don’t get why people like Textmate so much. I wanna like it more, but for some reason I guess it’s just not for me.

Honorable Mention For Coda

I gotta give an honorable mention to Coda. It’s pretty awesome. I love the remote connection capabilities & the built in terminal etc and it just feels “clean”. It’s a solid app but at $99 I can’t justify it. If I did more ad hoc web stuff I’d buy it in a heartbeat but I don’t… it’s perfect for editing my blog’s WP theme but I couldn’t see myself using it for a local, big, php project. For now I just fire up Transmit and use it’s “edit with” capability to edit docs on my FTP server via Smultron.

That’s it, I think… rock ‘n roll.

  • Digg
  • del.icio.us
  • Facebook
  • Reddit
  • Twitter
Tagged:

Search This Blog