Archive for the 'Geek' Category

Scanning a Directory For PHP Errors

My fellow web geeks might find this script, php-check, useful. It recursively scans a directory checking PHP files for syntax errors.

Just copy it somewhere in your path (like /usr/local/bin) and chmod it to 755.

I wrote the script because I edit PHP using Notepad++, so it's easy for small typos to enter my scripts. I needed a quick way to scan a directory after uploading revised files.
I wrote it in PHP so that those who need it will also know how to customize it.

PHP:
  1. #!/usr/bin/php
  2. <?php
  3. // php-check version 1.0
  4. // recursively scans a directory for .php files and runs php -l on
  5. // them (php -l checks for PHP syntax errors)
  6. // revisions at http://glenandpaula.com/wordpress/archives/2007/10/31/scanning-a-directory-for-php-errors/
  7.  
  8. if (php_sapi_name()!='cli') {
  9.     die("This utility can only be run from the command line.\n");
  10. }
  11.  
  12. $counter=0;
  13. $errors=false;
  14.  
  15. function scan_dir($dir) {
  16.     $counter=0;
  17.     $dh=opendir($dir);
  18.     while ($file=readdir($dh)) {
  19.         if ($file=='.' || $file=='..') continue;
  20.         if (is_dir($dir.'/'.$file)) {
  21.             $counter+=scan_dir($dir.'/'.$file);
  22.         } else {
  23.                if (substr($file, strlen($file) - 4) == '.php') {
  24.                         $counter++;
  25.                     $output=shell_exec("/usr/bin/php -l $dir/$file 2>&1");
  26.                     if (substr($output,0,2)!='No') { // skips the "No syntax errors in ..." message
  27.                         $errors=true;
  28.                         echo $output;
  29.                     }
  30.                }
  31.  
  32.         }
  33.     }
  34.     return $counter;
  35. }
  36. if ($argc!=2) {
  37.     die("Usage: php-check dirname (usually php-check .)\n");
  38. }
  39.  
  40. if (!is_dir($argv[1])) {
  41.     die("Argument must be a directory. The most common usage is php-check .\n");
  42. }
  43.  
  44. $counter=scan_dir($argv[1]);
  45.  
  46. echo "$counter files checked\n";
  47. exit($errors);
  48. ?>

This is a quick and dirty script - there are probably some bugs in it. User beware.

If you find it helpful, you might also want to check out scripts like PHP CodeSniffer or PHP Beautifier.

Me And The Mythbusters

I recently submitted a question to the Freakonomics guys for an interview with the MythBusters.

They picked my question as the first one!

Here's my question and their answer:

Me: Could you describe the brainstorming process that goes into an episode? How far in advance do you begin planning? Who sits in during those meetings?

ADAM: The usual crowd at a brainstorming session is me, Jamie, Alice Dallow (our producer), and whichever researcher is doing the segment we’re working on — either Dennis Kwon or Eric Haven. We also have an on-the-ground executive producer during an official “story meeting.” We usually have one or maybe two of them before shooting a myth, but discussions about stories can happen all over the place, and at any time.

Often, we’ll ask for certain parameters as far as locations or materials, and as we discover what’s possible or not possible, we’ll hone it down to what we’re actually going to do. The show’s researchers are fantastic about finding the weirdest of things and experts, and Alice is brilliant at keeping us on track. The discussions can be like herding cats — there’s a ribald, funny atmosphere, and we’ll range very far from the topic at hand.

Planning can take anywhere from a month to a day or two, depending on the schedule. We’ve had critical locations fall through at the last minute, and needed to turn 180 degrees on a few hours’ notice. We’ll also flag difficult stories as far in advance as we think necessary. Some things, like getting permission to film at Giants Stadium for the Jimmy Hoffa story, have taken the better part of a year to work out.

Then there’s the discussions that Jamie and I have. We’ll often take a difficult problem home, think about it overnight, and maybe discuss the problems we see in it while driving to a location. We also play devil’s advocate with each other — if one of us has a good idea, the other will poke as many holes in it as possible, and in this way we try our best to shake out any problems before we hit them.

JAMIE: This is, believe it or not, the most fun we have on the show. There is no underestimating the thrill of a big catastrophe or explosion; but if you really want to know what gets us going, it’s the brainstorming. Once a topic has passed muster, some basic research has been done by our research team, and we are down to nutting it out, Adam and I swing into action — sort of. Usually we go home first and think about it overnight, and then come in bursting with ideas. We set up in front of a dry erase board, and lay out any solutions we came up with by ourselves.

