12.02.2006

All your google are belong to us

I'm a google-whore. I freely admit this. I use a ton of their tools. Gmail. Calendar. The personalized search home page complete with widgets (or whatever google calls them, probably googets). Yahoo has the same tools and Ask.com is catching up with some neat stuff but still, google rules. Their tools are just dead simple to use. However, today I realized that their Search History tool is now saving my data for all of the following searches:
  • Web
  • Images
  • News
  • Froogle
  • Video
  • Maps
  • Music
That concerns me. Not so much the web stuff because I routinely go in there and clean up the search history. I do this not because I'm searching things that I don't want anyone to know about, but more because I like my search history to revolve around my professional searching on programming and whatnot. It's easier and faster to find things in there that way (note to google, should let users tag their searched and clicked items). What concerns me though is the map history. I've already become anal enough that I don't use my exact address when looking to get driving directions somewhere. I use my neighbors down the street. But now my neighbors address is stored in there. And now when I bring up my contacts in gmail, I can get a map to my friends and relatives houses, but of course then their addresses are in the search history too. I worry about this being some kind of junk mail magnet in the future. Or worse, some kind of google as big brother scenario where they know everything about you and everywhere you go. I may have to rethink my life as a google-whore and my utter addiction to their tools.

11.17.2006

How to create and use multiple profiles using the Profile Manager of Firefox

What's cool about this is that you can use one profile with all your nice web developer extensions set up and another for quick browsing with no extensions installed.  I find using a few extensions tends to bog Firefox down (even still today) so doing without some when I'm just cruising around killing time is quite nice.

The following was lifted from the mozilla site if memory serves me.

In order to create a new profile, you use the Profile Manager.

To start the Profile Manager in Windows, follow these steps:
  1. Close Firefox completely (select File > Exit from the main menu of Firefox).
  2. Select Start > Run... from the Windows Start menu.
  3. Enter firefox.exe -ProfileManager and press OK.

