Chris Nizzardini, Salt Lake City Utah, Web Developer Specializing in LAMP+Ajax Since 2006

My Blog

Here is my awesome blog.

FbModal 0.9.x – A MooTools Window Modal Overlay

Posted by chris on June 2nd, 2010 Comments (7)

This MooTools javascript window modal overlay window is designed to look similar to the modal used by a prominent social networking site. I had been using the awesome MochaUI for modals, but I decided to develop my own lightweight solution after reading this blog post by David Walsh. I based the CSS and functionality off of his original code, but I enhanced the javascript by making it object oriented and leveraging mootools to create the DOM elements on the fly. I also added a few other helpful methods. It uses mootools 1.2.4 and has not been tested with other versions of mootools. It works well enough in most browsers (tested in FireFox, Chrome, and IE 8). There are known issues with IE6 and IE7, the issues are FbModal does not work. I’m working on getting an environment for IE6/7 testing, but until then I’d appreciate some help on that. Click here to view the demo. Lets get started.

*Updated for version 0.9.2
Read the rest of this entry »

In ajax/dom/javascript (, )

MooTools Table Sorter 0.9.5 – For Sorting MySQL Data via XHR…and looking good doing it.

Posted by chris on May 31st, 2010 Comments(0)

Well its been a long weekend and I’m starting to wrap it up. But I couldn’t go to bed without redoing the documentation for my baby the MooTools TableSorter and updating the demo page. The documentation will loosely follow what you see in the demo page.

HTML Setup

You’ll need to include 3 files: MooTools 1.2 or higher, the CSS file, and the Table Sorter javascript class. You’ll also want to make sure all the images are there and update the CSS image paths to jive with the location on your web server.

1
2
3
	<link rel="stylesheet" media="screen" href="/mootools/table-sorter/table-sorter.css" />
	<script type="text/javascript" src="/js/mootools1-2.js"></script>
	<script type="text/javascript" src="/mootools/table-sorter/table-sorter.js"></script>

PHP Setup

You’ll want to use the TableSorter php class I included to make things easy one you.

1
	include_once 'TableSorter.class.php';

Server Side First

Notice setting the table headers is important. For instance when a user clicks on city the TableSorter will send the ORDER BY stored in the TH Title. This is how your server side code will know what to order by. Reply to this post if you have any questions on the server-side PHP code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
	function returnGeoHtmlTableStr($whereClause='',$startingFromRecord=0,$rowsPerPage=100,$orderBy='city ASC')
	{
		mysql_connect('localhost','user','password','database');
		mysql_select_db('database');
 
		$startingFromRecord = (int) $startingFromRecord;
		$rowsPerPage = (int) $rowsPerPage;
 
		$sql = "SELECT 
					count(*) as count 
				FROM 
					cnizz_geo 
 
				$whereClause
 
				";
		$result = mysql_query($sql);
		$countArr = mysql_fetch_assoc($result);
		$totalRows = $countArr['count'];
 
		if($orderBy==''){
			$orderBy='city ASC';
		}
 
		$sql = "SELECT SQL_CALC_FOUND_ROWS
					* 
				FROM 
					cnizz_geo 
 
				$whereClause
 
				ORDER BY 
					$orderBy
				LIMIT 
					$startingFromRecord,$rowsPerPage
				";
		$result = mysql_query($sql);
		$arr = array();
		while($row=mysql_fetch_assoc($result)){
			$arr[]=$row;
		}
 
		$sql = "SELECT FOUND_ROWS() as totalRows";
		$result = mysql_query($sql);
		$foundArr=mysql_fetch_assoc($result);
 
		$str = '
			<table class="DefaultTable" style="width:500px;">
			'.TableSorter::returnMetaStr($startingFromRecord,$rowsPerPage,$foundArr['totalRows'],count($arr),$orderBy).'
			<tr style="background:#FFF;"><td colspan="10" style="height:5px;">&nbsp;</td></tr>
			<tr id="GeoHead" class="DefaultTableHeader">
				<th id="City" title="'.(($orderBy=='city ASC')?'city DESC':'city ASC').'">City</th>
				<th id="State" title="'.(($orderBy=='state ASC')?'state DESC':'state ASC').'">State</th>
				<th id="Abbrev" title="'.(($orderBy=='state_abbrev ASC')?'state_abbrev DESC':'state_abbrev ASC').'">State</th>
				<th id="County" title="'.(($orderBy=='county ASC')?'county DESC':'county ASC').'">County</th>
			</tr>
			';
		$x=1;
 
		foreach($arr as $i)
		{
			if($x%2){
				$class='';
			}
			else{
				$class='zebra';
			}
			$str.= '<tr class="'.$class.'">
								<td><a id="'.$i['city'].'" title="'.stripslashes($i['city_id']).'">'.stripslashes($i['city']).'</a></td>
								<td>'.$i['state'].'</td>
								<td>'.$i['state_abbrev'].'</td>
								<td>'.$i['county'].'</td>
							</tr>';
			$x++;
		}
 
		$str.= '<tr style="background:#FFF;"><td colspan="10" style="height:5px;">&nbsp;</td></tr>';
		$str.=$meta.'</table>';
		return $str;
	}