Amazingly, as much as we are of different temperaments, we quickly spot the best solutions and chip in to flesh the approach out. It becomes like playing Ping-Pong with ideas. Sometimes it gets so intense that there is no time to complete sentences; it becomes a bunch of gesticulations, some pieces of words or phrases, and then, when we come out on the other end, the approach is fleshed out. We call it the “MythBusters Mindmeld.” To anyone listening, it is gibberish, but it allows us to plow through a huge amount of designing in no time (which is what we have a lot of on the show).

Read the rest of the interview.

Scripturizer in PHP

UPDATE 12/23/2004: I've moved my version of the code to the new WP Plugins repository, so you can download it at http://dev.wp-plugins.org/file/scripturizer/trunk/scripturizer.php

UPDATE: plans are afoot to merge the three existing codebases (Dean's, Scott Yang's, and this one) into a single Sourceforge project. (UPDATE 12/23/2004: nothing has really come of that--we're all a little busy and haven't really worked to make it happen. Oh well...)


Not realizing that Mean Dean was porting Scripturizer to PHP, I went ahead and did it so that I could begin using it on this Wordpress site. At about the same time Scott Yang made one, so there are two versions out there. Sorry about that.

I originally wasn't going to package it for release, but it turns out that I had to do it to actually use it on my site :), and so I figured I might as well put it in the public version to make it easy for anyone else to use. Also, figuring out how to use add_action was nonobvious (at least when I first did this--I believe the documentation has improved considerably), so I wanted to provide a clear example.

It extends the functionality of the original and also changes the data permanently in the user's database (as opposed to Scott's, which filters it on the fly). You can set mine to do that (see the source code), but Scott's will work that way out of the box. Which you prefer is up to you. Mine is more efficient, his affects all the archives without making you manually edit anything.

Usage: just copy the source code to a file named scripturize.php in your wp-content/plugins folder. Go to your administration panel, click on Plugins, and activate it. Then just refer to the Bible in your posts. If you don't want a Bible reference hyperlinked, be sure to enclose it in preformatting tags, like so:

<pre>John 3:16</pre>

Changes from Dean's original:

  • You can specify a translation you want to link to by putting the standard abbreviation after the reference like so: John 3:16, NIV or 2 Cor 5:20 (NET). This one is huge, for me.
  • Added New English Translation. I like this translation for several reasons, but mostly for its philosophical underpinnings.
  • Made syntax a little more permissive. For instance, you can now specify a reference by saying Gen. 12:1 or Gen 12:1 (period/no period).
  • Made syntax a little less permissive as regards whitespace. Just write things normally and everything will work fine (I changed this to correct some errors I was seeing wherein the link would run into the blank space after the reference).
  • The regular expressions handle linking a little bit differently. It does something more useful when confronted with a crazy reference like Rom 1:3, 5-8, 10,12 that the online Bibles don't know what to do with.
  • As I mentioned, by default it will actually change your post as stored in your database. Forever. Irreversibly. With no backup. Just be aware of that.
  • You can now specify a default translation. It is initially set to the NIV, because I assume that's what most people will want.

Please Report Bugs In Bug Tracker
I'd really like to know if you catch any bugs. I use this plugin myself, so bugs directly affect me! :)
There is a bug tracker set up at http://dev.wp-plugins.org/newticket, so please report any problems there.

Daily Bible Readings

I woke up early this morning and had this thought about daily Bible reading plans (namely, that it would be good to have one on our website).

So I added it on the top left of the screen. Just wanted to draw your attention to it.

I figured it would be pretty easy to set one up using PHP and MySQL, but I didn't want to have to do a ton of data entry. Rather than reinventing the wheel, I searched for an online tabulation of Bible readings. I found a good one at Bible-reading.com.