On Linux or Mac, start Firefox with the -ProfileManager switch, e.g. ./firefox -ProfileManager (this assumes that you're in the firefox directory)

// end lift

10.05.2006

DB2 Creating (faking) a Boolean datatype

When creating a table in DB2, to create a Boolean datatype column (since DB2 doesn’t have this natively) you have to use a check constraint on a smallint column. So if you have a column named “ACTIVE” that you want to be Boolean, you would create the that col like so: ACTIVE SMALLINT NOT NULL, CONSTRAINT CCACTIVE1 CHECK (ACTIVE in(0,1)) Then obviously, when you use that field, you can only insert/update using 1 and 0 respectively for your true and false values.

DB2 Creating Sequences to use with Primary Key ID fields

Well, another job and another database system to learn. I've got practically all of them under my belt now ;-) I finished reading this article on sequences vs key managers vs identity columns and decided I needed to go with a sequence. To create a new sequence called “USERS_SEQ” for a schema named “TEST” CREATE SEQUENCE TEST.USERS_SEQ AS BIGINT START WITH 1 INCREMENT BY 1 NO MAXVALUE NO CYCLE; To use that sequence to generate unique, incremented, primary key IDs for a table: INSERT INTO TEST.USERS (id, name_first) VALUES (NEXTVAL FOR TEST.USERS_SEQ, 'Rich'); To use that generated id value, you can use PREVVAL to get it back

8.18.2006

VS2005 Errors when creating .aspx pages that retrun XML or JSON

I kept getting this on a page that did nothing but reference a code behind.

Validation(): Element 'html' occurs too few times.

This is because VS2005 is performing HTML validation by default. Yuk. You can turn this off by going to:
  • Tools --> Options --> Text Editor --> HTML --> Validation
  • Uncheck the "Show Errors" checkbox

Voila!

8.16.2006

Handy AJAX data structures using JSON, XML, ADODB, PHP, and Mysql

I'm working on a project where I thought a little AJAX magic would help the user interface a bit, so I've been adding that functionality piece by piece. For this web site, we've previously standardized on using the ADODB PHP database abstraction library for all our queries.

The particular circumstances of the XMLHttpRequest callbacks usually required a few small rows of data to be returned. So, the challenge became how to use the ADODB record sets to create structures that were nice and portable for use with AJAX. Most of the examples of JSON code shows only the properties of one object being displayed. But to return multiple rows, you basically need an object with an object (ie, rows within a dataset)
There's currently quite a debate raging on whether to return XML or JSON for manipulating via JavaScript. I use both approaches depending on the situation but find that I prefer JSON the most. Here are functions for ADODB that will return both XML and JSON as well as examples of usage. These files can be copied from below or downloaded at:

http://www.boringguys.com/example_code/adodb/toxml.inc.txt
http://www.borignguys.com/example_code/adodb/tojson.inc.txt

Just remember to rename them to .php !!

Here's that same code:

toxml.inc.php
/** 
* Creates XML from the ADODB record set 
* 
* @param     object         $rs         - record set object 
* @param     bool        $moveFirst    - determines whether recordset is returned to first record 
* @return     string        $xml        - resulting xml 
* @version V1.0  10 June 2006  (c) 2006 Rich Zygler ( http://www.boringguys.com/ ). All rights reserved. 
* 
*    Released under both BSD license and Lesser GPL library license. You can choose which license 
*    you prefer. 
*/ 

function rs2xml($rs, $moveFirst = false) 
{ 
  if (!$rs) 
  { 
    printf(ADODB_BAD_RS,'rs2xml'); 
    return false; 
  } 

  $xml = ''; 
  $totalRows = 0; 
  $totalRows = $rs->numrows(); 

  $domxml = new DOMDocument('1.0', 'utf-8'); 
  $root = $domxml->appendChild($domxml->createElement('rows')); 
  $root->setAttribute('total-rows', $totalRows); 

  $row_count = 1; 
  while($line = $rs->fetchRow()) 
  { 
    $row = $root->appendChild($domxml->createElement('row')); 

    foreach ($line as $col_key => $col_val) 
    { 
      $col = $row->appendChild($domxml->createElement('column')); 
      $col->setAttribute('name', strtolower($col_key)); 
      $col->appendChild($domxml->createTextNode($col_val)); 
    } 
    $row_count++; 
  } 
  $domxml->formatOutput = true; 
  $xml = $domxml->saveXML(); 
  $domxml = null; 

  if ($moveFirst) 
  { 
    $rs->MoveFirst(); 
  } 
  return $xml; 
} 


tojson.inc.php
/** 
* Creates JSON ( http://www.json.org/ ) from the ADODB record set 
* 
* @param     object         $rs         - record set object 
* @param     bool        $moveFirst    - determines whether recordset is returned to first record 
* @return     string        $output        - resulting json string 
* @version V1.0  10 June 2006  (c) 2006 Rich Zygler ( http://www.boringguys.com/ ). All rights reserved. 
* 
*    Released under both BSD license and Lesser GPL library license. You can choose which license 
*    you prefer. 

Example output from query  "SELECT Name, Continent From Country LIMIT 10;" 

{"rows":[ 
{"row":{"Name":"Afghanistan","Continent":"Asia"}}, 
{"row":{"Name":"Netherlands","Continent":"Europe"}}, 
{"row":{"Name":"Netherlands Antilles","Continent":"North America"}}, 
{"row":{"Name":"Albania","Continent":"Europe"}}, 
{"row":{"Name":"Algeria","Continent":"Africa"}}, 
{"row":{"Name":"American Samoa","Continent":"Oceania"}}, 
{"row":{"Name":"Andorra","Continent":"Europe"}}, 
{"row":{"Name":"Angola","Continent":"Africa"}}, 
{"row":{"Name":"Anguilla","Continent":"North America"}}, 
{"row":{"Name":"Antigua and Barbuda","Continent":"North America"}} 
]} 

*/ 

function rs2json($rs, $moveFirst = false) 
{ 
  if (!$rs) 
  { 
    printf(ADODB_BAD_RS,'rs2json'); 
    return false; 
  } 

  $output = ''; 
  $rowOutput = ''; 

  $output .= '{"rows":'; 
  $totalRows = $rs->numrows(); 

  if($totalRows > 0) 
  { 
    $output .= '['; 
    $rowCounter = 1; 
    while ($row = $rs->fetchRow()) 
    { 
      $rowOutput .= '{"row":{'; 
      $cols = count($row); 
      $colCounter = 1; 
      
      foreach ($row as $key => $val) 
      { 
        $rowOutput .= '"' . $key . '":'; 
        $rowOutput .= '"' . $val . '"'; 

        if ($colCounter != $cols) 
        { 
          $rowOutput .= ','; 
        } 
        $colCounter++; 
      } 

      $rowOutput .= '}}'; 

      if ($rowCounter != $totalRows) 
      { 
        $rowOutput .= ','; 
      } 
      $rowCounter++; 
    } 
    $output .= $rowOutput . ']'; 
  } 
  else 
  { 
    $output .= '"row"'; 
  } 

  $output .= '}'; 

  if ($moveFirst) 
  { 
    $rs->MoveFirst(); 
  } 
  return $output; 
} 


Example Usage

Place both of the files into your existing ADODB directory. If you don't already have the "world" sample database from mysql set up, please go and get it and install it ( http://dev.mysql.com/doc/ ). Make sure that the toxml and tojson files from above are placed in your adodb/ dir. Then use the following sample pages. Make sure to change your db settings in the file to what's appropriate. You will need PHP5 for the XML example. But you could easily mock up a version of that in PHP4, or you could always use this.

To test it out just do something like this for xml


or this for json

Bug in CareerBuilder.com saved job search

This stuff drives me nuts.
  • Go to careerbuilder.com. Set up an account if you don't already have one
  • Add a job search, save it as an agent (or whatever they call it)
  • Now, when you go to your "my careerbuilder" you'll see a list of local jobs and your saved searches below that.
  • Click edit on your job search. Change the mileage (include jobs within: X miles)
  • Click "Save Edits." Watch in amazement as your mileage change is NOT saved

The only way to accurately save this change to your searches is to delete your current search and add another with the proper mileage constraints.

8.02.2006

How to get a C# class to talk to Mysql in under 5 minutes

I had to access a Mysql database at work today using C# and .NET. Well, I didn't have to... but I wanted to... and I had some down time. I'm mainly a PHP guy, but C# is similar enough to C/C++ that I figured out what I needed to do in a few minutes. I think it's always important to step out of your safe little world every now and again to try something radically different. It keeps your problem solving skills fresh.

Here's the rundown for those interested.
  • Download Mysql Connector/Net package http://dev.mysql.com/downloads/connector/net/1.0.html
  • While you're there, if you don't have the Mysql sample db "world" set up on your server, you should get that too at http://dev.mysql.com/doc/ (I'm assuming you know how to set this upin Mysql.
  • Install it on the Windows server you are using (and on your dev machine too)
  • Open up Visual Studio (2k5 if you got it)
  • Open up yer C# project
  • In the References of your project, Add a reference to the Mysql Connector. You'll probably need to go to the "browse" tab and go find it. The default install puts a Mysql.Data.dll in C:\Program Files\MySQL\MySQL Connector Net 1.0.7\bin\.NET 2.0
  • For my sample below, you'll also need to add the System and System.Data .NET references
  • Then plop this test code into a C# project. This example is just a stand-alone console app to get you going. There's plenty of documentation at http://www.mysql.org/doc/refman/4.1/en/connector-net.html to keep you motivated.
using MySql.Data.MySqlClient; 

class mysql 
{ 
  static void Main() 
  { 
    MySqlConnection conn; 
    string myConnectionString; 

    myConnectionString = "server=localhost;user id=test; pwd=test;database=world;"; 

    try 
    { 
      conn = new MySqlConnection(); 
      conn.ConnectionString = myConnectionString; 
      conn.Open(); 

      string sql = "SELECT Name, Continent FROM Country Limit 10"; 

      MySqlCommand cmd = new MySqlCommand(); 
      MySqlDataReader results; 
      cmd.CommandText = sql; 
      cmd.Connection = conn; 
      results = cmd.ExecuteReader(); 

      while (results.Read()) 
      { 
        //string f1 = results.GetString(0); 
        //int f2 = results.GetInt32(1); 
        System.Console.WriteLine(results.GetString(0) + ", " + results.GetString(1)); 
      } 

      results.Close(); 
      System.Console.ReadLine(); 
    } 
    catch (MySqlException ex) 
    { 
      System.Console.WriteLine("error" + ex.Message); 
      System.Console.ReadLine(); 
    } 
  } 
}

7.25.2006

XForms cometh to PHP ! Throw out HTML_Quickform?

PHP Architect has an article in their June 2006 issue about using XForms within PHP5. If you don’t know what XForms is/are, you’d better look into it. It’s basically a way to describe forms on your page and all the data validation rules entirely in XML. The form presentation and validation capabilities of it are kind of like HTML_Quickform on crack. Of course, there’s always a rub. No browsers natively support XForms. The article in PHPArch uses the FormFaces JavaScript to get things to work. But I don’t like the way FormFaces comes off. They tout both a GPL license and a commercial one but then they mask the JavaScript so you can’t extend it or see how it’s actually working. That smells like a temporary GPL license to me. So, I don’t think you could do XForms on the client side just yet. It’d be nice if someone would step up and create a server-based solution for XForms in PHP. Maybe I’ll do that myself. In the meantime though, the Quickform folks are already busy planning HTML_Quickform2, a PHP5 version of their form production code. That will have to do for now I suppose.

7.22.2006

Smarty not so smarty in PHP5. Try XSLT instead.

So I’ve been working on this pretty big migration project lately, from PHP4 / MySQL 4 to PHP5 / MySQL5. It’s even larger because we’re moving from a largely procedural code base to using objects with inheritance and a lot of composition.

So what’s all that have to do with Smarty? Well, all our PHP devs are busy getting familiar with the framework I’ve built for the project. So, that leaves some HTML gurus and ASP folks sitting around under-utilized on this project. Ideally, I’d like the PHP folks to work on the backend stuff and then have an HTML or ASP dev take care of the views.

Of course, if the templates are all done in Smarty that means these folks have to possess not only a decent understanding of PHP, but also thorough experience with Smarty templating. These skills are a bit of a reach for the HTML folks… and the ASP people will mostly just protest because they’d have to learn PHP stuff AND develop on a Linux box. ;-)

