Jun 11, 2009

Slashdotted; Post-mortem

About a day and a half ago, Reddit user stderr posted a link to the PHP documentation showing that GOTO will be a part of the language as of version 5.3. Somewhere in the reddit comments for this post, a link was pasted to an entry on this blog where I announced the feature being added years earlier. This naturally brought out the usual flame wars that circle around something like GOTO and drove some new traffic to my blog. No big deal, my server is pretty low-traffic, it can handle a few extra hits.


Within a few hours, burghler had browsed through other entries on my blog, finding what was at the time, the most recent entry about my friend's experience burying her mother. Just like the first reddit post, which had made the front page, this one also had a somewhat incendiary title.


Okay, more than a little incendiary, but I'll get to that in a moment...

The lesson

You would think, given that I'm the Architect for Yahoo WebSearch Front-end Engineering, that I would know something about configuring a server to not fall over under load. And in fact, I spend a good portion of my time on making sure that unexpected traffic spikes aren't enough to make a server get overloaded and trigger a chain-reaction of front-ends falling over. I really have no excuse for not preparing my server for what happened.


When I woke up Wed morning, I found that my server just didn't seem to respond to SSH or HTTP attempts. A reboot request didn't help, and the colo folks insisted that the server was simply running slow, but it was running. So I left my ssh connection attempt running and eventually I did get a login prompt. Several pained minutes later I managed to get an iptables rule in place to block off the flood of traffic (quicker than trying to stop the webserver). Suddenly, the CPU load was gone! Turns out I had my MaxClients setting much too high, and after a certain degree of concurrency, enough web-server children had spawned off to use up the available memory, which triggered disk swap, and made the CPU load 10x worse. Again, I know this effect exists, I really should have set up this server better.


A few tweaks to the config later and I got my server running smoothly. I also took the time to re-run my access log statistics. Of the aproximately 3 years of stats I've got, a full 2% of my hits were logged yesterday. Impressive reddit.... you win this round...

Bright squares indicate heavy traffic, dark squares indicate low traffic


Prior to yesterday's traffic

Jan






























Feb






























Mar






























Apr






























May






























Jun






























Jul






























Aug






























Sep






























Oct






























Nov






























Dec































01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31


Current stats

Jan






























Feb






























Mar






























Apr






























May






























Jun






























Jul






























Aug






























Sep






























Oct






























Nov






























Dec































01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

My flickr views...



Clarifications

Despite the title of the reddit entry, I have nothing against Christians. Further, I count myself as one. So if you really want to take a piss at people who are calling Christians evil, don't aim at me. Thanks.


Moreover, I don't think those people were evil, or even horrible (though I did use that word in the heat of the moment). A loved one had just died, and everyone was in pain. Death SUCKS, and it was a bad situation no matter how you slice it. I don't hate those people for trying to erase my friend though, I pity them. I pity the fact that they turned down the chance to mourn the passing of their loved one by crying on another loved one's shoulder. I pity the fact that they didn't get nearly the closure that my friend did. I pity them for willingly becoming victims of their own grief.


The rest is between them and God.

Jun 5, 2009

Wait, did you seriously just say that?

I grew up in California, and my state is pretty well true to it's reputation of being....less conservative than average. Granted, I've been harassed, shunned, even outright beaten over being queer, but I always thought that when it comes to certain things, especially family, there's a line that just isn't crossed. This is why the events of the past weekend so thoroughly amazed me.

