Yesterday was a milestone event in my PHP programming career; I wrote my first PHP robot script. It was a nerd triumph of sorts. My friend David, who got me started on PHP about 3 years ago, once again helped me get to the next level. He’s not really a PHP programmer per se, but he works data magic on spreadsheets and knows the PHP syntax well enough to pop data variables into PHP scripts brute force style. We collaborated to create a straight up PHP brass tacks script that did some real work. Which as it turns out, was a real epiphany for me.
Let me begin this story with an analogy about drywall and demolition. When I had first set out to remodel our kitchen in our first house, I had never done drywall or demolition. My father was an engineer, and most things we worked on together as father and son were precision in nature: rulers, pencils, straight lines, diagrams, graph paper, &c. So I really didn’t know what I was getting into when it was time to demolish my old kitchen. Luckily, I had my father-in-law coming over and this was his type of work, and I was about to learn from one of the best.
I woke up one spring morning and made myself breakfast in my kitchen for the last time. My father-in-law shows up after breakfast with a couple of sledge hammers and some other tools. He hands me one of the sledge hammers, takes a swing at a wall in my kitchen with the other and knocks the fuck out of it. A little explosion of dust and debris came from the contact of that hammer against the wall. That visual coupled with the loud THUD! noise made my goes wide. I was thinking ‘what the fuck!?!? we’re just going to knock this motherfucker the fuck down!?!?’. It was very liberating to swing that sledge hammer; it was intoxicating. I got into a zone smashing walls, cabinets, old nasty range-tops, counter-tops, soffets, &c. It all happened so fast. The kitchen that I had just eaten breakfast in was gone before lunch time. My kitchen was naked down to the studs and what used to be my kitchen was a scatter of debris in my backyard. It was awesome.
My father-in-law told me demolition and drywall aren’t precision crafts, they’re blue collar crafts. When you draw that pencil line on a piece of drywall and cut into it with your razor blade, you don’t need to be perfect, the mud is going to cover it up. If you fuck up and put your hammer through the drywall, it doesn’t matter, you mud it up and it never happened.
The point I’m trying to make is that sometimes when computer programming, we get trapped by some unnecessary dogma of setting up our code for refactoring and DRY bullshit that we forget to swing for the fences. We sometimes waste so much time contemplating a perfect plan that we forget to pick up that sledge hammer and knock the shit out of something. That’s what this code did the other day when David linked it up to his spreadsheet. He wrote a formula that copied and pasted the little snippet of PHP code below 3,222 times creating 26,000 lines of PHP that went off to work for two and half hours as fast as bandwidths and CPU’s could go. And when it was finished, the job was over. Mission accomplished. There was no reason to debate the elegance of the code or how you just repeated yourself 3,222 times thus breaking some bullshit rule about not repeating yourself.
Let’s look at the psuedo code of the script:
David runs a business called planetbulb.com. He needs to get his latest product images onto his production server from the server where his wholesaler keeps them for distributors like planetbulb.com. The wholesaler has given David a database that he’s pulled down into Microsoft Excel and he’s sorted the data down to 3,222 rows on a spreadsheet that have the URL and the new name he wants for each image. That’s the first objective: get the images. The other objective is good SEO. And, image names inside of image tags score big points with Google’s logic and the other big names like: Bing, Yahoo, &c. So, we want to get a list of 3,222 images from a remote URL, copy them to our hard drive, and rename them to a nicely crafted SEO name. If we do this right, it will help planetbulb.com get the lights from the wholesaler to the end consumer better and easier than anyone else. David will take it from there and get the images imported to his product portfolio with nice links and displays and what not.
Let’s look at the code:
<?php $remote_img = 'http://www.wholesalers_website.com/URL_string_to_image'; $img = imagecreatefromjpeg($remote_img); $image_name = "beautifully_crafted_SEO_image_name.jpg"; $path = 'images/' . $image_name; imagejpeg($img, $path); ?>
The code is pretty straight forward. Store the URL in a variable called $remote_img, use a native PHP function to create an image identifier from the URL, store our better SEO name in the variable $image_name, tell the $path variable what directory to use, and lastly output the image to a file.
So the only tricky thing I gotta pull off is the loop. This is pretty much where I was bogging down because I was getting so technical with how to write the loop. I’m not super great at programming PHP, so I bog down sometimes when I’m trying to make PHP do certain stuff or new stuff. I was over complicating things instead of getting the job done. I was spending too much time trying to figure the logic and getting nothing done. This is where David comes in with the sledge hammer…
I had sent him the code but had told him that I was stuck on the loop. David wrote a formula in Microsoft Excel that wrote the same little block of PHP above 3,222 times. Each block of PHP was fed the proper URL and new image name David wanted. I never think like this!! It was brilliant. You just load that script up, run it through, and toss it in the hopper when you’re done. Because who cares, you got what you wanted and you’re done. Next job please.
I love that kind of feeling and it was very eye opening for me because sometimes you just need to swing the hammer and get some shit done. My loop would have been an elegant 15 lines of code or so, but loop data would STILL need to be loaded into an array ANYWAY. I was about to write one loop and load it up with three thousand or so key => value pairs, what’s the big improvement there for the time wasted? It’s a trick question, there is none. David’s 26,000 lines of code is essentially the same thing as a foreach loop that forgoes yuppity programming semantics; David’s way leverages the power of Microsoft Excel. In my opinion, David’s way is a much better and efficient technique even though it flies in the face of some bullshit rule that says repeating yourself is inefficient. In about the time I spent fumbling with the most efficient way to do something, I could have had the job done. The conventional logic of programming etiquette and elegance is in this case, well… it’s horse shit; because the tools you use should depend on the job you gotta do. And for this job, and amongst spreadsheets, Microsoft Excel is hands down the best tool for this job. Microsoft Excel has been the most influential piece of software in my entire life because of things you can do like this. I don’t understand Microsoft haters; I love me some Microsoft and think Bill Gates is hall of fame type of guy. But, haters gonna hate.
Here are the tools used for this job:
- Windows 7 professional edition
- XAMPP apache server (free!)
- Notepad++ (free!)
- Microsoft Excel
- PHP 5.3 (free!)
- Mozilla’s Firefox (free!)
Let’s talk about a couple stumbling blocks before the machine came to life:
Copying and pasting the code from Microsoft Excel to Notepad++ presented the first little syntax error. When I first let the script rip, it crashed on arrival. Sometimes when you paste stuff from Microsoft Excel to a text editor there are some extra quotation marks and whatnot. Fortunately, Notepad++ has some nice find and replace utilities that fixed these problems in a hurry. This was easy.
Then, there was the moment of truth when I let it rip and it started humming. I was dancing at this point thinking “you gotta be kidding me, is this really working?”. I was elated. But then, buzz kill. I go for a drink of water and come back to a Maximum execution time of 60 seconds exceeded error because of a couple settings in my php.ini file that needed some attention. The script was able to get 115 images before it crapped out but I wasn’t going to batch this thing up 115 images at a time. That would suck. I needed to figure out how to raise the ceiling on those limits.
I changed the max_execution_time setting to zero (unlimited) in the php.ini file. I restarted Apache with XAMPP and let it rip again. Crashed again though. Another 115 photos or so and then it crashed again. I was stumped a little and had to do some more Googling. It turns out I had to raise the ceiling on two settings. The max_input_time also had to be changed to its unlimited setting which is negative one. I restarted Apache and let it rip again. I was off to the races. It was the coolest thing in my programming career ever. The settings necessary for the php.ini file are shown below.
;;;;;;;;;;;;;;;;;;; ; Resource Limits ; ;;;;;;;;;;;;;;;;;;; ; Maximum execution time of each script, in seconds ; http://php.net/max-execution-time ; Note: This directive is hardcoded to 0 for the CLI SAPI max_execution_time = 0 ; Maximum amount of time each script may spend parsing request data. It's a good ; idea to limit this time on productions servers in order to eliminate unexpectedly ; long running scripts. ; Note: This directive is hardcoded to -1 for the CLI SAPI ; Default Value: -1 (Unlimited) ; Development Value: 60 (60 seconds) ; Production Value: 60 (60 seconds) ; http://php.net/max-input-time max_input_time = -1
I think the epiphany part of this process is when you realize that you have just made the code do work for you outside of your house. The work is actually getting done out on the worldwide web. This sounds like no big deal somehow, but it is. There’s a realization that if I can make PHP do this, I can make it do it again in another capacity; for another reason down the road. The code is reusable and the know-how to modify it to the next job is a piece of cake.
The code wasn’t pretty, but it didn’t need to be. It just needed to do a lot of work. This is where I hearken back to a post my friend Richard wrote. Richard mentioned Mark Zuckerberg’s open letter for the Facebook I.P.O. emphasizing the quote: done is better than perfect. Those words resonated with me. I’m always trying to make some perfect thing but sometimes you just need it to work now. I’d been dwelling on that Zuckerberg quote for a couple weeks, applying it, and it was working. But, as Ice Cube says, you gotta continually check yoself because I missed it here a little bit. David’s approach helped me step back to consider a completely different way of accomplishing things that had a value greater than my initial plan.
This is a milestone event for me, because the whole end game for me is protecting the world’s water resources. I can use that code to help build respectmyplanet.org. Respectmyplanet.org is where I’m going to build out some cool stuff for people to upload pictures. The PHP is going to pull off the EXIF data from people’s pictures and drop a pushpin on a map using the Google Maps API V3. Then it will register the photo in the database and allow people close by to add comments to it. People in the location being polluted will be able to band together using common sense geolocation to find representation from good lawyers that can help them. This way, people will be able to work together to share data on where companies are polluting our water or air. This will allow the power of the people to work harder for a stronger Democracy to say “We the People Want to Protect Our Water”.
Check out this video 🙂