Enter XSLT. Most developers in other languages use XSLT already (ASP, .NET, JSP, etc). I’ve never understood why it’s so slow to catch on with PHP. Perhaps because the XML tools in PHP4 were so poor?

So if the ASP folks already know XSLT, and the HTML folks don’t yet, but can learn a templating skill that is basically development-language-agnostic, I think it’s a win-win-win situation.

I’ve thought this way for a long time but this project has really crystallized my take on it. Developers at any level should strive to learn tools and techniques that can be universally applied to other languages. You may be a PHP programmer today, but you might be something else tomorrow.

7.17.2006

Functionality of the PHP trim command I bet you did not know

trim

(PHP 3, PHP 4 , PHP 5)trim -- Strip whitespace from the beginning and end of a string

Description

string trim ( string str [, string charlist]) You can also specify the characters you want to strip, by means of the charlist parameter. Simply list all characters that you want to be stripped. With .. you can specify a range of characters. Example:

$strComma = "item 1, item 2, item 3,"; 
echo trim($strComma, ',');

7.13.2006

Best... Typo... Ever...

From: Sysadmin Subject: Server auto logout FYI Interactive logins on all unix machines will now automatically timeout after 1 hour of inactivity. If you are running a long-running job/script, this will be unaffected if it runs past an hour. If you are just shitting at a shell prompt, and haven't typed anything in an hour, you will be logged out. Feel free to pass this on to anyone else I may have missed.