Several months ago, when she told me that her mother had Cancer, I promised my kinda-ex-nevermind-it's-complicated-girlfriend that when the time came, I'd jump on a plane and fly out to the Midwest to help her bury her mom. So it was, that when she called me from Toronto (she was in the middle of a business trip), I booked a one-way flight (we weren't sure how long things would take), and flew off to Cleveland to meet her and offer my sympathies.

Death is hard, no matter how prepared for the end you are, but for my friend it was doubly difficult. For the past four years, she'd only rarely been able to see her mom, due to both distance and conflict between her and other people in her mother's family. We'd hoped that in the darkness of losing a loved one, those hard feelings and prejudices could be set aside, that family could come together for just one day to share grief and say good-bye. We were unbelievably wrong...

We landed together at CLE on friday night and headed over to her dad's house (her parents had been long divorced). He greeted us, filled her in on the past few months and her mother's last days, and we left feeling the weight of the occasion, but ready to grieve. On the way out, her sister called saying, "Some of the family have asked that you don't show up to the viewing. They say you can come into the funeral home for a few minutes afterward, but not during the general viewing."

I know, take a minute to absorb that statement. Who are these family members? Vague mumbles always answered this question, but they were certainly not going to tolerate my friend's presence. We resolved to call around the next day...

It was Saturday and the obituary had come out. Anachronistic newsprint mourned the loss of a sainted mother to my friend's sister, "special mother" to my friend's ex-spouse, but no mention of my friend. They had simply erased her, with a nod to her ex as a special kind of insult.

My friend called her sister back, wanting to understand how so much animosity could survive and flourish like that. She wasn't going to be erased, so she told her sister that the family could just deal with the fact that she would be present at the viewing. It was her mother that'd died, and she intended to say good-bye. A few hours later, news had filtered through to her step-father who called and delivered a matter-of-fact edict. "Here's your options, and I'm only going to say this once. You can come at 7, after everyone else is done, and take your 15 minutes to say good-bye, or you can not come at all. I'll have a cop at the door to make sure of that. *click*"

Yes, you heard that right, he was hiring an off-duty police officer to keep her out of her own mother's services.

And before you ask, yes, her step-father had that legal right, as the funeral home was private property contracted by him. So it was, that the next day, we (My friend, another friend of her's, and myself), drove to a shopping center near the funeral home and parked where our cars couldn't be identified and vandalized, and we walked to the funeral home at the official start time. Sure enough, a uniformed police officer stood guard at the entrace.


Arriving

We sent in the third member of our party, as she comes off much less threatening than I, and hadn't been explicitly told not to show up. She went inside, and formally asked the funeral home's director (with the step-father standing nearby), if we could be allowed inside. "Oh my God! They're here! They're here!", I wasn't present, of course, but I'm told the step-father reacted like we'd just stormed the beach at Normandy. "Those people are not to be allowed inside under any circumstances!", the funeral director could only agree with his client's request, so our other friend walked back to the sidewalk, where we sat down and initiated project Ghandi.

Okay, we didn't have any clever name for it at the time, but the premise was simple enough. We were in a labor state where the right to strike is sacrosanct. Being a public easement, we knew we were in our legal rights to remain there. This was the crux moment. Although we had legal rights, the police officer could have trumped up a reason to remove us for the duration of the ceremony, and we'd have lost our gamble completely, but he just stood at the door, showing no hint of emotion of sympathies for either side. A credit to his uniform.

I'm told, from those who were inside, that the step-father was yelling at the cop to have us removed and/or arrested. The cop answered that we were on public grounds and not causing a disturbance, so there was nothing he could do. I'm told he would get up every 15 minutes to look out the window and see if we were still there. We were. I'm told he called the police department to have additional officers sent around to "round us up", each new arrival told him the same story, no laws were being broken.


The challenge

About half an hour into the services, we were approached by the ex, who calmly flipped through the binder full of memories my friend had brought with her. They hugged, but didn't say much... What can be said at that point? Then my friend's ex-mother-in-law came over and just as I thought we were going to see another calm, but sad episode of sharing... "You know, you brought this on yourself."

I felt numb for a moment. I couldn't possibly have heard that come out of her mouth, not with my friend's mother lying in a casket 20 feet away... My friend managed to utter, "No", then turned away and began crying. "Yes, you did. You brought this on yourself." Our other friend interjected, "That's really not necessary..." "Yes it is", the mother in law replied, "this situation is because of her actions..."


She didn't get to finish that sentence. Something inside me snapped and a wellspring of rage came over me. I stood directly in front of the MiL, and found the most even temped voice I could manage, "Ma'am, I understand that you've just lost someone dear to you. I understand that you're in pain, and I understand that you think you're doing good, so I'm going to try to say this in the nicest way possible.", from here, my decorum ran out of rehearsed speeches and my rage took over, "You are an unchristian, bad...bad... Horrible person."

"No she isn't.", I heard from my firend's ex, but I ignored that. I stared at, and through her MiL, almost wanting a physical confrontation. "Sara..." The plaintive caution of our other friend snapped me out of my anger and I stepped away, andrenaline thundering through my blood. The MiL gave up trying to berate my friend and began to walk away. "I'm sorry", I offered, "That was unnecessary and uncalled for, I apologize." I don't remember much of the next several minutes, as my stress level slowly calmed down.

"Thank you", my friend told me. "I needed some strength right there and that's exactly what you gave me." After a moment she smiled, "You did unload on her a bit though...". "Yeah", I smiled back, "I was killing a few of my own demons there at the same time, might've over-estimated the firepower...

Soon afterward, her step-grandmother came around. "Why don't you just leave? You've making a spectacle of your mother's viewing!" She continued and I held myself back as long as I could. My friend held her own against this onslaught much better, continually drawing the conversation back to her mother, and trying to remember the best of her mother and focus on the mourning of her passing. The step-grandmother continued to catalouge all the (made-up) offenses my friend had allegedly committed against the family (all of which were thinly veiled reproachments for her queerness), until I spoke up, asking her if Jesus taught forgiveness, "Yes, BUT... we someone, when you have, when the person that has brought you into this world..." Honestly, even though I captured video of the entire event, I couldn't tell you for certain what she said as her argument descended and crashed into incoherency. Eventually she threw her hands up and walked away. Our other friend looked at me a little dumb-founded... "That... Was almost a thing of beauty the way she fell apart..." Yeah, I felt a little guilty at the efficacy of it too....


Redemption

Next up, was my friend's cousin. "What are y'all doing out here? Aren't you coming inside?" We told him what the step-father had said. His curious smile fell into disbelief, then anger rose in his face until his aura throbbed a dark crimson red. "That's ridiculous, I'll be right back." He stormed inside, and I'm told he raised holy hell on our behalf. Shortly thereafter, several more family members came out until there was all but a line queuing up around my friend to console her and share grief over her mother's death. For myself, I began to worry that we'd start to qualify as an unruly mob and give the police something to raise a fuss about. Nothing happened though, I think I even saw the cop smile.

Vindication

Eventually her mother's nurse, who was no part of the family, pulled my friend aside. "I only knew your mother for a few months, but she told me things about you in that time. Good things.", and she proceeded to list off things that she couldn't have made up. Things that proved to my friend that her mother really had loved her at the end, but was too afraid to show it.

My friend visibly brightened after that. As though she'd let go of something sour and offal. A few more hours passed in the pleasant late-spring weather. People came out and went back in, arrived and departed, noone else said an unkind word after her step-grandmother. Finally, when the funeral home was nearly empty, the cop approached us, "The funeral director's told me it's okay for you to come in now. I'm sorry for your loss." We thanked him and shook his hand and made our way inside. The step-father and other naysayers were nowhere to be seen, but there at the end of an array of fold-out chairs, was my friend's mother.


A poetic ending

I won't go into the details of her weeping, but she cried out the last of her grief. After hours of sharing, but not having access to the body, my friend had excised the worst of her grief already. She had prepared herself and found the peace she needed to see her mother's still form. For all her step-father's machinations and attempts to rob her of her mother and her place in her family, my friend was able to grieve her mother's passing in a way that couldn't possibly have been any better or more complete. If we had been inside the whole time, the shock of seeing her with so many unresolved things would have been devastating. If we had simply taken orders and not shown up until the last few minutes, there would not have been nearly enough time, and there would have been no family to lean on. By standing on the sidewalk, we took away that power, we reclaimed it as our own, and we amplified it even further. We said good-bye.

And the naysayers? They just looked like monsters. Love: 1, Hate: 0; Schadenfreude, I haz it.

Jan 8, 2009

Yahoo!, doing something right!

I love it when Yahoo! manages to just get something right. Checkout the awesome sauce of a media player widget. By doing nothing more than linking to an external script. All three of these P3 podcasts become magically playable directly from my blog.

Click the play buttons, but don't forget to notice the little slide-out player in the lower-left corner. Swanky, n'est-ce pas?

Dec 30, 2008

2008 Lookback

It's been a helluva year... No, seriously, it's been... unique.


Last January, I started off the year with a presentation at geekSessions-1.3, along with some associated "hanging-out" in San Francisco (a city I normally avoid, because I dislike large crowds of people). I also got a brand new insulin pump to replace the seven year old beast who's LCD display had finally died. The pump itself didn't die (kudos to Medtronic for that), just the display. I've enjoyed my new "pocket pancreas" about as much as the old one, though of course the incremental improvements to its design haven't gone unappreciated.


February was a fairly quiet month for me professionally. A mixup in some of my medications (not related to the new pump), left me really distracted and irritable. The medications have been sorted, but I got to like the fear I induced in my coworker's eyes to the point that I keep up the show for appearances sake. :)

March was a flurry of activity getting things sorted at home and at work so that I could take a much needed month off in April. This month would ultimately turn into a mere three weeks since I refuse to relax, but it was time well spent anyway. During March I met two new friends who I've since come to appreciate deeply, and in April I got to spend a lot of time with my grandma; Something I do far too little of.


May saw the launch of Yahoo! Search Monkey move into full swing, bringing a lot of time and effort by the entire Search team along with it. As part of the launch, we held a developer event in Sunnyvale, and I learned that if you blog long and hard enough, random strangers will eventually show you naked pictures of themselves.


June was a hard month to handle. My wife of more than 10 years got herself a 1 bedroom apartment and moved out. We're both feeling the repercussions of that, and while reconciliation is a possibility, we really haven't fixed any of the things were wrong with our relationship. See, we're just as F-ed up as a straight couple, but with twice the estrogen! It was also at this time that my grandfather's cancer took a turn for the worse and he found himself spending a great deal of time in ICU. His children and grandchildren did their best to avoid feeling useless as we waited outside him room, not sure if he was going to pull out of it...


In July, my grandfather was feeling good enough that we threw a small party for my cousin's graduation, and brought him along for what we all knew was going to be his last summer. There was a lot of smiling outdoors and crying in the bathroom. During this party my grandfather pulled me aside and gave me a gift that... I'm not even sure he understood how much it meant to me... My sister took photos, and we all doted a bit more than we should have, but we built a new memory around him that we can carry with us.


Having managed some pretty downer months so far this summer, I took a week at the end of August to take a real vacation to south Utah where I went hiking with four complete strangers I'd met over the internet. Hrmmm... desert... strangers... dangerous climbs? Not the most sane thing I've ever done, but I made some really good friendships that'll last for years to come, and if all goes well, I'll be taking another trip with them this coming June, back to Zion National Park.


September saw ZendCon08 and PHP Appalachia, the latter of which spawned far too many anecdotes about the rowdiness of the PHP community. Where should I start? The semi-naked toxic hot tub? The jagged piece of glass that Chris tried to kill Ben with but got stuck in Cal's foot instead? The fire department we bribed with a cute blonde? Nonono, what happens in Pigeon Forge, stays in Pigeon Forge...


In October, my grandfather fell ill again, holding on just long enough to say good-bye to his children and grandchildren. Sadly his great-grandchildren aren't likely to remember him very well, but thankfully I know that my last words to him were, "I love you", and at least he went quickly. We can all hope for so much when out time eventually comes.


November led to another rowdy conference get together. This time it was php|works in Atlanta, GA, and I dunno about you, but Marco really needs to stop letting me near the open bar. I'm not a frequent drinker, so my tolerance is really very low, and I do... unconventional things when I've had my ninth vodka/cranberry... Doesn't hurt that the bartender was very generous... Oh well, at least I didn't throw up in the taxi on the way to Cal's going-away party. ((Note: I didn't say who did... assuming anyone did... which I didn't say either...))


And oh yeah... the election... biggest sack full of mixed emotions in a long time... Okay, sure, let me get it out, YAY! Obama won. I have HUGE hopes for this guy, and given what I've seen of his transition process, I think he might just stand a chance of living up to his hype. YES. WE. CAN. There, now that that's out of my system, I can go back to being really dissapointed in the One Million californians who voted in favor of Proposition 8. I can go back to slamming my face into the desk whenever I hear the FALSE argument that equal marriage rights will lead to sodomy in the streets and pedophilia in the classrooms. I can go back to being disappointed by my fellow Christians who call homosexuality as significant a threat to humanity as global warming and a threat to world peace. That's not just any Christian saying that by the way, that's the ever-lovin' POPE.


And then here it is: December. My wife and I are talking about getting back together, though I'm not sure we're making progress... I'm doing my best to focus back on my work. I've gotten back into rock climbing, and am eagerly awaiting the snow season to start in earnest. I got up to my dad's for another Christmas with the family, strained by not having gramps around, but I can tell my dad's trying to step up and fill the patriarchal void that's been left. I've spent the past week fighting off a cold and baking cookies. Tomorrow I'll head back into the office and get some work done before having friends over for a new year's eve bash. On thursday, it'll all start over again...


Happy new year.

May 15, 2008

I have officially arrived

I was at the Search Monkey Developer Launch tonight to answer questions and give demos to the attendees. The event itself was a nice success, but that's not what I'm writing about. What I'm writing about is one particular attendee. Apologies to this guy if I embarrass him, but he had to know I'd say something.


After getting through the initial queue of developers asking about Search Monkey, I was approach by a tall young man:

<guy> Hey, you're Sara Golemon, right?
<me> Yeah...
<guy> Nice to meet you, I really like your blog entries about how PHP works,
and I bought your book!
<me> Oh fantastic! Are you enjoying it?
<guy> Yeah, it's really heavy, and I haven't had a chance to use a lot,
but I was experimenting with writing my own libssh2 wrapper...

By this point, I'm suitably blushing. I'm easily swayed by compliments thanks to my lack of self-esteem. Then he takes a turn...

<guy> I almost emailed this to you, it's a photo my girlfriend took of me without warning...
Let me just find it in my camera
* guy shows photo of himself lying in a water-filled bathtub, naked, covering his... bits
with a copy of my book

I... um... well... okay... I can see why you wouldn't email that out of the blue.... Now, I try to think of myself as a fairly progressive, hard-to-phase sort. I can tell a dirty joke with the best of 'em, but this just... left me giggly for the next hour. Like, um...wow... okay... Thanks for sharing...


Is this a sign? Is it a measure of notoriety when strangers show you naked photos of themselves at random tech gatherings?

Jan 19, 2008

Understanding Opcodes

A blog reader (I have readers???) recently shared his wishlist, "I'm trying to figure out how to show the opcodes like you have in your post...". I promised that I'd throw something together, so here it is:


Slow down, wtf is an "Opcode"?

Short answer: It's the compiled form of a PHP script, similar in principle to Java bytecode or .NET's MSIL. For example, say you've got the following bit of PHP script:

<?php
echo "Hello World";
$a = 1 + 1;
echo $a;

PHP (and it's actual compiler/executor component, the Zend Engine) are going to go through a multi-stage process:

  1. Scanning (a.k.a. Lexing) - The human readable source code is turned into tokens.
  2. Parsing - Groups of tokens are collected into simple, meaningful expressions.
  3. Compilation - Expressions are translated into instruction (opcodes)
  4. Execution - Opcode stacks are processed (one opcode at a time) to perform the scripted tasks.
Side note: Opcode caches (like APC), let the engine perform the first three of these steps, then store that compiled form so that the next time a given script is used, it can use the stored version without having to redo those steps only to come to the same result.

Er... okay... can you elaborate a little? What's lexing? I thought superman put him in jail...

That's Lex Luthor you nit-wit! The most expedient way to explain lexing is by example. Take a look at the manual page for token_get_all(), this gem is actually a wrapper around the Zend Engine's own language scanner. Play around with it a bit, and you'll notice that plugging the short script above into it will produce:

Array
(
[0] => Array
(
[0] => 367
[1] => <?php
)
[1] => Array
(
[0] => 316
[1] => echo
)
[2] => Array
(
[0] => 370
[1] =>
)
[3] => Array
(
[0] => 315
[1] => "Hello World"
)
[4] => ;
[5] => Array
(
[0] => 370
[1] =>
)
[6] => =
[7] => Array
(
[0] => 370
[1] =>
)
[8] => Array
(
[0] => 305
[1] => 1
)
[9] => Array
(
[0] => 370
[1] =>
)
[10] => +
[11] => Array
(
[0] => 370
[1] =>
)
[12] => Array
(
[0] => 305
[1] => 1
)
[13] => ;
[14] => Array
(
[0] => 370
[1] =>
)
[15] => Array
(
[0] => 316
[1] => echo
)
[16] => Array
(
[0] => 370
[1] =>
)
[17] => ;
)

In the array returned by token_get_all(), you have two types of tokens: Single character non-label characters are returned as just that. The character that was found in the source file at that point. Everything else, from labels, to language constructs, to multi-character operators (like >>, +=, etc...) are returned as an array containing two elements: The token ID (which corresponds to T_* constants -- e.g. T_ECHO, T_STRING, T_VARIABLE, etc...), and the actual text which that token came from. What the engine actually gets is slightly more detailed than what you see in the output from token_get_all(), but not by much...

Okay, tokenization just breaks the script into bite-size pieces, how does parsing work then?

The first thing the parser does is throw away all whitespace (Unlike some other P* language...). From the reduced set of tokens, the engine looks for irreducible expressions. How many expressions do you see in the example above? Did you say three? WRONG There are three statements, but one of those statements is made of two distinct expressions. In the case of $a = 1 + 1; the first expression is the addition, followed by the assignment to the variable as a second, distinct expression. All together our expression list is:

  1. echo a constant string
  2. add two numbers together
  3. store the result of the prior expression to a variable
  4. echo a variable

Hey! That's starting to sound familiar! Did I see that kind of description before?

Oh, you must mean my post about strings (plug). That's correct, because these expressions are exactly the pieces which go into making up oplines! Given the expression list we've just reached, the resulting opcodes look something like:

  • ZEND_ECHO 'Hello World'
  • ZEND_ADD ~0 1 1
  • ZEND_ASSIGN !0 ~0
  • ZEND_ECHO !0

What happened to $a? What's the difference between ~0 and !0?

Short answer: !0 is $a


So here's the deal.... oplines have five principle parts:

  • Opcode - Numeric identifier which distinguishes what the opline will do. This is what coresponds to ZEND_ECHO, ZEND_ADD, etc...
  • Result Node - Most opcodes perform "non-terminal" actions. That is; after executing there's some result which can be consumed as an input to a later opline. The result node identifies what temporary location to place the result of the operation in.
  • Op1 Node - One of two inputs to the given opcode. An input may be a constant zval, a reference to a previous result node, a simple variable (CV), or in some cases a "special" data element, such as a class definition. Note that an opcode may use both, one, or neither input node. (Some even use more, see ZEND_OPDATA)
  • Op2 Node - Ditto
  • Extended Value - Simple integer value used to differentiate specific behaviors of an overloaded opcode.

So obviously the nodes are the most complicated parts of an opline, here's the important parts of what they look like:

  • op_type - One of IS_CONST, IS_TMP_VAR, IS_VAR, IS_UNUSED, or IS_CV
  • u - A union of the following elements (the one which is used depends on the value of op_type):
    • constant (IS_CONST) - zval value. This node results which you include a literal value in your script, such as the 'Hello World' or 1 values in the example above.
    • var (IS_VAR or IS_TMP_VAR or IS_CV) - Integer value corresponding to a temporary slot in a lookup table used by the engine.

Now let's look at the difference between those optypes, particularly with respect to u.var:

  • IS_TMP_VAR - These ephemeral values are strictly for use by non-assignment non-terminal expressions. They don't support any refcounting because they're guaranteed not to be shared by any other variable. These are denoted in the examples I use on this site (and in VLD output) as tilde characters (~)
  • IS_VAR - Usually the result of a ZEND_FETCH(_DIM|_OBJ)?_(R|W|RW), or one of the assignment opcodes (which are technically non-terminal expressions since they can be used as inputs to other expressions. Since these are tied to real variables, they have to respect reference counting and are passed about at an extra degree of indirection. They're stored in the same table though. These are denoted by the string symbol ($)
  • IS_CV - "CV" stands for "Compiled Variables". These are basicly cached hash lookups for fetching simple variables from the local symbol table. Once a variable is actually looked up at runtime, it's stored at an extra level of indirection in an even faster lookup table using an index into a vector. That's what the number in this node denotes. These types of nodes are distinguished by a bang (!)

Boggle... You...so lost me there...

Yeah, that explanation sort of got away from me didn't it? What can I clear up?


All I really want to know is how to translate some source code into an opcode..list...thingy...

Heh, okay... first off, that "opcode list thingy" is called an op_array, and you can generate those really easily using one of two PECL packages. You can use my parsekit package, which is useful for programmatic analysis of script compilation, but frankly... it's not what you're looking for and there's not much call for scripts analyzing other scripts anyway. I recommend Derick's VLD (Vulcan Logic Disasembler) which is what'll actually generate the kinds of opcode lists you'll see me use in blog posts.


Once you've got it installed (it installs like any other PECL extension), you can run it with a command like the following:

php -d vld.active=1 -d vld.execute=0 -f yourscript.php

Then sit back and watch the opcodes fly! Important note: Using -r with command line code may not work due to a quirk of the way the engire parses files in older versions of PHP (and with older versions of VLD). Be sure to put your script on disk and reference it using -f if -r doesn't work for you.


Holy schnikies! That's a lot of opcodes! How can I tell what they all do?

Take a look at Zend/zend_vm_def.h in your PHP source tree. In here you'll find a meta-definition of every single opcode used by the engine. Side note: It's used as a source for zend_vm_gen.php which generates the actual code file zend_vm_execute.h. How's that for chicken and egg? Every version of PHP since 5.1.0 has required PHP be already built in order to build it!

Jan 17, 2008

I'm syndicated, and it has nothing to do with PHP!

I was running some test queries using my usual spread of values and came across a result of "Lieutenant Fluffy?" which was far too whimsical a topic to ignore. Turns out someone thought my holiday photos made for a good creative commons pick. Kudos to the news site for respecting licensing terms properly!