Your Server Side Controller

1
2
3
if($_GET['action']=='returnGeoHtmlTableStr'){
	die(returnGeoHtmlTableStr('',$_GET['start'],$_GET['rows'],$_GET['orderBy']));
}

Now the JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
	window.addEvent('domready',function(){
		sorter = new TableSorter({
			request: 'action', 
			action: 'returnGeoHtmlTableStr', 
			destination: 'XhrDump', 
			prev: 'PagePrev', 
			next: 'PageNext', 
			head: 'GeoHead',
			rows: 100,
			startWait: "",
			endWait: ""
		});
	})

Lets explain this line by line.

  1. request: ‘action’, This is how you name the GET parameter. So in this instance the GET looks like $_GET['action']
  2. action: ‘returnGeoHtmlTableStr’, This is the value of GET parameter defined in step 1, so $_GET['action'] = ‘returnGeoHtmlTableStr’
  3. destination: ‘XhrDump’, This is the element id where TableSorter will write results too
  4. prev: ‘PagePrev’, This is the element that the class will listen on for Previous Page requests.
  5. next: ‘PageNext’, Same as above except it goes to the next page when this element is clicked
  6. head: ‘GeoHead’, This tells the class where to look for all those TH tags, which it uses to do sorts on if a Title is defined on the TH tag.
  7. rows: 100, How many rows should the request return.
  8. page: location.href, Where to send the GET request
  9. method: ‘get’, The type of method (GET or POST). By default the method is get, but you can change it to post.

Other cool stuff you can do

You can add additional parameters to the GET request in the form of parameter name => parameter value.

1
sorter.addParameter('zipcode','84101');

You can remove these user-defined parameters by calling removeAllParameters.

1
sorter.removeAllParameters();

You can remove a specific parameter by calling removeParameter.

1
sorter.removeParameter('zipcode');

You can initiate a sort anytime you want by calling sort.

1
sorter.sort();

At the moment this is all it does. There are some known issues in IE where the up/down arrows will not appear on sorts. Also the visual-effects are a bit degraded in IE as well. However it does work in IE and all other major browsers. I have windows-only clients using this right now, as well as FireFox and Safari only clients using it. I’ll be releasing a new version later this Summer based on bug fixes to production installs and feature enhancements I have running in the wild. Please reply to this blog post with any comments, bugs, or questions. Enjoy.

In rant (, )

Faster Mass SQL Inserts With MySQL and PHP

Posted by chris on May 31st, 2010 Comments(0)