7.10.2006

Load this Firefox bookmark in the sidebar

Bookmark a page in Firefox. Right click on the bookmark and select "properties." There's an option for "Load this bookmark in the sidebar." If you check that button, every time you click on that bookmark, it will open up in your sidebar. Pretty darn handy. Can't believe I didn't know about this before. Of course, the only things I bookmark locally anymore are internal apps.

This doesn't work in SeaMonkey though.

7.06.2006

Everybody else is doing the Ajax Whois, why not me?

A buddy at work fell in love with the Ajax Whois and wanted a version on his own linux site. I've been playing around with a lot of Ajax stuff lately so I thought I'd give it a go using Ajax (javascript) and PHP. Here's the resulting code. It's just a quick and dirty solution because I had some technical difficulties working on his crappy server. I couldn't upload anything (like the brilliant prototype js library) so I had to bake most of the js from scratch except for a line borrowed here and there, most notably from this guy. Of course the other informal rule was that it had to be completed during spare time at work today. It's just two files, index.php and whois.php (rename the saved files with .php extension). Download and enjoy your own web based ajax whois. Just be careful not to get yourself blacklisted by doing tons of searches in a short time period.

7.05.2006

Zend Studio Tip of the day -- Bookmarks

Ever need to refer to 2 or more different places in a file while in Zend? You can bookmark the sections for easy manuvering through the file. Put your cursor on the line you want to bookmark, and either right click the line number on the left or hit "F2." Voila! A green bookmark has been setup.