I copied the plan into Word and used the search and replace features to format all the readings into 364 SQL INSERT statements (the number of readings in this plan). I added two more (thereby insuring that the database always has the data that I query for even in a leap year. Side note: I picked these somewhat at random and they're probably not great choices, especially the Matthew reading).

Then I created some quick PHP code to take the current day of the year and look up the corresponding reading. I took the output and made it compatible with Bible Gateway and voila--an easy online Bible reading plan!

The code was very straightforward:

PHP:
  1. $date=getdate();
  2. $day=$date['yday'];
  3.  
  4. $link = mysql_connect(*put your own info here*);
  5.  
  6. mysql_select_db(*your database*);
  7.  
  8. $sql=sprintf("SELECT * FROM bible_reading WHERE day='%d'",$day);
  9.  
  10. $result=mysql_query($sql);
  11.  
  12. $line = mysql_fetch_array($result, MYSQL_ASSOC);
  13.  
  14. $passage=$line["passage"];
  15.  
  16.  
  17. mysql_close($link);
  18.  
  19. $URL=sprintf("http://bible.gospelcom.net/cgi-bin/bible?language=english&passage=%s&version=NIV",urlencode($passage));
  20.  
  21. printf("Bible Reading for %s",date('l F jS'));
  22.  
  23. printf("<a href='%s'>%s</a>",$URL,$passage);

That's pretty much it. It turned out to be a piece of cake!

The data entry would have been horrible--but I was able to avoid that hassle. If you need the SQL statements for any reason, you can use these:

SQL:
  1. CREATE TABLE `bible_reading` (
  2.   `day` int(11) NOT NULL DEFAULT '0',
  3.   `passage` varchar(255) NOT NULL DEFAULT '',
  4.   PRIMARY KEY  (`day`)
  5. ) TYPE=MyISAM;
  6.  
  7. #
  8. # Dumping data for table `bible_reading`
  9. #
  10.  
  11. INSERT INTO `bible_reading` VALUES (1, 'Romans 1-2');
  12. INSERT INTO `bible_reading` VALUES (2, 'Genesis 1-3');
  13. INSERT INTO `bible_reading` VALUES (3, 'Joshua 1-5');
  14. INSERT INTO `bible_reading` VALUES (4, 'Psalms 1-2');
  15. INSERT INTO `bible_reading` VALUES (5, 'Job 1-2');
  16. INSERT INTO `bible_reading` VALUES (6, 'Isaiah 1-6');
  17. INSERT INTO `bible_reading` VALUES (7, 'Matthew 1-2');
  18. INSERT INTO `bible_reading` VALUES (8, 'Romans 3-4');
  19. INSERT INTO `bible_reading` VALUES (9, 'Genesis 4-7');
  20. INSERT INTO `bible_reading` VALUES (10, 'Joshua 6-10');
  21. INSERT INTO `bible_reading` VALUES (11, 'Psalms 3-5');
  22. INSERT INTO `bible_reading` VALUES (12, 'Job 3-4');
  23. INSERT INTO `bible_reading` VALUES (13, 'Isaiah 7-11');
  24. INSERT INTO `bible_reading` VALUES (14, 'Matthew 3-4');
  25. INSERT INTO `bible_reading` VALUES (15, 'Romans 5-6');
  26. INSERT INTO `bible_reading` VALUES (16, 'Genesis 8-11');
  27. INSERT INTO `bible_reading` VALUES (17, 'Joshua 11-15');
  28. INSERT INTO `bible_reading` VALUES (18, 'Psalms 6-8');
  29. INSERT INTO `bible_reading` VALUES (19, 'Job 5-6');
  30. INSERT INTO `bible_reading` VALUES (20, 'Isaiah 12-17');
  31. INSERT INTO `bible_reading` VALUES (21, 'Matthew 5-7');
  32. INSERT INTO `bible_reading` VALUES (22, 'Romans 7-8');
  33. INSERT INTO `bible_reading` VALUES (23, 'Genesis 12-15');
  34. INSERT INTO `bible_reading` VALUES (24, 'Joshua 16-20');
  35. INSERT INTO `bible_reading` VALUES (25, 'Psalms 9-11');
  36. INSERT INTO `bible_reading` VALUES (26, 'Job 7-8');
  37. INSERT INTO `bible_reading` VALUES (27, 'Isaiah 18-22');
  38. INSERT INTO `bible_reading` VALUES (28, 'Matthew 8-10');
  39. INSERT INTO `bible_reading` VALUES (29, 'Romans 9-10');
  40. INSERT INTO `bible_reading` VALUES (30, 'Genesis 16-19');
  41. INSERT INTO `bible_reading` VALUES (31, 'Joshua 21-24');
  42. INSERT INTO `bible_reading` VALUES (32, 'Psalms 12-14');
  43. INSERT INTO `bible_reading` VALUES (33, 'Job 9-10');
  44. INSERT INTO `bible_reading` VALUES (34, 'Isaiah 23-28');
  45. INSERT INTO `bible_reading` VALUES (35, 'Matthew 11-13');
  46. INSERT INTO `bible_reading` VALUES (36, 'Romans 11-12');
  47. INSERT INTO `bible_reading` VALUES (37, 'Genesis 20-23');
  48. INSERT INTO `bible_reading` VALUES (38, 'Judges 1-6');
  49. INSERT INTO `bible_reading` VALUES (39, 'Psalms 15-17');
  50. INSERT INTO `bible_reading` VALUES (40, 'Job 11-12');
  51. INSERT INTO `bible_reading` VALUES (41, 'Isaiah 29-33');
  52. INSERT INTO `bible_reading` VALUES (42, 'Matthew 14-16');
  53. INSERT INTO `bible_reading` VALUES (43, 'Romans 13-14');
  54. INSERT INTO `bible_reading` VALUES (44, 'Genesis 24-27');
  55. INSERT INTO `bible_reading` VALUES (45, 'Judges 7-11');
  56. INSERT INTO `bible_reading` VALUES (46, 'Psalms 18-20');
  57. INSERT INTO `bible_reading` VALUES (47, 'Job 13-14');
  58. INSERT INTO `bible_reading` VALUES (48, 'Isaiah 34-39');
  59. INSERT INTO `bible_reading` VALUES (49, 'Matthew 17-19');
  60. INSERT INTO `bible_reading` VALUES (50, 'Romans 15-16');
  61. INSERT INTO `bible_reading` VALUES (51, 'Genesis 28-31');
  62. INSERT INTO `bible_reading` VALUES (52, 'Judges 12-16');
  63. INSERT INTO `bible_reading` VALUES (53, 'Psalms 21-23');
  64. INSERT INTO `bible_reading` VALUES (54, 'Job 15-16');
  65. INSERT INTO `bible_reading` VALUES (55, 'Isaiah 40-44');
  66. INSERT INTO `bible_reading` VALUES (56, 'Matthew 20-22');
  67. INSERT INTO `bible_reading` VALUES (57, '1 Corinthians 1-2');
  68. INSERT INTO `bible_reading` VALUES (58, 'Genesis 32-35');
  69. INSERT INTO `bible_reading` VALUES (59, 'Judges 17-21');
  70. INSERT INTO `bible_reading` VALUES (60, 'Psalms 24-26');
  71. INSERT INTO `bible_reading` VALUES (61, 'Job 17-18');
  72. INSERT INTO `bible_reading` VALUES (62, 'Isaiah 45-50');
  73. INSERT INTO `bible_reading` VALUES (63, 'Matthew 23-25');
  74. INSERT INTO `bible_reading` VALUES (64, '1 Corinthians 3-4');
  75. INSERT INTO `bible_reading` VALUES (65, 'Genesis 36-39');
  76. INSERT INTO `bible_reading` VALUES (66, 'Ruth');
  77. INSERT INTO `bible_reading` VALUES (67, 'Psalms 27-29');
  78. INSERT INTO `bible_reading` VALUES (68, 'Job 19-20');
  79. INSERT INTO `bible_reading` VALUES (69, 'Isaiah 51-55');
  80. INSERT INTO `bible_reading` VALUES (70, 'Matthew 26-28');
  81. INSERT INTO `bible_reading` VALUES (71, '1 Corinthians 5-6');
  82. INSERT INTO `bible_reading` VALUES (72, 'Genesis 40-43');
  83. INSERT INTO `bible_reading` VALUES (73, '1 Samuel 1-5');
  84. INSERT INTO `bible_reading` VALUES (74, 'Psalms 30-32');
  85. INSERT INTO `bible_reading` VALUES (75, 'Job 21-22');
  86. INSERT INTO `bible_reading` VALUES (76, 'Isaiah 56-61');
  87. INSERT INTO `bible_reading` VALUES (77, 'Mark 1-2');
  88. INSERT INTO `bible_reading` VALUES (78, '1 Corinthians 7-8');
  89. INSERT INTO `bible_reading` VALUES (79, 'Genesis 44-47');
  90. INSERT INTO `bible_reading` VALUES (80, '1 Samuel 6-10');
  91. INSERT INTO `bible_reading` VALUES (81, 'Psalms 33-35');
  92. INSERT INTO `bible_reading` VALUES (82, 'Job 23-24');
  93. INSERT INTO `bible_reading` VALUES (83, 'Isaiah 62-66');
  94. INSERT INTO `bible_reading` VALUES (84, 'Mark 3-4');
  95. INSERT INTO `bible_reading` VALUES (85, '1 Corinthians 9-10');
  96. INSERT INTO `bible_reading` VALUES (86, 'Genesis 48-50');
  97. INSERT INTO `bible_reading` VALUES (87, '1 Samuel 11-15');
  98. INSERT INTO `bible_reading` VALUES (88, 'Psalms 36-38');
  99. INSERT INTO `bible_reading` VALUES (89, 'Job 25-26');
  100. INSERT INTO `bible_reading` VALUES (90, '