I was programming some code that needed to do a lot of inserts a few months back. I hypothesized that creating a big SQL insert statement would be faster than executing a bunch of small insert statements. I didn’t have time to create a test, but I wanted to go back and test this theory at some point. The idea was that even though there is a penalty for looping through an array and accessing a variable to build the SQL statement that it would still be faster than asking PHP to send a bunch of tiny querries.

My test server is my local machine running Ubuntu 10.04, dual 1.80Ghz core Intel processors with 2 GB of memory. Its running the latest stable release of PHP5, Apache2, and MySql5. I used the standard php mysql_connect function, not mysqli. The database engine used in this test was MyIsam. I performed 1000 inserts in the first test, I then altered the code to build one giant insert. I restarted the apache and mysql server after the first scenario.

Read the rest of this entry »

In SQL, php ()

Holiday Weekend: Why not redesign my site!

Posted by chris on May 30th, 2010 Comment(1)

I’ve been sitting on this new design for over two months now and found myself up early Saturday morning with no pressing matters or client work to be done. Reward myself with a relaxing morning, right? Nah, find something to program! I based the design off many designs I’ve seen out there in the wild from other developers and designers. The polaroid type image of me was done in about 30 minutes using a GIMP tutorial I found last week. I then installed the awesome WP Syntax plugin for the neat syntax highlighting you see in some of my posts. Still have some work to do, but I’m spent for now.

Now I’ll reward myself with some beer pong and barbecue. Enjoy your memorial day.

In rant ()

Fix Gnome Vino Server (VNC) From Randomly Closing on Ubuntu

Posted by chris on March 19th, 2010 Comments(0)

I’m not a fan of Gnomes implementation of the VNC Server on Ubuntu. It is always randomly closing on me. If you have SSH access to your desktop though you can remotely start the vino-server allowing you to once again VNC in.

Simply create the following script and name it something like start-vino.sh:

1
2
3
4
5
#!/bin/bash
gconftool-2 -s -t bool /desktop/gnome/remote_access/enabled true
gconftool-2 --type bool --set /desktop/gnome/remote_access/prompt_enabled 0
export DISPLAY=:0.0
/usr/lib/vino/vino-server

Now chmod the script 744, giving only you the owner the ability to execute and modify the file. Next time your vino server dies, tunnel into your desktop and run this script. You can find more information by viewing this Ubuntu Forum thread.

In linux (, , )

Type Casting In PHP To Prevent XSS and SQL Injection

Posted by chris on March 14th, 2010 Comment(1)

Lots of developers think the best way to prevent XSS and SQL injection attacks are by passing all user input through a filter function. If you’re one of these developers don’t worry, you’re still right. There is a better (less code and less CPU cycles) way to do this on certain user inputs though. Type casting to integers should be used on all user inputs that should be a numeric value. This ensures that a valid data type is being used and it automatically converts any strings to an integer. This effectively prevents any SQL injection or XSS attacks.

1
$customer_id = (int) $_POST['customer_id'];

This automatically prevents someone from being able to pass in something like:

1
1' OR 1='1

or

1
window.location 'aol.evilcloneofaol.com'
In php (, , , )

So What Is The Difference Between Web Developers and Web Designers?

Posted by chris on February 24th, 2010 Comments (2)

I get asked this question one way or another all the time. Either its someone actually trying to understand the difference (and there is a huge difference) or by people I am introducing myself to when they ask me what I do for a living. In the later sense they usually respond with “Oh so you know how to build web pages.” This doesn’t bother me, but I’m still a little dumbfounded with the prevalence of obvious web applications like facebook, myspace, and twitter in peoples lives.

We’re all guilty of this though, right? I have a friend who is a plumber and he had to explain the difference between commercial and residential plumbing to me, and even within those branches of plumbing there are specialties but we won’t go into those today.