How do you use this puppy? Easy. Take a look at the right hand side of the editor window and you'll see a green line that is clickable, right next to the scroll bar. Clicking there takes you to that bookmark. Even cooler, if you hover over the bookmark line there, it will pop-up the line of code that is bookmarked.

If you need to remove the bookmark, you do the same thing, right click on the line number of hit F2 again.

Until next time... Happy Zending!

AOL Instant Messenger – Triton, Norton, Password problems

So I thought I’d forgo using my GAIM today, even though it's totally working correctly... and even though it completely connects to all my instant message accounts... and see if the new AOL Instant Messenger called Triton did anything interesting. It turns out it does not. The thing hardly even works. Ugh. Why do I even bother?


Frustration # 1

When I installed it, it left my old AOL messenger in there instead of just upgrading that one.



Frustration # 2

I couldn’t figure out which ports to open on my Norton software firewall. Even though I explicitly gave AIM6.exe permission to access the Internet, it was trying to use some odd port that I don’t have opened. I’m afraid it’s too new for the port info to be out in the wild yet. This one’s a deal-breaker for me, but it gets worse.



Frustration # 3

I had forgotten my password so I clicked the “forgot password” link which brought me to https://my.screenname.aol.com/ where I was able to answer some pre-determined security questions and then change my password. However, while the screens there reminded me to only use letters and numbers for the password, the web form neglected to check for other characters.

So without realizing this restriction, I used a symbol in my password. Of course when you get into AIM Triton (with no firewall of course), it keeps coming back that your username/password is incorrect. Because it sees that symbol and freaks out. This one stumped me for a good few minutes. You have to go back and change your password to not use any funny characters. This is form validation 101 people. Filter input. And give appropriate error messages.

Back to GAIM I go.

6.02.2006

Brake lights with 5 bars

I've been stuck in traffic while driving a lot lately.  Why don't car brake lights show how hard someone is braking?  It seems to me if we standardized on a size of brake light that could go on the back of every vehicle, that we could have 5 bars on it.  When the driver is braking hard, all 5 bars would be lit, when breaking moderately, only 3 bars would be lit, and when just tapping the brakes, only one bar would be lit. Maybe I'm just a sucker for standards like this.... but this idea would save everyone from having to evaluate the distance and speed of multiple cars while in stop and go traffic and would probably prevent a lot of minor accidents.  Somebody should start working on this.  

6.01.2006

PHP Zend Studio 5.2 Released with license for Zend Platform

From the email:
Zend is pleased to announce the release of Zend Studio 5.2 - now including a free developer license for Zend Platform allowing you to increase the reliability and maximize the performance of your application before deployment.

I've already downloaded the update and installed.  However, it's not clear how you actually get the license for the platform.  Hopefully they straighten that out so I can start playing with it.

 UPDATE: How to get the Zend Studio Platform and get it licensed.

5.08.2006

JSP to PHP and Back Again (with Netbeans)

Several years ago, I worked at a dotcom start-up working on JSP templates for an ATG system. I’ve dabbled in Java on and off for a few years, but I’ve mostly worked with PHP. Well, now I have a few projects at work coming up that require me to do some Java / JSP web development so I’ve been diving into everything there is that world.


Needless to say, the Java / JSP landscape has changed quite a bit since the year 2000.


I’ve mainly been concentrating my efforts right now on Tomcat. So I’ve started using Netbeans which has a bundled version of Tomcat. Pretty cool stuff. However, there’s quite a few things missing from the Netbeans tutorials.


Frustration # 1


When I launched a basic JSP page, I kept receiving the message: “Starting of tomcat failed, the server port 8084 is already in use