I was explaining the difference to my girlfriend the other night. I was a bit intoxicated so I came up with an over the top analogy of the Sistine Chapel. The way I broke it down was you can liken the architect and the builders to web developers and Michelangelo and the painters as the web designer. So the web developer gives a website functionality. Its the web developer that enables you to submit your latest tweet, update your facebook status, and add all those images to myspace. Its the web designer who makes it look good. Now I over simplified the web designers job, they need to know a lot about how users view a page, how to catch a users eye, and web designers are usually damn good in PhotoShop (which has gotten pretty complex).

Another example is the engine and drivetrain in an automobile (web developers) versus the body, interior, and paint job (web designer). These two analogies are fairly accurate. Thoughts?

In rant ()

MySQL engines, InnoDb versus MyISAM for web developers

Posted by chris on February 23rd, 2010 Comments (3)

Let me start out by saying I think MyISAM sucks. I hate it. It’s the default MySQL database engine, but its non-relational so a lot of people just start using it without exploring the other options. Hey thats okay, I did the same thing until some smart guys over at my last job introduced be to InnoDb. MyISAM is probably the best way to go for newer web developers just trying to cut their teeth on web application development. At some point its time to a pick up a book and learn how InnoDb can save you time, save you headaches, reduce the amount of code you write, and make the world a better place (okay that last one is a reach).

The best part about InnoDB is that its relational. Its transaction-safe too, but I’ll just focus on the relation side of things for now. What is a relation? A relation joins two tables together on a common value. Typically this is a parent-child relationship known as a one-to-many, but it can be a one-to-one relation too. Lets look at three tables.

tbl_profile
—————
profile_id
profile_name

tbl_profile_setting
———————–
profile_setting_id
profile_setting_name

tbl_profile_has_setting
—————————
profile_id
profile_setting_id

We have a profile table for storing whatever, then a profile can have settings. It doesn’t really matter what these settings are for the purpose of this article, but a profile can have multiple of these settings. You could have this same structure in MyISAM, but you would have to store the relations in your code. Your code is prone to errors. It happens, in fact is happens enough that I try to write as little code as possible. My goal is to leverage as much pre-written code as possible, because its been reviewed by more people and if I’m using that code I likely trust the source. InnoDB is an awesome example of this. Its widely deployed and written by people with more skills than me. No inferiority-complex here, thanks InnoDB.

For creating a relation. We’ll use phpMyAdmin. MySQL Administrator works great too and if your nutty enough you can look up the SQL for doing it in the mysql command line console. Go into the tbl_profile_has_setting table. In the structure tab you will see a link called Relation View. Click on this. You’ll notice a drop down next profile_id and profile_setting_id (these will only appear if you made these primary keys). You’ll need to create indexes on these two columns in the tbl_profile_has_setting table as well. Select the tbl_profile.profile_id and tbl_profile_setting.profile_setting_id for their respective columns. For the On Delete drop down select cascade.

What you’ve just done is create relations that have the following rules enforced by the database engine.

  1. When you delete a profile, its corresponding record(s) in tbl_profile_has_settings is deleted automajically
  2. When you delete a profile setting, its corresponding record(s) in tbl_profile_has_settings is deleted automajically
  3. When you add a record to tbl_profile_has_setting the profile_id and profile_setting_id must exist in their respective tables

Guess what, you don’t have to verify that the setting exists anymore when inserting into tbl_profile_has_setting and you don’t even need to worry about the profile existing. MySQL will return an error if these rules are violated. You now have referential integrity, clean data, and happy reports. You made all this possible just by creating the relation. So what did the cascade option do? That created rule 1 and 2 above. The auto-delete. Cascade should be used wisely as it can have devastating consequences (you records are automatically deleted), but when you implement a cascade this is normally what you want.

So why doesn’t everyone use InnoDb over MyISAM. There are several reasons:

  1. You need to be more knowledgeable to use it. This isn’t just throw data in grab it out anymore. It takes more thought and for bigger projects you’ll want to create ER diagrams to flowchart out your database.
  2. Performance penalty. Since you’ve offloaded the work to the database engine your database now runs slower. I scoff when people use this as an argument against InnoDb. If your application has gotten to be so successful that InnoDb is the sole reason of your slow down then congratulations, not many people are as successful as you. Plus InnoDb operates in a lower level language that is faster than the PHP code you are writing. Also most of your slowdowns in PHP web applications can be attributed to poorly written queries, bad database design to begin with, and lack of innovation to come up with solutions to improve speed.
  3. Harded to backup. Yes you can still use the mysqldump to backup your data, but you can’t copy the actaul database file like you could with MyIsam. This is a crappy form of database backup anyways. If you’re big enough to wear the mysqldump is no longer a sane method of doing backups then just stop being cheap and go buy the enterprise software to manage your data. Your data is important to you right?

Hope this helps some people and I hope it offends some people as well. This is one of those things that I cannot find common ground on, its debated often between me and co-workers. On a side note, don’t let your domain expire while on vacation. You’ll lose your SERPs fast.

In SQL, php (, , )

Twittrash – Twitter Trash and Other Scum on the Internet

Posted by chris on February 17th, 2010 Comments(0)

So I recently started using twitter and you can follow me by going to http://www.twitter.com/cnizzdotcom. I had long been opposed to twitter because I thought it was useless. Of course I was initially opposed to myspace and facebook as well which I am currently using on or have used at one point. I guess I am sometimes a bit reactionary when it comes to knew things. Not just technology, but even certain technologies and methodologies in programming. This is a dangerous thing in my field, but I’m getting more progressive by the day. I laugh thinking about how years ago I stated to a co-worker “extending classes is a horrible idea.” Hey, if we were never wrong, then we’d never improve, right? So I take comfort in my opinions evolving as I become more knowledgeable.

So about a month ago I began using twitter. My use of twitter is really just an exercise in marketing my most important product across the internet, which is me! What I’ve learned in my month with twitter is that twitter is not much different than SEO blackhat, whitehat, and greyhat that you see with ranking in Google. In the SEO world you have scum that write bots (actually they are quite easy to write) which like graffiti in parks (the trashy kind) spam blogs and forums in an effort to win backlinks.

In the twitterverse its the same. You have twitbots, employed by twittrash that will follow someone for a few hours, maybe a few days (its hard to tell) and then unfollow them. All this is done automatically so the twittrash doesn’t have to do it manually. You’ve probably noticed this before. I noticed it right away and assumed it was some bot, but it was confirmed while reading a forum post over at DP. The poster advised another poster to “use a twitter automation program to auto follow then unfollow after time has passed and they don’t follow back.” The term twittrash immediately popped into my head.

There are legitimate ways of winning followers in twitter. It’s hard starting from ground zero and doing things legit (trust me I’m doing it now) but it can be done.

  1. Find people you know and start following them
  2. If you already know the person and they know you are now following them its likely they will reciprocate.

  3. Use hashtags to reach a broader audience
  4. When you use a hash tag such as #php or #embarassing it reaches everyone else listening for that hashtag. Of course spammers use these as well, but you glance over the spam and find the good stuff just like with anything else on the web.

  5. Write good twits and links to quality content
  6. This is a no brainer and its the exact same thing you do when optimizing for google.

  7. Include links to your twitter page everywhere
  8. Add a link to your twitter page on your facebook, myspace, blog, and to forum signatures

On the web and in life, when ever something good comes a long there will be [insert prefix here]-trash to try and ruin it. Twittrash is no different than snake oil salesman, politicians, and blog spammers. Thanks for reading.

In rant, seo ()

How To Write a Page Controller in PHP for Dynamic Content

Posted by chris on February 6th, 2010 Comments(0)