I thought maybe it was Apache so I shut that down. Then I shutdown Mysql, Postgresql and Oracle express (I like databases). Still nothing. Hmm… it worked at the office, but now not at home. What’s the difference? Ahh… the Norton firewall stuff. Once I disabled that, we were good to go. So, instead of leaving Norton off, I finally added the Tomcat ports (8084, 8081, and 8025) to the Norton rules.


Frustration # 2


When running the “Getting Started” Netbeans tutorial… about the second thing they have you do is to run a simple JSP page, but one that uses JSTL 1.1. When creating a new web app project, Netbeans creates an index.jsp file with some JSTL stuff in it. It's commented out but it's just begging to be played with. I thought this was kind of like going to med school and performing brain surgery your first day. But anyway, I uncommented the lines.



When attempting this, I received two main errors:


org.apache.jasper.JasperException: Failed to load or instantiate TagLibraryValidator class


The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved


After several minutes of searching, I realized, that you have to add the Tag Library within Netbeans to get this tutorial to work. You’d think they would just tell you that… and tell you how. Big strike agains Sun right there for me.


Anyway, you add the library like this:


  • Go to the properties of your project
  • go to library
  • add library
  • jstl 1.1
  • save
  • then run

Now to work up some basic CRUD functionality with MySQL. More notes as I discover and untangle my frustrations.

4.09.2006

Zend Inspectors Window

NOTE: Having recently started using Zend at work and at home for projects, I think it's a great product that has sped up my PHP development time quite a bit. I will therefore be posting some tips and tricks on its use in the following weeks.


The Inspectors Window displays the methods/functions and any included/required files for the PHP program that you are currently working on. For PHP class files, it will also show all the class variables (properties) and any other inherited methods.


To display the Inspectors Window in Zend, you can either go to the View menu and select Show/Hide Inspectors or click on the "Inspectors" area in the side navigation. Then you can click on the "File" button at the top of the window. You can also inspect all the files for a given "Project" but that's beyond the scope of this tip.


To test it out, bring up a PHP file that has functions in it, and look in the Inspectors area. It will show you all the functions available. It also shows the parameters that need to be sent for each function. If the function returns a value, the Inspectors window attempts to figure what data type the returned value is (that's why there's a lot of "unknowns" listed. The return value needs to be specified in comments using PHPDoc code (which will be a future tip).


Clicking on the function name in the Inspectors window takes you right to the code where the function is declared... kind of a function bookmarket. Pretty nifty.


When working with objects/class files, the Inspectors window is even more helpful. If you have any object inheritance, it will drill up into each parent object and show you those inherited methods as well. This means theres' hardly ever a need to do a print_r(get_class_methods($this));


If you have any questions on this, please feel free to ask. Until next time, happy inspecting!!

3.23.2006

Stupid Zend Humor

Here's a quick IM with another programmer at work

Tom (3/23/2006 1:49:54 PM): WHat did you do to my Zend?
Rich (3/23/2006 1:50:18 PM): nothin
Rich (3/23/2006 1:50:20 PM): why?

Tom (3/23/2006 1:50:37 PM): Froze for a minute
Rich (3/23/2006 1:53:12 PM): mine's been fine
Tom (3/23/2006 1:53:29 PM): seems better now
Rich (3/23/2006 1:53:55 PM): that's because I stopped running slow_toms_zend();
Tom (3/23/2006 1:54:05 PM):
Tom (3/23/2006 1:55:08 PM): You forgot the parameter: slow_toms_zend(xtra_slow_today);
Rich (3/23/2006 1:55:51 PM): there's a default set up in the function declaration:
Rich (3/23/2006 1:56:02 PM): function slow_toms_zend(xtra_slow_today = true)
Tom (3/23/2006 1:55:56 PM): and then there's the 'break his balls' parameter
Rich (3/23/2006 1:56:26 PM): no, that's a separate function
Rich (3/23/2006 1:56:47 PM): it's a public method in the PissTomOff class
Tom (3/23/2006 1:56:55 PM): ;-)
Rich (3/23/2006 1:57:00 PM): is it still slow?
Tom (3/23/2006 1:57:03 PM): No, but outlook crashed
Rich (3/23/2006 1:57:11 PM): Dude, you need a new computer. Or feed that hamster inside yours.