This how to will cover the topic of creating a dynamic content system. It’s a well known fact that when you come across a site like wikipedia that they don’t have an html file for each article. That would be insanity. It would be nearly impossible to display the file tree in an IDE and cumbersome to search through even with an OS that has a slick file system and powerful shell like Linux. Trust me, I worked on a site that created a unique page for each product on their site (they’ve since gotten with the times). So how can web browsers access a page like http://en.wikipedia.org/wiki/Mike_Tyson, when that file doesn’t exist. The application uses a combination of server-side code, database storage, and apache htaccess magic. Here’s how to do this.

Apache HTACCESS
This is the most important part of redirecting dynamic content. The .htaccess file is what makes the magic happen. What happens is a user requests http://en.wikipedia.org/wiki/Mike_Tyson, apache goes to process the request and does its thing. Normally apache would redirect this to a 404 error page because the file does not exist, but if it see’s the .htaccess file in the directory, then apache will follow the rules we defined in the htaccess. Our rule will tell apache that if the file is not found, to go to some other file. We will call this file mycontroller.php (because its the controller in our ModelViewController). Below is some example code to get your started:

1
2
3
4
5
6
7
8
9
10
11
12
Options -Indexes
Options +FollowSymLinks
DirectoryIndex index.php
ErrorDocument 404 /404.php
 
<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ mycontroller.php [L,QSA]
</IfModule>

Recap:
1. We have /public_html/mydomain.com/wiki/.htaccess
This overwrites the Apache Web Servers default operating procedures.

2. We redirect the request to /public_html/mydomain.com/wiki/mycontroller.php
This contains the server side code that will handle our request for the Mike Tyson article.

The Database
Going in detail on this topic is beyond the scope of this article, but you’ll need some sort of database management system to store your article on Mike Tyson and the thousands of other articles. Of course there are other options like an XML file, but a database such as MySQL is the sanest approach for most sites.

Server Side Code
You’ll need some sort of server-side code running whether is ASP, JSP, or PHP. I’m a bit partial to PHP so lets roll with that. In mycontroller.php your code might look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$uriArr = explode('/',$_SERVER['REQUEST_URI']); 
$article = $uriArr[2];
$article = urldecode($page); // in this case the article equates to Mike_Tyson
 
$sql = "SELECT * FROM article WHERE name = '$article'";
$result = mysql_query($sql);
if(mysql_num_rows($result) == 1){
	$page = mysql_fetch_assoc($result);
	header('HTTP/1.1 200 OK');
	header('Connection: close');
	include_once 'mytemplatepage.php';
DIE():
}
else{
	header('HTTP/1.1 404 Not Found');
	header('location: /404.php');
	header('Connection: close');
DIE();
}

This is asking our database for any records it has on the request Mike_Tyson. If a row is returned than we know we’ve found our article. We tell the browser that this is a 200 OK request. Then we include a file called mytemplate.php (this file is never actually seen by the browser). We set the record in the database to a variable array called $page. Our mytemplate.php file will look for this variable and begin populating the article. Lets see $page contains the following data: Title, Body, Image, and References. The mytemplate.php file might look something like this:

1
2
3
4
5
6
7
8
9
10
$title = $page['title '];
$body = $page['body '];
$image = $page['image '];
$references = $page['references '];
echo "<html><head><title>$title</title></head><body>";
echo "<h1>$title</h1>";
echo "<div class="mainImage">$image</div>";
echo "<p>$body</p>";
echo "<p>$references</p>";
echo "</body></html>";

Sweet! We can use the same template for a bunch of different articles, without having to create multiple files. Now if the user had searched for the following url: http://en.wikipedia.org/wiki/Mike_TysonIsEvil, we wouldn’t have an article on that. So instead the code would tell the browser this is a 404 Error and route the browser to the 404.php page.

This is an over simplified version of a dynamic content system, but it would work. If I was developing one of these on a professional level it would be complete with objects to handle requests, string cleaners to protect against SQL injection and XSS attacks, error logging, and the works! Let me know if you have questions I can answer and thanks for reading.

In php, seo (, , , , )