<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-20648899</id><updated>2011-11-15T07:47:56.862-08:00</updated><title type='text'>whenpenguinsattack.com</title><subtitle type='html'>Dedicated to usage of open source software on a closed source platform.&lt;br&gt;&lt;br&gt;Have a question? Feel free to email me here:&lt;A HREF="mailto: justin@whenpenguinsattack.com"&gt;justin@whenpenguinsattack.com&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>97</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-20648899.post-114344031533543794</id><published>2006-06-12T14:20:00.000-07:00</published><updated>2007-03-16T17:00:01.616-07:00</updated><title type='text'>Excel and php without activeX</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/pearsmall.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/pearsmall.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Introduction&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Spreadsheet_Excel_writer is a PEAR component for creating Excel files without the need for COM components. The files generated are in the Excel 5 (BIFF5) format, so all functionality until that version of Excel (but not beyond) should be available.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Using&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The most common use for Spreadsheet_Excel_Writer will be spitting out large (or not so large) amounts of information in the form of a spreadsheet, which is easy to manipulate with a fairly ubiquitous spreadsheet program such as Excel (or OpenOffice).&lt;br /&gt;&lt;br /&gt;Example 1:&lt;br /&gt;&lt;br /&gt;send('test.xls');&lt;br /&gt;&lt;br /&gt;// Creating a worksheet&lt;br /&gt;$worksheet =&amp; $workbook-&amp;amp;gtaddWorksheet('My first worksheet');&lt;br /&gt;&lt;br /&gt;// The actual data&lt;br /&gt;$worksheet-&gt;write(0, 0, 'Name');&lt;br /&gt;$worksheet-&gt;write(0, 1, 'Age');&lt;br /&gt;$worksheet-&gt;write(1, 0, 'John Smith');&lt;br /&gt;$worksheet-&gt;write(1, 1, 18);&lt;br /&gt;&lt;br /&gt;// Let's send the file&lt;br /&gt;$workbook-&gt;close();&lt;br /&gt;?&gt;&lt;br /&gt;&lt;br /&gt;The first thing you should notice, is that we created a workbook before any worksheets. All worksheets are contained within a workbook, and a workbook may contain several worksheets.&lt;br /&gt;&lt;br /&gt;Another important thing, which you should have in mind when programming with Spreadsheet_Excel_Writer, is that ampersand sign (&amp;) that appears when we created our worksheet. That ampersand means we are referencing a Worksheet object instead of copying it. If you don't know what that means, don't worry, all you have to remember is to always use ampersands when calling addWorksheet() for creating a worksheet, or addFormat() for creating a format.&lt;br /&gt;Saving to a regular file&lt;br /&gt;&lt;br /&gt;You may have noticed also the following line:&lt;br /&gt;&lt;br /&gt;// sending HTTP headers&lt;br /&gt;$workbook-&gt;send('test.xls');&lt;br /&gt;&lt;br /&gt;What that means is that we are sending our spreadsheet to a browser. But what if we just want to save the spreadsheet in our machine? Well, you just have to omit that line and give a valid file path to the workbook constructor.&lt;br /&gt;&lt;br /&gt;For example, if we wanted to save the same spreadsheet we created in our first example to a file named 'test.xls', we would do it like so:&lt;br /&gt;&lt;br /&gt;Example 2:&lt;br /&gt;&lt;br /&gt;addWorksheet('test worksheet');&lt;br /&gt;&lt;br /&gt;$worksheet-&gt;write(0, 0, 'Name');&lt;br /&gt;$worksheet-&gt;write(0, 1, 'Age');&lt;br /&gt;$worksheet-&gt;write(1, 0, 'John Smith');&lt;br /&gt;$worksheet-&gt;write(1, 1, 10);&lt;br /&gt;&lt;br /&gt;// We still need to explicitly close the workbook&lt;br /&gt;$workbook-&gt;close();&lt;br /&gt;?&gt;&lt;br /&gt;&lt;br /&gt;More info and documentation on this component can be found &lt;a href="http://www.pear.php.net/manual/en/package.fileformats.spreadsheet-excel-writer.php"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114344031533543794?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114344031533543794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114344031533543794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114344031533543794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114344031533543794'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/06/excel-and-php-without-activex.html' title='Excel and php without activeX'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114886630405439032</id><published>2006-05-28T18:31:00.000-07:00</published><updated>2006-05-30T08:07:55.193-07:00</updated><title type='text'>Adding friends to myspace using perl</title><content type='html'>By Justin Silverton&lt;br /&gt;&lt;br /&gt;I came across this perl script today that allows you to add friends to your myspace account using perl.main website is &lt;a href="http://www.glitchnyc.com/?page_id=117"&gt;Here&lt;/a&gt;Taken from the website: " This is a perl script, and it’s certainly rough around the edges. If you’re running on windows, there are applications available for cheap that will do the job better and with more support. I’m on Linux, so I needed a cross-platform script that did just what I needed.&lt;br /&gt;&lt;br /&gt;That said, this little bit of code should run on any machine with the proper perl modules installed (WWW::Mechanize, HTML::TokeParser::Simple, and Text::CSV). It’s open source, released under the GPL."DownloadThe script can be found &lt;a href="http://www.glitchnyc.com/GlitchCastFriendAdder.pl"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How do I run this?&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;On Linux&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If you’re running on Linux, running this code is fairly simple. Just invoke it with perl GlitchCastFriendAdder.pl&lt;br /&gt;&lt;br /&gt;If it complains that it’s needs certainly libraries, you can add them with CPAN, apt, or yum.&lt;br /&gt;To add the necessary libraries using apt on Fedora Core, Red Hat, CentOS, Debian, Ubuntu, and others, run this command as root: (package names may differ slighly across distros. If one does not appear available, search for it with apt-cache search packagename) apt-cache search mechanize&lt;br /&gt;brings up libwww-mechanize-perl&lt;br /&gt;apt-cache search tokeparser&lt;br /&gt;brings up libhtml-tokeparser-simple-perl&lt;br /&gt;apt-cache search csv-perl&lt;br /&gt;brings up libtext-csv-perl&lt;br /&gt;now that I’ve found the package names (I’m using ubuntu, so this exact command should work for all debian distros with universe and multiverse enabled)&lt;br /&gt;apt-get install libhtml-tokeparser-simple-perl libtext-csv-perl libwww-mechanize-perl&lt;br /&gt;You could of course use CPAN to install these modules instead, but I’m less familiar with that method. If you know how, please email me at GlitchCastFriendAdder A.T. GlitchNYC.com Now that you’ve got all your modules, the code should run just fine. Be sure that you’ve added at least one MySpace URL to friendPagesToScrape.txt - you’ll have to make that file if you haven’t already.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Running on a Mac&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I have no idea. In theory, this should be fairly similar to the process above. If you get it to work, let me know how you did it!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Running on Windows&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This should be possible using ActiveState perl. It’s been a while since I used it, but if memory serves, there is a GUI that allows you to choose the packages you need. Just select these: * WWW::Mechanize * HTML::TokeParser::Simple * Text::CSV&lt;br /&gt;I’ve now had my first report of this working on windows! To get the firefox captcha routine to work, you’ll need to change the firefox executable path. This is as simple as commenting one line and uncommenting another. It’s right below the username and password at the top of the code.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Running the script &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;First, enter your username and password at the top of the script&lt;br /&gt;Second, paste a bunch of myspace url’s containing people you want to add into the file friendPagesToScrape.txt in the same directory where the main script is.&lt;br /&gt;UPDATE: The URLs should be one per line! (this is a change from version 1.0)&lt;br /&gt;HINT - It’s easy to change just the “page” variable when you paste in the url’s to get multiple pages of friends of one group/person.&lt;br /&gt;&lt;br /&gt;The script will parse that file, and then go to each page in the list, getting all the friend IDs on the page. Once it has grabbed all the friendIDs, it adds each of the friends, prompting you if it needs a captcha. I’ve tuned it to be fairly patient (1 friend added every 5 seconds or so) so as to not anger the myspace gods and incur lots of captchas, but you can tune as it runs by following the prompts if you start to get too many captchas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114886630405439032?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114886630405439032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114886630405439032' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114886630405439032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114886630405439032'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/adding-friends-to-myspace-using-perl.html' title='Adding friends to myspace using perl'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114827713081372059</id><published>2006-05-21T22:51:00.000-07:00</published><updated>2006-06-19T09:48:57.476-07:00</updated><title type='text'>Convert your pdf files directly to html</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/pdf2html_ssa.gif"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/pdf2html_ssa.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;There is this great program I found called pdf2html. It is an opensource, free, program that will allow you to convert your pdf files directly to html.&lt;br /&gt;&lt;br /&gt;It can be downloaded here (the win32 gui version): &lt;a href="http://guiguy.wminds.com/downloads/pdf2htmlgui/"&gt;http://guiguy.wminds.com/downloads/pdf2htmlgui/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;original sourceforge project: &lt;a href="http://sourceforge.net/projects/pdftohtml/"&gt;http://sourceforge.net/projects/pdftohtml/&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The idea for this web-site was a culmination of events that began in my efforts to find a simple utility for a very specific task (I wanted to convert my rm video clips to anything else). After what seemed like months of searching, I was finally able to locate a command line utility that promised to do the trick (Tinra).&lt;br /&gt;&lt;p&gt;I found it in a help forum where others were asking for a graphical user interface (GUI) for it. I decided to make TinraGUI as a way of showing thanks to the group for helping me find what I was after. I soon discovered, however, that I couldn't attach the program I made to my reply on the forum, so I needed a web-site to host it. I put up a quick site at Tripod for the purpose. But when it seemed that it was going to be more popular than I first thought, I imagined a web-site like this one where I could make simple Windows programs and GUI's for people on request and for free.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;I personally found this tool to be very helpful. I was able to convert nearly all of my .pdf files to web pages with almost no errors or mistakes.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114827713081372059?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114827713081372059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114827713081372059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114827713081372059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114827713081372059'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/convert-your-pdf-files-directly-to.html' title='Convert your pdf files directly to html'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114789812690940417</id><published>2006-05-17T13:32:00.000-07:00</published><updated>2006-05-23T07:28:51.523-07:00</updated><title type='text'>Connecting to Authorize.net with PHP</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;br /&gt;&lt;br /&gt;What is authorize.net?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The Authorize.Net Payment Gateway is a secure Internet bridge between merchant businesses and the credit card and electronic check payment processing networks. We provide merchants with fast, reliable and secure passage for transaction data via a 128-bit Secure Sockets Layer (SSL) Internet Protocol (IP) connection, and manage the complex routing of payment information to the appropriate credit card processors. &lt;a href="http://www.authorize.net/resources/howitworksdiagram/"&gt;See a diagram&lt;/a&gt; that illustrates a typical Authorize.Net credit card transaction.&lt;br /&gt;&lt;br /&gt;&lt;p class="BodyMainText"&gt;The Authorize.Net Payment Gateway is available to merchants seven days a week, 24 hours a day. The payment gateway offers many features and options that can be tailored to specific merchant business models.&lt;/p&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Where do I start?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The first thing that you need to do, is signup with a test account. This will allow you to test out transactions to make sure your scripts are interfacing properly with their API. Here is the URL for getting your account:&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;http://developer.authorize.net/testaccount&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;br /&gt;API documentation can also be found here:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;http://www.authorize.net/support/AIM_guide.pdf&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;after signing up, you should receive your new account info within 48 hours.&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;br /&gt;The Code&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;I have a library available here: (URL). It is originally written by Micah Carrick and is under the GPL/GNU public license. I have made some important additions to the main library, which are needed for it to function properly.&lt;br /&gt;&lt;br /&gt;you can get it here: &lt;a href="http://www.electronicfiles.net/files/1773/authorize_lib.zip"&gt;http://www.electronicfiles.net/files/1773/authorize_lib.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Requirements:&lt;/span&gt; PHP version 4 and above with the CURL extensions enabled&lt;br /&gt;&lt;br /&gt;The following 3 files are contained in the above .zip download:&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-STYLE: italic"&gt;authorizenet.class.php &lt;/span&gt;- main class library for connecting to the authorize.net gateway&lt;br /&gt;&lt;span style="FONT-STYLE: italic"&gt;demo.php&lt;/span&gt; - an example driver file that shows how to use the library file. A test transaction is made to the main gateway.&lt;br /&gt;&lt;span style="FONT-STYLE: italic"&gt;ca-bundle.crt - &lt;/span&gt;main certificate file required by CURL for SSL transactions (windows users can place this in c:\windows\system32)&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Important Variables that you need to change&lt;br /&gt;&lt;br /&gt;Location: authorizenet.class.php&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;curl_setopt ($ch, CURLOPT_CAINFO,"c:\\windows\\system32\\ca-bundle.crt");&lt;br /&gt;curl_setopt ($ch,CURLOPT_CAPATH,"c:\\windows\\system32\\ca-bundle.crt");&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;change the 3rd parameter&lt;span style="FONT-WEIGHT: bold"&gt; &lt;/span&gt;"c:\\windows\\system32\\ca-bundle.crt" to the location of your CRT file.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Location: authorizenet.class.php&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;var $gateway_url = "https://test.authorize.net/gateway/transact.dll";&lt;br /&gt;&lt;br /&gt;it currently points to the authorize.net gateway for test accounts. If you have an account that is performing real transactions, change this variable to the following value: ""https://secure.authorize.net/gateway/transact.dll"&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Location: demo.php&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;$a-&gt;add_field('x_login', 'YOUR_USERID');&lt;br /&gt;$a-&gt;add_field('x_password', 'YOUR_PASSWORD');&lt;br /&gt;&lt;br /&gt;change x_login to your Login ID (not partner ID)&lt;br /&gt;and x_password to your password&lt;br /&gt;&lt;br /&gt;You should have received both of these in an email from authorize.net&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Tahoma;font-size:78%;"&gt;&lt;span style="font-family:Tahoma;font-size:9;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114789812690940417?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114789812690940417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114789812690940417' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114789812690940417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114789812690940417'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/connecting-to-authorizenet-with-php.html' title='Connecting to Authorize.net with PHP'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114765215808346595</id><published>2006-05-14T17:15:00.000-07:00</published><updated>2006-05-14T17:34:33.920-07:00</updated><title type='text'>An Excel Killer</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/screenshot1_thumb.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/6545/2077/320/screenshot1_thumb.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I came across this ajax application today called ajaxXLS.  It's an ajax execl application that can read and write excel files.  It is one of the best ajax apps I have seen to date and displays the power and capability of AJAX.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;&lt;span style="font-size:85%;"&gt;Functionality&lt;/span&gt;&lt;br /&gt;&lt;/h1&gt;             &lt;p class="shorten"&gt;On this first release of the ajaxXLS viewer, you can            expect to open spreadsheet files with all your common cell formatting            categories such as text style, decimals, currencies, date, and time.            ajaxXLS will preserve your formulas, backgrounds and borders from the            files created in Microsoft Excel or OpenOffice. ajaxXLS is platform            independent and can be used with any operating system. Unlike typical            office programs that you install on your computer, features will continue            to be added to ajaxXLS and made available to you immediately without            the need for complicated reinstallation or reconfiguration of software.            Try ajaxXLS today and see for yourself how AJAX applications are redefining            the way you use software.&lt;/p&gt;                                    With this release,                we're publishing the methodology whereby any search engine, email                client or other software developer can provide a link to an existing                .xls document (hosted online) so that anyone can open it using ajaxXLS.                See for yourself how a spreadsheet document can be launched right                from my web page by clicking on this sample &lt;a href="http://www.ajaxlaunch.com/misc/nojscript.html" onclick="window.open ('http://usa.ajaxxls.com/apps/calc/content/index.xul?doc=http://www.ajaxlaunch.com/misc/xls/revenue.xls','ajax13','scrollbars,resizeable,width=800,height=600'); return false;"&gt;revenue.xls&lt;/a&gt;.To                obtain the code to create a link on your website that opens any                spreadsheet in ajaxXLS, &lt;a href="http://www.ajaxlaunch.com/launch_ajaxxls.html"&gt;please                click here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;&lt;span style="font-size:85%;"&gt;Redefining Software&lt;/span&gt; &lt;/h1&gt;         &lt;p class="shorten"&gt;AJAX programming techniques allow web-based software to function smoothly without the waiting around for page uploads that you normally associate with the Internet. The benefits of web-based software are so compelling, we feel that they are the future of the industry. These benefits include:&lt;/p&gt;    &lt;ul&gt;&lt;li&gt;Global access, all you need is an internet connection&lt;/li&gt;&lt;li&gt;Platform independent, you can use it with any operating system&lt;/li&gt;&lt;li&gt;Automatic updates and upgrades, no more computer restarts or missed patches/updates&lt;/li&gt;&lt;li&gt;Server side management — all the busywork is done for you&lt;/li&gt;&lt;/ul&gt;             &lt;p&gt;AjaxXLS is just a small step forward in this software revolution, and            we are proud to be a part of it.&lt;/p&gt;&lt;span style="font-weight: bold;"&gt;Test it out for yourself&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;To test it out, go here (it requires FireFox)&lt;span style="font-weight: bold;"&gt;: &lt;a href="http://www.ajaxlaunch.com/ajaxxls/internals/ajaxxls-nojscript.html"&gt;http://www.ajaxlaunch.com/ajaxxls/internals/ajaxxls-nojscript.html&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114765215808346595?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114765215808346595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114765215808346595' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114765215808346595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114765215808346595'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/excel-killer.html' title='An Excel Killer'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114003741120287023</id><published>2006-05-13T03:50:00.000-07:00</published><updated>2006-05-13T00:44:41.333-07:00</updated><title type='text'>mysql vs postgres</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;em&gt;postgres/mysql comparison chart&lt;/em&gt;&lt;/center&gt;&lt;center&gt;&lt;em&gt;&lt;/em&gt;&lt;/center&gt;&lt;center&gt;&lt;/center&gt;&lt;center&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Feature&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Mysql 3.x&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Mysql 4.0&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Mysql 5.x&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Postgres 7.x&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Subselects&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Partial&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Views&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Foreign Key Relationships&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Foreign Key Constraints&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Triggers&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Indexing (non-trivial types)&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sequences&lt;/td&gt;&lt;td&gt;Partial&lt;/td&gt;&lt;td&gt;Partial&lt;/td&gt;&lt;td&gt;Partial&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Transactions&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Table Inheritance&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Async. Notifications&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Constraints&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Select Into&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Stored Procedures&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Row-Level Locking&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Table-Level Locking&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Geospatial datatypes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Native Replication&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;b&gt;Companies using postgres&lt;/b&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/95x51_6.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;These are links to case studies, showcasing the successful usage of postgres in an organization &lt;p&gt;&lt;br /&gt;&lt;a href="/files/about/casestudies/wcgcasestudyonpostgresqlv1.2.pdf"&gt;BASF&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="/about/casestudies/mohawk" target="_self"&gt;Mohawk Software&lt;/a&gt;&lt;br /&gt;&lt;a href="/files/about/casestudies/Proximity10.pdf"&gt;Proximity&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="/files/about/casestudies/RadioParadise.pdf"&gt;Radio Paradise&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="/about/casestudies/shannonmedical" target="_self"&gt;Shannon Medical Center&lt;/a&gt;&lt;br /&gt;&lt;a href="/files/about/casestudies/Spiros.pdf"&gt;Spiros Louis Stadium&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="/files/about/casestudies/OpenSourceSoftware_Dravis.pdf"&gt;The Dravis Group OSS Report&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="/about/casestudies/vanten" target="_self"&gt;Vanten Inc.&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;center&gt;&lt;b&gt;Companies using mysql&lt;/b&gt;&lt;/center&gt;&lt;p&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/mysql_100x52-64.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com/why-mysql/case-studies/mysql-hp-ongame-casestudy.pdf"&gt;Patypoker.com&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com/why-mysql/case-studies/mysql-greyhound-data-casestudy.pdf" target="_self"&gt;Greyhound bus - data website (PDF format)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com/why-mysql/case-studies/mysql-sandstorm-casestudy.pdf"&gt;Sandstorm&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com/why-mysql/case-studies/mysql-leapfrog-casestudy.pdf"&gt;Leapfrog schoolhouse&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com/why-mysql/case-studies/mysql-netqos-casestudy.pdf" target="_self"&gt;NetQos&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com/why-mysql/case-studies/mysql-sony-casestudy.pdf"&gt;Sony&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com/why-mysql/case-studies/mysql-dell-nine-systems-casestudy.pdf"&gt;Dell&lt;/a&gt; &lt;span class="txtMediumGrey"&gt;(PDF format)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.mysql.com/why-mysql/case-studies/mysql-friendster-casestudy.pdf" target="_self"&gt;Friendster.com&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;So which one is better?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Both postgres and mysql have had success on large-scale websites and they each have their benefits:&lt;/p&gt;&lt;p&gt;&lt;em&gt;Where postgres wins:&lt;/em&gt;&lt;/p&gt;&lt;p&gt;1) faster with more complex queries&lt;/p&gt;&lt;p&gt;2) ACID compliant&lt;/p&gt;&lt;p&gt;3) embedded language capibility (Perl, PHP, TCL, and PG/PLSQL)&lt;/p&gt;&lt;p&gt;4) on average, can handle more concurrent connections&lt;/p&gt;&lt;p&gt;&lt;em&gt;where mysql wins:&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;1) more wide-spread support and usage with ISPs and the open source commuity&lt;/p&gt;&lt;p&gt;2) robust replication&lt;/p&gt;&lt;p&gt;3) easier for newcomers to use&lt;/p&gt;&lt;p&gt;4) on average, faster per query&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114003741120287023?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114003741120287023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114003741120287023' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114003741120287023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114003741120287023'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/mysql-vs-postgres.html' title='mysql vs postgres'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114067576576745063</id><published>2006-05-10T23:08:00.000-07:00</published><updated>2006-05-18T11:20:49.966-07:00</updated><title type='text'>tech resume tips</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here are some tips that may help you when you apply for your next tech job:&lt;br /&gt;&lt;p class="headline2"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Top Ten Technical Resume Writing Tips&lt;/span&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;List your technical knowledge first, in an organized way. Your technical strengths must stand out clearly at the beginning of your resume. Ultimately, your resume is going to be read by a thoughtful human being, but before it gets to that point it often has to be categorized by an administrative clerk, and make its way past various sorts of key word searches. Therefore, you should list as many directly relevant buzz words as you can which reflect your knowledge and experience. List all operating systems and UNIX flavors you know. List all programming languages and platforms with which you're experienced. List all software you are skilled with. Make it obvious at a glance where your strengths lie - whether the glance is from a hiring manager, a clerk, or a machine.&lt;/li&gt;&lt;li&gt;List your qualifications in order of relevance, from most to least. Only list your degree and educational qualifications first if they are truly relevant to the job for which you are applying. If you've already done what you want to do in a new job, by all means, list it first, even if it wasn't your most recent job. Abandon any strict adherence to a chronological ordering of your experience.&lt;/li&gt;&lt;li&gt;Quantify your experience wherever possible. Cite numerical figures, such as monetary budgets/funds saved, time periods/efficiency improved, lines of code written/debugged, numbers of machines administered/fixed, etc. which demonstrate progress or accomplishments due directly to your work.&lt;/li&gt;&lt;li&gt;Begin sentences with action verbs. Portray yourself as someone who is active, uses their brain, and gets things done. Stick with the past tense, even for descriptions of currently held positions, to avoid confusion.&lt;/li&gt;&lt;li&gt;Don't sell yourself short. This is by far the biggest mistake of all resumes, technical and otherwise. Your experiences are worthy for review by hiring managers. Treat your resume as an advertisement for you. Be sure to thoroughly "sell" yourself by highlighting all of your strengths. If you've got a valuable asset which doesn't seem to fit into any existing components of your resume, list it anyway as its own resume segment.&lt;/li&gt;&lt;li&gt;Be concise. As a rule of thumb, resumes reflecting five years or less experience should fit on one page. More extensive experience can justify usage of a second page. Consider three pages (about 15 years or more experience) an absolute limit. Avoid lengthy descriptions of whole projects of which you were only a part. Consolidate action verbs where one task or responsibility encompasses other tasks and duties. Minimize usage of articles (the, an, a) and never use "I" or other pronouns to identify yourself.&lt;/li&gt;&lt;li&gt;Omit needless items. Leave all these things off your resume: social security number, marital status, health, citizenship, age, scholarships, irrelevant awards, irrelevant associations and memberships, irrelevant publications, irrelevant recreational activities, a second mailing address ("permanent address" is confusing and never used), references, reference of references ("available upon request"), travel history, previous pay rates, previous supervisor names, and components of your name which you really never use (i.e. middle names).&lt;/li&gt;&lt;li&gt;Have a trusted friend review your resume. Be sure to pick someone who is attentive to details, can effectively critique your writing, and will give an honest and objective opinion. Seriously consider their advice. Get a third and fourth opinion if you can.&lt;/li&gt;&lt;li&gt;Proofread, proofread, proofread. Be sure to catch all spelling errors, grammatical weaknesses, unusual punctuation, and inconsistent capitalizations. Proofread it numerous times over at least two days to allow a fresh eye to catch any hidden mistakes.&lt;/li&gt;&lt;li&gt;Laser print it on plain, white paper. Handwriting, typing, dot matrix printing, and even ink jet printing look pretty cheesy. Stick with laser prints. Don't waste your money on special bond paper, matching envelopes, or any color deviances away from plain white. Your resume will be photocopied, faxed, and scanned numerous times, defeating any special paper efforts, assuming your original resume doesn't first end up in the circular file&lt;/li&gt;&lt;/ul&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Finalizing Your Resume&lt;/span&gt;&lt;br /&gt;&lt;b class="elOrange" style="COLOR: rgb(51,51,51)"&gt;&lt;a name="aFinalizing"&gt;&lt;/a&gt;&lt;/b&gt;&lt;ul&gt;&lt;li&gt;Resumes should be concise and in a manageable document length. &lt;/li&gt;&lt;li&gt;Your Name and Page Number should be located on every page, just in case pages become separated while in the hands of the prospective employer.&lt;br /&gt;(The Name and Page number can be in the Header or Footer part of the resume, or at the top of the page using a smaller font size, to avoid distracting the reader. Page Numbers can be written as: Page 2, Page Two, Page 2 of 3, or Page Two of Three.) &lt;/li&gt;&lt;li&gt;Do not put a photograph of yourself on the resume. Potential employers will not be hiring you based on your looks! However, International candidates will need to send their scanned photograph to the Systems Integration Solutions, Inc. International Department representative along with the final formatted resume. &lt;/li&gt;&lt;li&gt;Type your resume in a word processing document and back it up on a disk. Updating your resume then becomes easy. If you are not a typist, ask a professional to type it. &lt;/li&gt;&lt;li&gt;Use one typeface such as Times New Roman, Arial, or other traditional typeface. The standard font size is 11 point. Headers may be increased to 12 point. &lt;/li&gt;&lt;li&gt;Margins should be no less than one inch on sides, top, and bottom. The white space serves as a border and keeps the resume from looking cluttered. &lt;/li&gt;&lt;li&gt;Avoid underlining within the resume narrative. If you have written the statements well, they will need no further emphasis. &lt;/li&gt;&lt;li&gt;Always do a print preview of each page of your resume, to view the layout and spacing. &lt;/li&gt;&lt;li&gt;E-mail your resume document, with a short introduction letter to your Systems Integration Solutions, Inc. contact. The document can then be opened, printed, and distributed to clients. &lt;/li&gt;&lt;li&gt;Laser-print your completed resume or have it professionally typeset. &lt;/li&gt;&lt;li&gt;Give or mail an interviewer your resume printed on an off-white, tan, or light gray quality bond paper. Never give them a photocopy of your resume. &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114067576576745063?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114067576576745063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114067576576745063' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114067576576745063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114067576576745063'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/tech-resume-tips.html' title='tech resume tips'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114731428262449575</id><published>2006-05-10T19:24:00.000-07:00</published><updated>2006-05-10T19:41:27.013-07:00</updated><title type='text'>is AjaxOS worth the wait?</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/thumb_desktop.png"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/thumb_desktop.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;What is AjaxOS?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;ajaxOS is a Linspire-based operating system with some revolutionary new features to support the adoption of web-based software. Some of the cool new things you can expect to see on ajaxOS include:&lt;br /&gt;&lt;br /&gt;Automatic launch of AJAX software when clicking on a supported filetype.Ability to save files to virtual storage.Ability to navigate through a file browser to the files uploaded to virtual storage as well those on your local computer.&lt;br /&gt;&lt;br /&gt;ajaxOS will be available for download in the next few weeks. You can &lt;a href="http://www.ajaxlaunch.com/forum/profile.php?mode=register&amp;amp;agreed=true"&gt;register&lt;/a&gt; to receive notification of the ajaxOS and other AJAX software releases or visit &lt;a href="http://www.ajaxlaunch.com/"&gt;http://www.ajaxlaunch.com/&lt;/a&gt; to read the official announcements.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Benefits of using ajaxOS&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;Information Security&lt;/em&gt; – Your files and documents are safe from computer crashes, laptop theft, viruses and other virtual attacks on your computer since they are all saved on ajaxOS remote storage.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Web-based Software&lt;/em&gt; Applications Included – Save money. No need to purchase expensive software – it's all included in ajaxOS.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Updated and Upgraded Automatically&lt;/em&gt; – Spending time and money on software updates and upgrades is also a thing of the past, most ajaxOS applications are upgraded automatically.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Full file compatibility&lt;/em&gt; – applications are compatible with all standard file formats, allowing you to easily transfer your existing files and share files created using AJAX software with others.&lt;br /&gt;&lt;br /&gt;View ajaxOS presentation at Desktop linux summet of 2006: &lt;a href="http://boss.streamos.com/download/marketing/dls2006/mbr_dls2006-session4_edit_060425.rm"&gt;http://boss.streamos.com/download/marketing/dls2006/mbr_dls2006-session4_edit_060425.rm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm not really sure if ajaxOS will even be worth downloading. The release notes discuss "revolutionary new features". The screenshots look nice, and it is based on linpire (a linux distro), but it looks like they are basically just integrating a web storage service (which is not a new idea) into a linux distribution.&lt;br /&gt;&lt;br /&gt;Even though I don't think it is anything revolutionary or special, I still think I will download it when it is finally released.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114731428262449575?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114731428262449575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114731428262449575' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114731428262449575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114731428262449575'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/is-ajaxos-worth-wait.html' title='is AjaxOS worth the wait?'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114670193309824383</id><published>2006-05-03T17:15:00.000-07:00</published><updated>2006-05-10T05:09:32.190-07:00</updated><title type='text'>Mysql free enterprise edition</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Many people may not realize that mysql has a free, enterprise version of the open-source database application.&lt;br /&gt;&lt;br /&gt;It's called maxdb and available here: &lt;a href="http://www.mysql.com/products/maxdb/"&gt;http://www.mysql.com/products/maxdb/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here are some benefits:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Reduced cost of your SAP implementation&lt;/li&gt;&lt;li&gt;Easy configuration and low administration&lt;/li&gt;&lt;li&gt;Elaborate backup and restore capabilities&lt;/li&gt;&lt;li&gt;Continuous operation, no scheduled downtimes required&lt;/li&gt;&lt;li&gt;Designed for large number of users and high workloads&lt;/li&gt;&lt;li&gt;Scales to database sizes in the terabytes&lt;/li&gt;&lt;li&gt;High availability through cluster and hot-standby support&lt;/li&gt;&lt;li&gt;Synchronization Manager to control enterprise-wide data replication&lt;/li&gt;&lt;li&gt;Easy-to-use graphical database tools&lt;/li&gt;&lt;li&gt;Available for all enterprise HW/OS platforms&lt;/li&gt;&lt;li&gt;Supports all major SAP solutions&lt;/li&gt;&lt;/ul&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Languages supported&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold"&gt;(APIs)&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JDBC&lt;/li&gt;&lt;li&gt;ODBC&lt;/li&gt;&lt;li&gt;SQLDBC (native C/C++ interface)&lt;/li&gt;&lt;li&gt;Precompiler (to be [re-]released soon)&lt;/li&gt;&lt;li&gt;PHP&lt;/li&gt;&lt;li&gt;Perl&lt;/li&gt;&lt;li&gt;Python&lt;/li&gt;&lt;li&gt;WebDAV&lt;/li&gt;&lt;li&gt;OLE DB, ADO, DAO, RDO and .NET via ODBC&lt;/li&gt;&lt;li&gt;Delphi and TCL via Third Party Programming Interfaces&lt;/li&gt;&lt;/ul&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Platforms supported&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;HP-UX (HP-PA, ia64)&lt;/li&gt;&lt;li&gt;IBM AIX (Power)&lt;/li&gt;&lt;li&gt;Linux (x86_32, x86_64, ia64, PPC_64)&lt;/li&gt;&lt;li&gt;Sun Solaris (SPARC, x86-64 support planned)&lt;/li&gt;&lt;li&gt;Microsoft Windows 2000 (x86_32)&lt;/li&gt;&lt;li&gt;Microsoft Windows Server 2003 (x86_32, x86_64, ia64)&lt;/li&gt;&lt;li&gt;Microsoft Windows XP (x86_32)&lt;/li&gt;&lt;/ul&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Differences from mysql&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;MaxDB is a mature product with 30 year history. The system offers built-in hot backup, does not need any online reorganizations and claims to be SQL 92 Entry-Level compatible. One current development goal is "zero administration" and by this "low TCO".&lt;/p&gt;&lt;p&gt;Over the last years MaxDB has been intensively be improved, especially for mySAP Business Suite environments. You can expect very good OLTP performance combined with relatively low hardware requirements.&lt;/p&gt;&lt;p&gt;Uninterrupted operations and stability is another strength of MaxDB.&lt;/p&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Helpful Links&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Performance: &lt;a href="http://dev.mysql.com/tech-resources/articles/maxdb-performance-primer.pdf"&gt;http://dev.mysql.com/tech-resources/articles/maxdb-performance-primer.pdf&lt;/a&gt;&lt;br /&gt;Helpful Hints: &lt;a href="http://maxdb.yapabout.com/"&gt;http://maxdb.yapabout.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114670193309824383?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114670193309824383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114670193309824383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114670193309824383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114670193309824383'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/mysql-free-enterprise-edition.html' title='Mysql free enterprise edition'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114652340386741880</id><published>2006-05-01T15:39:00.000-07:00</published><updated>2006-05-05T00:50:54.376-07:00</updated><title type='text'>A PHP search engine</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Have you ever wanted a search engine that will show you articles and code samples from around the Internet?&lt;br /&gt;&lt;br /&gt;BeebkeX (&lt;a href="http://www.beeblex.com"&gt;http://www.beeblex.com&lt;/a&gt;), a search engine for just php related material does just that.&lt;br /&gt;&lt;br /&gt;some other interesting features of this site:&lt;br /&gt;&lt;br /&gt;News Search: &lt;a href="http://beeblex.com/index.php?d=phpa_news"&gt;http://beeblex.com/index.php?d=phpa_news&lt;/a&gt;&lt;br /&gt;Article Search: &lt;a href="http://beeblex.com/index.php?d=phpa_articles"&gt;http://beeblex.com/index.php?d=phpa_articles&lt;/a&gt;&lt;br /&gt;Job Search: &lt;a href="http://beeblex.com/index.php?d=php_jobs"&gt;http://beeblex.com/index.php?d=php_jobs&lt;/a&gt;&lt;br /&gt;Blog Search: &lt;a href="http://beeblex.com/index.php?d=php_blogs"&gt;http://beeblex.com/index.php?d=php_blogs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;some cool facts about the site&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What does BeebleX index?&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;Articles and news that have appeared in phparchitect (phpa:)&lt;br /&gt;A complete copy of the PHP manual (man:)&lt;br /&gt;The mailing lists being hosted at php.net (lists:)&lt;br /&gt;Several PHP-related Blogs (blogs:)&lt;br /&gt;Several PHP-related Job Sites (jobs:)&lt;br /&gt;We have plans to add articles from other websites, forum postings and PHP-related blogs to the engine in the near future.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What does BeebleX run on?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;BeebleX runs on PHP 5.1 and Apache 1.3. The backend search engine is &lt;a href="http://www.xapian.org/"&gt;Xapian&lt;/a&gt;, to which our system interfaces using a custom extension&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What are "PHP-related entries?"&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Although we index all of the entries provided by a blog, we have implemented an algorithm that attempts to filter out only those entries that are related to PHP.&lt;br /&gt;The algorithm is still a bit primitive, but it's usually pretty efficient, regardless of whether a blog implements categories or not. Naturally, when we say "pretty efficient," we mean that some non-PHP-related entries slip through from time to time. Like most other things related to BeebleX... this is a work in progress!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Are there any special shortcuts that I can use to speed up searches?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Yes! You can prefix your search with one of the following:&lt;br /&gt;man: — performs a search on the PHP manual (e.g.: &lt;a href="http://beeblex.com/search.php?s=man:+echo"&gt;man: echo&lt;/a&gt;)&lt;br /&gt;f: — finds a specific function in the PHP manual and redirects the user to it. (e.g.: &lt;a href="http://beeblex.com/search.php?s=f:+echo"&gt;f: echo&lt;/a&gt;)&lt;br /&gt;phpa: — performs a search on phparchitect content (e.g.: &lt;a href="http://beeblex.com/search.php?s=phpa:+xml"&gt;phpa: xml&lt;/a&gt;)&lt;br /&gt;lists: — performs a search on the mailing list archive (e.g.: &lt;a href="http://beeblex.com/search.php?s=lists:+bug+NEAR+xml"&gt;lists: bug NEAR xml&lt;/a&gt;)&lt;br /&gt;l:list — limits the search to mailing list list (e.g.: &lt;a href="http://beeblex.com/search.php?s=tabini+l:php.general"&gt;tabini l:php.general&lt;/a&gt;)&lt;br /&gt;We also provide a feature called "Google passthrough" that you can use to bypass BeebleX and run your query directly against Google or Google Groups:&lt;br /&gt;g: — bypasses BeebleX and runs the query transparently against Google (e.g.: &lt;a href="http://beeblex.com/search.php?s=g:tabini"&gt;g:tabini&lt;/a&gt;)&lt;br /&gt;gg: — bypasses BeebleX and runs the query transparently against Google Groups (e.g.: &lt;a href="http://beeblex.com/search.php?s=gg:tabini"&gt;gg:tabini&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114652340386741880?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114652340386741880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114652340386741880' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114652340386741880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114652340386741880'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/05/php-search-engine.html' title='A PHP search engine'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114642276463603583</id><published>2006-04-30T11:31:00.000-07:00</published><updated>2006-06-14T16:51:50.636-07:00</updated><title type='text'>The Future of Mysql</title><content type='html'>&lt;span style="font-weight: bold;"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In a recent article from zdnet:&lt;br /&gt;&lt;br /&gt;"Oracle played a big card when it bought InnoDB, the most popular way to inject data into the open source mySQL database.  &lt;p&gt;Monday mySQL responds by getting &lt;a href="http://www.solidtech.com/" target="_blank"&gt;Solid™ Information Technology&lt;/a&gt;, a proprietary database vendor, to take its solidDB Storage Engine for MySQL open source, under the GPL, starting in June. &lt;/p&gt;  &lt;p&gt;Solid has its base in telecommunications and transaction processing, which had been considered a completely different market from the small fry mySQL supplies. It has 3 million copies out at places like Alcatel, Cisco, EMC, HP, NEC, Nokia, and Nortel. &lt;/p&gt;  &lt;p&gt;The addition of Solid technology to mySQL, the company said, puts mySQL into the enterprise league and makes it a direct threat to Oracle." (full article available &lt;a href="http://blogs.zdnet.com/open-source/?p=620"&gt;here&lt;/a&gt;)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Where is mysql going from here?&lt;/span&gt;  The purchase of the solidDB storage engine is a direct result of the Oracle buy out of the innoDB storage engine currently being used.  Oracle attempted to buy out the mysql database back in February for an undisclosed amount, but were unsuccessful.  They are now trying to rid themselves of their competiton by purchasing the developers and the technology behind it.  It was only a matter of time before something like this was going to happen.  As a company based on an open source product, its biggest asset is its developers.  Large companies may not be able to take the company over, but they can purchase the developers behind its main technology.  The Mysql corporation now has control over technology that sets them apart from their competition.&lt;br /&gt;&lt;/p&gt;&lt;span style="font-weight: bold;"&gt;Is this better than Innodb? &lt;/span&gt;It does support transactions, but it does not support foreign keys (it will, however support them in the future).  The following is a list of solidDB features:&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   * ACID transactions.&lt;br /&gt;* Automatic roll forward recovery after failure.&lt;br /&gt;* Uses optimistic (or pessimistic) multiversion concurrency control.&lt;br /&gt;* Database and log files are binary compatible among different platforms.&lt;br /&gt;* Fully multi-threaded using kernel threads. It uses multiple CPUs/cores  if they are available.&lt;br /&gt;* Supports all MySQL SQL data types&lt;br /&gt;* Supports full MySQL syntax&lt;br /&gt;* Isolation levels supported: READ COMMITTED, REPEATABLE READ and SERIALIZABLE&lt;br /&gt;* The MySQL-specific SHOW command can be used to retrieve information&lt;br /&gt;about databases, database engines, tables, and indexes.&lt;br /&gt;* Function names occupy a different name space than table or column names.&lt;br /&gt;* No practical limit on number of tables or columns, or database size.&lt;br /&gt;* The EXPLAIN command can be used to determine how the optimizer resolves&lt;br /&gt;a query. (not yet supported in the prototype)&lt;br /&gt;* Foreign keys and on-line backup will be supported in future product release. They are already supported by solidDB, but the interface between MySQL and solidDB is not yet available for these features.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114642276463603583?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114642276463603583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114642276463603583' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114642276463603583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114642276463603583'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/future-of-mysql.html' title='The Future of Mysql'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114618007848673174</id><published>2006-04-27T16:20:00.000-07:00</published><updated>2006-09-10T18:40:47.776-07:00</updated><title type='text'>10 ajax applications you can't live without</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;1) WadgetOS - &lt;a href="http://www.theartofennui.com/wadgetos/wadgetos.php"&gt;http://www.theartofennui.com/wadgetos/wadgetos.php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;An Ajax- based WebOS. It includes a web-browser, chat client, caclulator, and games (slot machine). I can't find a lot of info on this, because most of it has since been taken down, but it is still interesting.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Here is an update I received from the co-creator&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;i'm the co-creator of wadgetos, thanks for mentioning it. the whole thing was basically a proof of concept, the biggest feature being the ability for anyone to create programs using the powerfull php language. and the info hasn't been taken down, it's just not too easy to find ;)&lt;br /&gt;&lt;a href="http://www.theartofennui.com/2006/03/20/wadgetos-v1-source/"&gt;http://www.theartofennui.com/2006/03/20/wadgetos-v1-source/&lt;/a&gt;&lt;br /&gt;&lt;p&gt;2) Kiko - &lt;a href="http://www.kiko.com/"&gt;http://www.kiko.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;a) dead simple calendar you can use right in your web browser&lt;br /&gt;b) Universal access: Kiko integrates with your mobile phone and AIM and lets you access your calendar from any computer.&lt;br /&gt;c) Share your calendar: Invite anyone to events (not just other Kiko users!) Let others view your calendar with just a click. Check out the &lt;a href="http://www.kiko.com/calendar/example"&gt;example calendar &lt;/a&gt;&lt;br /&gt;As easy as paper - or maybe easier: Write "Pay gas bill every month" onto your calendar and watch Kiko do the Right Thing! &lt;/p&gt;&lt;p&gt;3) time-tracker - &lt;a href="http://www.formassembly.com/time-tracker/"&gt;http://www.formassembly.com/time-tracker/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Time Tracker is a simple tool to keep track of the time you spend on any task.&lt;/p&gt;&lt;p&gt;4) Del.icio.us Director - &lt;a href="http://johnvey.com/features/deliciousdirector/"&gt;http://johnvey.com/features/deliciousdirector/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;del.icio.us direc.tor is a prototype for an alternative web-based rich UI for &lt;a href="http://del.icio.us/"&gt;del.icio.us&lt;/a&gt;. It leverages the XML and XSL services of modern browsers to deliver a responsive interface for managing user accounts with a large number of records.&lt;br /&gt;The main features are:&lt;/p&gt;&lt;p&gt;A) In-browser handling of del.icio.us bookmarks (tested up to 12,000 records)&lt;br /&gt;B) Find-as-you-type searching of all your bookmarks, with basic search operators&lt;br /&gt;C) Sort by description, tags, or timestamp&lt;br /&gt;D) Ad-hoc tag browser &lt;/p&gt;&lt;p&gt;5) Ajax IM - &lt;a href="http://www.unwieldy.net/ajaxim/"&gt;http://www.unwieldy.net/ajaxim/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ajax im is a browser-based instant messaging client. It uses the XMLHTTPRequest object in JavaScript to send and receive commands to and from the server. No refreshing of the page is ever needed for this "web application" to work, as everything is updated in real-time via JavaScript.&lt;/p&gt;&lt;p&gt;6) Ajax Write - &lt;a href="http://www.ajaxwrite.com/"&gt;http://www.ajaxwrite.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;AjaxWrite is a streamlined word processor, comparable to Microsoft Word. To keep the program lean, we left out some obscure advanced features; you'll find the functions you use most often, right where you'd expect them to be. (We're still working on the spell checker.) You can import and export documents in all popular formats, including documents with graphics. The save function lets you save your work to a drive on your computer. Also, since you run ajaxWrite from your web browser, it is platform independent and can therefore be used with any operating system.&lt;/p&gt;&lt;p&gt;7) Ajax Sketch - &lt;a href="http://www.ajaxsketch.com/"&gt;http://www.ajaxsketch.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;AjaxSketch is basically a pared down version of Illustrator or Inkscape — perfect for creating quick charts and diagrams from scratch. It includes autoshapes, pencil mode, and text for creating the basics. You can also edit by resizing, rotating, changing background or pen color, and altering opacity.&lt;/p&gt;&lt;p&gt;8) Eye Spot - &lt;a href="http://eyespot.com/"&gt;http://eyespot.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Use the eyespot Mixer to edit and combine your videos, music and photos online! Share your video and mixes with the world for Free.&lt;/p&gt;&lt;p&gt;9) webezz - &lt;a href="http://www.webezz.net/"&gt;http://www.webezz.net/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Build your website using an easy-to-use Ajax Editor.&lt;/p&gt;&lt;p&gt;1o) meebo - &lt;a href="http://www21.meebo.com/"&gt;http://www21.meebo.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sign into your AIM, MSN, ICQ, Google Talk, Jabber, or Y! Messenger account with this ajax based web site. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114618007848673174?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114618007848673174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114618007848673174' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114618007848673174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114618007848673174'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/10-ajax-applications-you-cant-live.html' title='10 ajax applications you can&apos;t live without'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114513050349011099</id><published>2006-04-27T03:40:00.000-07:00</published><updated>2006-11-13T12:55:45.396-08:00</updated><title type='text'>Free Icons - redux</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Back due to popular demand, here is a list of sites that provide free icons that can be used in any application. Anyone may use the list in it's entirety.&lt;br /&gt;&lt;br /&gt;If anyone has any other sites that offer free icons, please let me know and I will add it.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Updated 4/27/06&lt;br /&gt;&lt;br /&gt;My goal is to have the largest list of free icon sites on the Internet&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.opentux.com.ar/lordcrow/packs/kneu.html"&gt;http://www.opentux.com.ar/lordcrow/packs/kneu.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://moglenstar.net/freeicons/"&gt;http://moglenstar.net/freeicons/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.bluevertigo.com.ar/bluevertigo.htm"&gt;http://www.bluevertigo.com.ar/bluevertigo.htm&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.yellowpipe.com/yis/download/free-icons.php"&gt;http://www.yellowpipe.com/yis/download/free-icons.php&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.zeldman.com/icon.html"&gt;http://www.zeldman.com/icon.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.forrestwalter.com/icons/index.html"&gt;http://www.forrestwalter.com/icons/index.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.silvestre.com.ar"&gt;http://www.silvestre.com.ar&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.deviantart.com/deviation/18808605/"&gt;http://www.deviantart.com/deviation/18808605/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.graphicpush.com/index.php?s=icons"&gt;http://www.graphicpush.com/index.php?s=icons&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tango-project.org/"&gt;http://tango-project.org/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.entity.cc/"&gt;http://www.entity.cc/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.famfamfam.com/about/"&gt;http://www.famfamfam.com/about/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.fasticon.com/downloads.html"&gt;http://www.fasticon.com/downloads.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://strawbee.com/2005/11/06/tiny-little-icons/"&gt;http://strawbee.com/2005/11/06/tiny-little-icons/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.macnn.com/articles/06/04/05/free.icons.flash.fab/"&gt;http://www.macnn.com/articles/06/04/05/free.icons.flash.fab/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://e-lusion.com/"&gt;http://e-lusion.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.yellowpipe.com/yis/download/free-icons.php"&gt;http://www.yellowpipe.com/yis/download/free-icons.php&lt;/a&gt;&lt;br /&gt;&lt;a href="http://icon-king.com/"&gt;http://icon-king.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://sa-ki.deviantart.com/"&gt;http://sa-ki.deviantart.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://mattbrett.com/"&gt;http://mattbrett.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.iconsdesigns.com/2005/12/17/snowish-first-release/"&gt;http://www.iconsdesigns.com/2005/12/17/snowish-first-release/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.iconbuffet.com/"&gt;http://www.iconbuffet.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.drweb.de/webgrafik/symbol_sammlungen.shtml"&gt;http://www.drweb.de/webgrafik/symbol_sammlungen.shtml&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.graphicpush.com/index.php?s=icons"&gt;http://www.graphicpush.com/index.php?s=icons&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.pixelgirlpresents.com"&gt;http://www.pixelgirlpresents.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.iconbazaar.com/"&gt;http://www.iconbazaar.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.iconfactory.com/show.asp"&gt;http://www.iconfactory.com/show.asp&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.aha-soft.com/iconlibs.htm"&gt;http://www.aha-soft.com/iconlibs.htm&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.icongalore.com/sales/purchase-and-download.php"&gt;http://www.icongalore.com/sales/purchase-and-download.php&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ndesign-studio.com/resources/pixel_icons.htm"&gt;http://ndesign-studio.com/resources/pixel_icons.htm&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.websiteicons.com/"&gt;http://www.websiteicons.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://web.thenetter.com/free-icons.html"&gt;http://web.thenetter.com/free-icons.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.brainybetty.com/icons.htm"&gt;http://www.brainybetty.com/icons.htm&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.aceicons.com/free.html"&gt;http://www.aceicons.com/free.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://i-cons.tk/"&gt;http://i-cons.tk/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.iheartny.com/icons.html"&gt;http://www.iheartny.com/icons.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.glyfx.com/free.html"&gt;http://www.glyfx.com/free.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.sharewareplaza.com/Free-Icon-Gallery-download_24998.html"&gt;http://www.sharewareplaza.com/Free-Icon-Gallery-download_24998.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.iconbulk.com/stockfree.asp"&gt;http://www.iconbulk.com/stockfree.asp&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.freewarebox.com/free_762_free-icons-for-winxp-software-download.html"&gt;http://www.freewarebox.com/free_762_free-icons-for-winxp-software-download.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.instantroyaltyfreemusic.com/directory/index.php?c=6"&gt;http://www.instantroyaltyfreemusic.com/directory/index.php?c=6&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gold-software.com/xpstyleicons-review19366.htm"&gt;http://www.gold-software.com/xpstyleicons-review19366.htm&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.treepad.com/free_icons/"&gt;http://www.treepad.com/free_icons/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.top20free.com/icons.html"&gt;http://www.top20free.com/icons.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.freedownloadmanager.org/downloads"&gt;http://www.freedownloadmanager.org/downloads&lt;/a&gt;&lt;br /&gt;/royalty_free_icons_software/&lt;br /&gt;&lt;a href="http://www.obout.com/t2/icons.aspx"&gt;http://www.obout.com/t2/icons.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://jeenaparadies.net/webdesign/free-icons"&gt;http://jeenaparadies.net/webdesign/free-icons&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.fileedge.com/get/free-icons/"&gt;http://www.fileedge.com/get/free-icons/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.clickfire.com/content/graphics/favicons/favicons.php"&gt;http://www.clickfire.com/content/graphics/favicons/favicons.php&lt;/a&gt;&lt;br /&gt;&lt;a href="http://turbomilk.com/freeicons/"&gt;http://turbomilk.com/freeicons/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is a random site in Japanese I found while searching for free icons. Although it contains no icons, it does contain i-candy. Enjoy:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.akikobrand.com/"&gt;http://www.akikobrand.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114513050349011099?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114513050349011099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114513050349011099' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114513050349011099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114513050349011099'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/free-icons-redux.html' title='Free Icons - redux'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114611471591033026</id><published>2006-04-26T22:10:00.000-07:00</published><updated>2006-04-27T05:47:26.496-07:00</updated><title type='text'>Commodore 64 emulator in PHP</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;For those of you that still remember the early days of computing, there is a commodore 64 emulator written in PHP.&lt;br /&gt;&lt;br /&gt;A live demo is available here: &lt;a href="http://phpc64.extra.hu/c64/index.html"&gt;http://phpc64.extra.hu/c64/index.html&lt;/a&gt;&lt;br /&gt;the sourcecode is available here: &lt;a href="http://phpc64.extra.hu/php_c64_source.tar.gz"&gt;http://phpc64.extra.hu/php_c64_source.tar.gz&lt;/a&gt; (released under the GPL License)&lt;br /&gt;&lt;br /&gt;Homepage is here: &lt;a href="http://phpc64.extra.hu/"&gt;http://phpc64.extra.hu/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Some Commands&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;The following are supported: NEW, RUN, LIST, LIST N-M, SAVE "NAME", LOAD "NAME",&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Programming examples&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;PRINT "HELLO WORLD"&lt;br /&gt;IF 2&lt;6&gt;"A" THEN XXX (Note: XXX being a line number.)&lt;br /&gt;GOTO XXXGOSUB XXX (...)&lt;br /&gt;RETURN&lt;br /&gt;&lt;br /&gt;10 FOR I%=1 TO 1020&lt;br /&gt;PRINT "C64"&lt;br /&gt;30 NEXT I% (Note: variable after NEXT is optional, but recommended)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Known Bugs&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;-----* doesn't check BASIC programs for syntax errors (because of size limitations)*&lt;br /&gt;Internet Explorer crashes when loading programs longer then approximatly 700 bytes&lt;br /&gt;* when the frame containing c.php is loaded before creation of frame named 's', it causes javascript error; you should reload the page when this bug shows&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Tricks&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;in Opera the execution of the BASIC program stops when INPUT commands are being executed; it will continoue if you activate another tab, then return to the window of the Emulator (you should press RETURN)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114611471591033026?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114611471591033026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114611471591033026' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114611471591033026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114611471591033026'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/commodore-64-emulator-in-php.html' title='Commodore 64 emulator in PHP'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114609150309827278</id><published>2006-04-26T15:44:00.000-07:00</published><updated>2006-05-09T16:19:03.066-07:00</updated><title type='text'>An operating system in PHP</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Is it possible? a full-fledged operating system written in PHP? I never thought so before, but I recently found a great application that proves me wrong. Even though it has some help from java, flash, and javascript, it is still a very fast and functional OS. It is also open source, so you can install it on your own server, but if you don't have the hardware, a free account can be created on their servers.&lt;br /&gt;&lt;br /&gt;first, here is some info on how to get it:&lt;br /&gt;&lt;br /&gt;it's called eyeos and you can create a free account here: &lt;a href="http://www.eyeos.info"&gt;http://www.eyeos.info&lt;/a&gt;&lt;br /&gt;the main site is located here: &lt;a href="http://www.eyeos.org"&gt;http://www.eyeos.org&lt;/a&gt;&lt;br /&gt;API Info: &lt;a href="http://www.eyeos.org/appsAPI"&gt;http://www.eyeos.org/appsAPI&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;mini-server for windows: &lt;a href="http://www.eyeos.org/miniserver"&gt;http://www.eyeos.org/miniserver&lt;/a&gt;&lt;br /&gt;Source code: &lt;a href="http://www.eyeos.org/Downloads"&gt;http://www.eyeos.org/Downloads&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;With eyeOS you can access your data and your applications anywhere, anytime. A virtual office in your hands, no need to install anything in the computer. Everything lives in the browser, for you and your work colleagues. eyeOS is open source and free software. &lt;a href="http://www.eyeos.info/"&gt;Set up freely an account on our servers&lt;/a&gt; or, if you prefer it, &lt;a href="http://www.eyeos.org/Downloads"&gt;install it in your server&lt;/a&gt;. Make your life easier with the virtual word processor, calendar, file manager, messenger, browser and other applications. And if you want more applications, just visit the &lt;a href="http://www.eyeapps.org/"&gt;eyeOS Application Database&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;My review&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Today, I created a free account online. Below is a screenshot of the built-in word-processor:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/eyeos.png"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/eyeos.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;What I liked about it&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;A) Very fast and Responsive Interface&lt;br /&gt;B) Open Source and easy-to-use API&lt;br /&gt;C) Written in PHP&lt;br /&gt;D) eye candyish graphics&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Where I feel it needs work&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;A) Not many apps. I think with an increase in user support, it will become more of a development platform than a proof of concept.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Although it may not have a wide variety of uses right now, it is very interesting to see that it is possible to create an entire platform using PHP and other web technologies.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Other Operating systems in PHP&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Ssearching the Internet, I also found some other Operating Systems written in PHP: &lt;p&gt;Phoenixz: &lt;a href="http://sourceforge.net/projects/phoenixz/"&gt;http://sourceforge.net/projects/phoenixz/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Jsuix (not PHP, but a unix like OS written in javascript): &lt;a href="http://www.masswerk.at/jsuix/"&gt;http://www.masswerk.at/jsuix/&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114609150309827278?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114609150309827278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114609150309827278' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114609150309827278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114609150309827278'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/operating-system-in-php.html' title='An operating system in PHP'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114601427852111311</id><published>2006-04-25T18:15:00.000-07:00</published><updated>2006-09-17T15:37:40.403-07:00</updated><title type='text'>Programming Languages you never knew existed</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;I have compiled a list of interesting programming languages from around the Internet. If anyone has any more to add to this list, let me know.&lt;br /&gt;&lt;br /&gt;&lt;a title="ALPACA programming language" href="http://en.wikipedia.org/wiki/ALPACA_programming_language"&gt;ALPACA&lt;/a&gt; - a meta-language for programming arbitrary &lt;a title="Cellular automata" href="http://en.wikipedia.org/wiki/Cellular_automata"&gt;cellular automata&lt;/a&gt;&lt;br /&gt;&lt;a class="external text" title="http://esoteric.voxelperfect.net/wiki/Aura" href="http://esoteric.voxelperfect.net/wiki/Aura"&gt;Aura&lt;/a&gt; - a brainfuck descendant&lt;br /&gt;&lt;a title="Arbol programming language" href="http://en.wikipedia.org/wiki/Arbol_programming_language"&gt;Arbol&lt;/a&gt; &lt;a class="external autonumber" title="http://cluster.phys.uni-sofia.bg/ross/arbol/" href="http://cluster.phys.uni-sofia.bg/ross/arbol/"&gt;[1]&lt;/a&gt; - a small functional programming language&lt;br /&gt;&lt;a title="Argh! programming language" href="http://en.wikipedia.org/wiki/Argh!_programming_language"&gt;Argh!&lt;/a&gt; - A &lt;a title="Fungeoid" href="http://en.wikipedia.org/wiki/Fungeoid"&gt;fungeoid&lt;/a&gt; with complex data storage&lt;br /&gt;&lt;a class="external text" title="http://sange.fi/~atehwa/b5/" href="http://sange.fi/~atehwa/b5/"&gt;B5&lt;/a&gt; - a functional macro processor&lt;br /&gt;&lt;a class="external text" title="http://fvdp.homestead.com/files/eso_index.html#BFM" href="http://fvdp.homestead.com/files/eso_index.html#BFM"&gt;BFM&lt;/a&gt; - a brainfuck variant with macros&lt;br /&gt;&lt;a class="external text" title="http://www.dangermouse.net/esoteric/bit.html" href="http://www.dangermouse.net/esoteric/bit.html"&gt;BIT&lt;/a&gt; - where the basic types are the bit and the address-of-a-bit&lt;br /&gt;&lt;a class="external text" title="http://esoteric.voxelperfect.net/wiki/Braincopter" href="http://esoteric.voxelperfect.net/wiki/Braincopter"&gt;Braincopter&lt;/a&gt; - an image based brainfuck clone&lt;br /&gt;&lt;a title="Brainfuck" href="http://en.wikipedia.org/wiki/Brainfuck"&gt;brainfuck&lt;/a&gt; - designed to have the smallest compiler ever&lt;br /&gt;&lt;a class="external text" title="http://web.archive.org/web/20040206060216/http://demo.raww.net/muriel/bub.html" href="http://web.archive.org/web/20040206060216/http://demo.raww.net/muriel/bub.html"&gt;Bub&lt;/a&gt; - a brainfuck variant&lt;br /&gt;&lt;a class="external text" title="http://esoteric.voxelperfect.net/wiki/Lesser_known_programming_languages" href="http://esoteric.voxelperfect.net/wiki/Lesser_known_programming_languages"&gt;C-&lt;/a&gt; - a fictional joke language&lt;br /&gt;&lt;a class="external text" title="http://c-p-l.sourceforge.net/" href="http://c-p-l.sourceforge.net/"&gt;C-P-L&lt;/a&gt; - a language in which a non-comment is a syntax error (but on the plus side, all styles of comments are supported, and comments may be arbitrarily nested).&lt;br /&gt;&lt;a class="external text" title="http://web.archive.org/web/20031209180058/http%3A//www.mines.edu/students/b/bolmstea/malbolge/index.html" href="http://web.archive.org/web/20031209180058/http://www.mines.edu/students/b/bolmstea/malbolge/index.html"&gt;Dis&lt;/a&gt; - a variant of Malbolge&lt;br /&gt;&lt;a class="external text" title="http://esoteric.voxelperfect.net/wiki/Lesser_known_programming_languages" href="http://esoteric.voxelperfect.net/wiki/Lesser_known_programming_languages"&gt;DOGO&lt;/a&gt; - a fictional joke language&lt;br /&gt;&lt;a title="Doublefuck" href="http://en.wikipedia.org/wiki/Doublefuck"&gt;Doublefuck&lt;/a&gt; - an extended version of brainfuck&lt;br /&gt;&lt;a class="external text" title="http://esoteric.voxelperfect.net/wiki/Lesser_known_programming_languages" href="http://esoteric.voxelperfect.net/wiki/Lesser_known_programming_languages"&gt;FIFTH&lt;/a&gt; - a fictional joke language&lt;br /&gt;&lt;a title="FiPL" href="http://en.wikipedia.org/wiki/FiPL"&gt;FiPL - &lt;/a&gt;Fish Programming language (half-joke, a parody on programming language paradigms)&lt;br /&gt;&lt;a class="external text" title="http://www.aldweb.com/articles.php?lng=" href="http://www.aldweb.com/articles.php?lng=en&amp;pg=5298" pg="5298"&gt;HELP&lt;/a&gt; - HELP stands for Hellish &amp;amp; Esoteric Language for Palm&lt;br /&gt;&lt;a class="external text" title="http://catseye.mine.nu:8080/projects/hunter/" href="http://catseye.mine.nu:8080/projects/hunter/"&gt;Hunter&lt;/a&gt; - a language related to noit o’ mnain worb and RUBE&lt;br /&gt;&lt;a class="external text" title="http://spuzz.net/projects/homespring/about.php" href="http://spuzz.net/projects/homespring/about.php"&gt;Homespring&lt;/a&gt; - an excessively high-level language, where the instructions are &lt;a title="English language" href="http://en.wikipedia.org/wiki/English_language"&gt;English&lt;/a&gt;&lt;br /&gt;sentences based around the metaphor of a mountainside river.&lt;br /&gt;&lt;a class="external text" title="http://web.archive.org/web/20020617125506/www.catseye.mb.ca/esoteric/illgol/%23%23/" href="http://web.archive.org/web/20020617125506/www.catseye.mb.ca/esoteric/illgol/##/"&gt;Illgol##&lt;/a&gt; - a variant of ILLGOL&lt;br /&gt;&lt;a title="Java2K" href="http://en.wikipedia.org/wiki/Java2K"&gt;Java2K&lt;/a&gt; - a probabilistic language&lt;br /&gt;&lt;a title="L33t programming language" href="http://en.wikipedia.org/wiki/L33t_programming_language"&gt;l33t&lt;/a&gt; - inspired by brainfuck and Beatnik, source code is entered as 'l33t 5p34k'&lt;br /&gt;&lt;a class="external text" title="http://esoteric.voxelperfect.net/wiki/Mycelium" href="http://esoteric.voxelperfect.net/wiki/Mycelium"&gt;Mycelium&lt;/a&gt; - a 2-dimensional image based language where the code is read from a png image&lt;br /&gt;&lt;a class="external text" title="http://sourceforge.net/projects/nietzsche/" href="http://sourceforge.net/projects/nietzsche/"&gt;Nietzsche&lt;/a&gt; - a hexadecimal language&lt;br /&gt;&lt;a title="Obfuna" href="http://en.wikipedia.org/wiki/Obfuna"&gt;Obfuna&lt;/a&gt; - single character instructions for unary operations&lt;br /&gt;&lt;a class="external text" title="http://esoteric.voxelperfect.net/wiki/Orthagonal" href="http://esoteric.voxelperfect.net/wiki/Orthagonal"&gt;Orthagonal&lt;/a&gt; - a two-dimensional stack-based language&lt;br /&gt;&lt;a title="Piet programming language" href="http://en.wikipedia.org/wiki/Piet_programming_language"&gt;Piet&lt;/a&gt; - an art-based programming language&lt;br /&gt;&lt;a class="external text" title="http://homepage.eircom.net/~kmgaughan/esolang/q-bal/" href="http://homepage.eircom.net/~kmgaughan/esolang/q-bal/"&gt;Q-BAL&lt;/a&gt; - a queue-based language&lt;br /&gt;&lt;a class="external text" title="http://web.archive.org/web/20020816074556/www.catseye.mb.ca/esoteric/rube/index.html" href="http://web.archive.org/web/20020816074556/www.catseye.mb.ca/esoteric/rube/index.html"&gt;RUBE&lt;/a&gt; - not quite a cellular automaton&lt;br /&gt;&lt;a class="external text" title="http://p-nand-q.com/humor/programming_languages/smithsharp.html" href="http://p-nand-q.com/humor/programming_languages/smithsharp.html"&gt;SMITH#&lt;/a&gt; - described as "the future of GOTO"&lt;br /&gt;&lt;a title="Snobol" href="http://en.wikipedia.org/wiki/Snobol"&gt;snobol&lt;/a&gt; - StriNg Oriented symBOlic Language&lt;br /&gt;&lt;a title="Spoon programming language" href="http://en.wikipedia.org/wiki/Spoon_programming_language"&gt;Spoon&lt;/a&gt; - a brainfuck derivative&lt;br /&gt;&lt;a title="TWiRQ programming language" href="http://en.wikipedia.org/wiki/TWiRQ_programming_language"&gt;TWiRQ&lt;/a&gt; &lt;a class="external autonumber" title="http://www.parabolagames.com/?page=" href="http://www.parabolagames.com/?page=catalog&amp;amp;p=twirq_1_0_0" p="twirq_1_0_0"&gt;[12]&lt;/a&gt; - a two-dimensional language&lt;br /&gt;&lt;a title="UNITY programming language" href="http://en.wikipedia.org/wiki/UNITY_programming_language"&gt;UNITY&lt;/a&gt; - a programming language without program flow.&lt;br /&gt;&lt;a title="Unlambda" href="http://www.madore.org/~david/programs/unlambda/"&gt;Unlambda&lt;/a&gt; - Your Functional Programming Language Nightmares Come True&lt;br /&gt;&lt;a title="URISC" href="http://en.wikipedia.org/wiki/URISC"&gt;URISC&lt;/a&gt; - a machine with only one instruction&lt;br /&gt;&lt;a title="Whenever programming language" href="http://en.wikipedia.org/wiki/Whenever_programming_language"&gt;Whenever&lt;/a&gt; - a language with no sense of urgency&lt;br /&gt;&lt;a title="Whitespace programming language" href="http://en.wikipedia.org/wiki/Whitespace_programming_language"&gt;Whitespace&lt;/a&gt; - only spaces, tabs and newlines are considered syntax&lt;br /&gt;&lt;a class="external text" title="http://www.bur.st/~yayyak/Wiki/Specification.html" href="http://www.bur.st/~yayyak/Wiki/Specification.html"&gt;Wiki&lt;/a&gt; - whose programs consist of machine code encoded as &lt;a title="Wikipedia" href="http://en.wikipedia.org/wiki/Wikipedia"&gt;Wikipedia&lt;/a&gt; articles.&lt;br /&gt;&lt;a title="Winter" href="http://swiftlytilting.com/t/winter"&gt;Winter&lt;/a&gt; - mediaWiki scripting language&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114601427852111311?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114601427852111311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114601427852111311' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114601427852111311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114601427852111311'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/programming-languages-you-never-knew.html' title='Programming Languages you never knew existed'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114585271971488779</id><published>2006-04-23T21:23:00.000-07:00</published><updated>2006-05-12T01:47:29.426-07:00</updated><title type='text'>Top 10 PHP frameworks</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Below is a list of the top 10 frameworks for PHP:&lt;br /&gt;&lt;br /&gt;10) &lt;a href="http://neonlabs.structum.com.mx/main.php?strItem=moebius"&gt;Mobius&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Moebius PHP Library is a project that concentrates on building a set of classes that wraps around the built-in php functions. The idea behind the creation of this library is to create an object framework to work on PHP, going from mySQL management to Table manipulation. The site is powered in fact by the moebius library.&lt;br /&gt;&lt;br /&gt;9) &lt;a href="http://www.blueshoes.org/"&gt;Blueshoes&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;BlueShoes provides developers with real-world solutions for common system components such as User Management, Session Handling, Closed User Groups, Exception Handling and Logging, Object Persisting as well as Form building and Handling.&lt;br /&gt;&lt;br /&gt;8) &lt;a href="http://sourceforge.net/projects/phrame"&gt;Phrame&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Phrame is a web development platform for PHP based on the design of Jakarta Struts. Phrame provides your basic Model-View-Controller architecture, and also takes a step further adding standard components such as: HashMap, ArrayList, Stack, etc...&lt;br /&gt;&lt;br /&gt;7) &lt;a href="http://php-fusebox.sourceforge.net/"&gt;Fusebox&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Fusebox is the most popular framework for building ColdFusion and PHP web applications. "Fuseboxers" find that the framework releases them from much of the drudgery of writing applications and enables them to focus their efforts on creating great, customer-focused software.&lt;br /&gt;&lt;br /&gt;6) &lt;a href="http://seagull.phpkitchen.com/"&gt;Seagull&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Seagull is an object oriented framework written in PHP that focuses on best practices, clean code and reusable components.&lt;br /&gt;&lt;br /&gt;5) &lt;a href="http://ez.no/products/ez_publish"&gt;EZ Publish&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;eZ publish gives you control of your content. Create, handle, sort and store documents, files and images. Publish them in the format, channel or media you prefer.&lt;br /&gt;&lt;br /&gt;4) &lt;a href="http://sourceforge.net/projects/krill/"&gt;Krill&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Krill is a php Framework based on the MVC2 paradigm.&lt;br /&gt;&lt;br /&gt;3) &lt;a href="http://sourceforge.net/projects/php-booba/"&gt;php-booba&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Simple PHP framework for developing web applications.&lt;br /&gt;&lt;br /&gt;2) &lt;a href="http://www.edit-x.com/"&gt;edit-x&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Edit-X CMS features enhanced tools for larger content management environments and offers support for multiple sites and unlimited authorized users. Users have an intuitive WYSIWYG (What You See Is What You Get) editorial interface that makes adding and updating content as easy as using a word processor. Edit-X CMS is designed to give organizations of all sizes a scalable solution for managing online information.&lt;br /&gt;&lt;br /&gt;1) &lt;a href="http://www.binarycloud.com/"&gt;Binary Cloud&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;binarycloud is a web application framework for the &lt;a class="urllink" href="http://www.php.net/"&gt;PHP&lt;/a&gt; language. It provides a set of services that are frequently used when writing web applications and helps to improve reuseability by providing a modular application infrastructure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114585271971488779?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114585271971488779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114585271971488779' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114585271971488779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114585271971488779'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/top-10-php-frameworks.html' title='Top 10 PHP frameworks'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114577067609398084</id><published>2006-04-22T22:37:00.000-07:00</published><updated>2006-05-12T00:54:01.213-07:00</updated><title type='text'>Converting php scripts to windows apps</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I came across this application the other day that will allow you to convert php scripts to native windows applications.&lt;br /&gt;&lt;br /&gt;The application is called WinBinder and it is available &lt;a href="http://hypervisual.com/winbinder/examples.php"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;S&lt;span style="FONT-WEIGHT: bold"&gt;ome benefits of using winbinder&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&lt;b&gt;Some key benefits&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Large installed base of PHP programmers.&lt;/li&gt;&lt;li&gt;No compiling and linking steps necessary: just code and run.&lt;/li&gt;&lt;li&gt;Access to the vast range of existing PHP functions and extensions, including databases, graphics, web functions, XML, PDF, and much more.&lt;/li&gt;&lt;li&gt;A small set of WinBinder functions encapsulates many complex aspects of the Windows API and makes programming for Windows an easy task.&lt;/li&gt;&lt;li&gt;Provides 100% native Windows classes and controls.&lt;/li&gt;&lt;li&gt;Interfaces directly to the Window API. This means fast execution, no extra libraries and no installation required.&lt;/li&gt;&lt;li&gt;Supports both procedural and object-oriented programming models.&lt;/li&gt;&lt;li&gt;High performance, compares favorably to most scripting languages.&lt;/li&gt;&lt;li&gt;Produces standalone applications that can be easily installed and removed with no reboot.&lt;/li&gt;&lt;li&gt;Small footprint. A simple Windows application, complete with the PHP runtime and SQLite extension, is smaller than 700 kB (zipped).&lt;/li&gt;&lt;li&gt;A database-independent framework allows easy coding (no SQL knowledge is necessary) and smooth integration with the WinBinder code.&lt;/li&gt;&lt;li&gt;No database server required if using SQLite.&lt;/li&gt;&lt;li&gt;Does not need to use to the Windows registry, but may use it if necessary.&lt;/li&gt;&lt;li&gt;&lt;a href="http://hypervisual.com/winbinder/overview.php"&gt;More...&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Simple Example&lt;/span&gt;&lt;br /&gt;&lt;p&gt;Here is the minimum code required for a Windows application:&lt;/p&gt;&lt;span style="font-size:100%;"&gt;&lt;code&gt;&lt;span style="COLOR: rgb(0,0,0)"&gt;&lt;span style="COLOR: rgb(0,0,187)"&gt;&lt;span style="COLOR: rgb(0,119,0)"&gt;include &lt;/span&gt;&lt;span style="COLOR: rgb(221,0,0)"&gt;"../include/winbinder.php"&lt;/span&gt;&lt;span style="COLOR: rgb(0,119,0)"&gt;; &lt;/span&gt;&lt;span style="COLOR: rgb(255,128,0)"&gt;// Include WinBinder library&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(0,0,187)"&gt;wb_create_window&lt;/span&gt;&lt;span style="COLOR: rgb(0,119,0)"&gt;(&lt;/span&gt;&lt;span style="COLOR: rgb(0,0,187)"&gt;NULL&lt;/span&gt;&lt;span style="COLOR: rgb(0,119,0)"&gt;, &lt;/span&gt;&lt;span style="COLOR: rgb(0,0,187)"&gt;PopupWindow&lt;/span&gt;&lt;span style="COLOR: rgb(0,119,0)"&gt;, &lt;/span&gt;&lt;span style="COLOR: rgb(221,0,0)"&gt;"Hello"&lt;/span&gt;&lt;span style="COLOR: rgb(0,119,0)"&gt;, &lt;/span&gt;&lt;span style="COLOR: rgb(0,0,187)"&gt;480&lt;/span&gt;&lt;span style="COLOR: rgb(0,119,0)"&gt;, &lt;/span&gt;500&lt;span style="COLOR: rgb(0,119,0)"&gt;); &lt;/span&gt;&lt;span style="COLOR: rgb(255,128,0)"&gt;// Create application window&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(0,0,187)"&gt;wb_main_loop&lt;/span&gt;&lt;span style="COLOR: rgb(0,119,0)"&gt;(); &lt;/span&gt;&lt;span style="COLOR: rgb(255,128,0)"&gt;// Enter message loop&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(0,0,0)"&gt;here is what the above will display when compiled:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/minimal.png"&gt;&lt;img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/minimal.png" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114577067609398084?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114577067609398084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114577067609398084' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114577067609398084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114577067609398084'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/converting-php-scripts-to-windows-apps.html' title='Converting php scripts to windows apps'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114571986043137070</id><published>2006-04-22T08:29:00.000-07:00</published><updated>2006-05-24T14:19:46.193-07:00</updated><title type='text'>add/remove program registry info</title><content type='html'>&lt;span style="font-weight: bold;"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For people that write windows applications, the following info will allow you to add your application to the add/remove programs menu.&lt;br /&gt;&lt;br /&gt;Create a key with your app name name under HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall to add entries to the "Add/Remove Programs" section in the Control Panel.&lt;br /&gt;&lt;br /&gt;For Windows NT (NT4/2000/XP), it's also possible to create the key in the HKCU hive, so it will only appear for the current user.&lt;br /&gt;&lt;br /&gt;There are several values you can write to the key to give additional information about your application and the uninstaller.&lt;br /&gt;&lt;br /&gt;Write a value using the WriteRegStr command (for strings) or WriteRegDWORD command (for DWORD values).&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Product"                "DisplayName" "Application Name"&lt;br /&gt;&lt;br /&gt;Required values&lt;br /&gt;&lt;br /&gt;  * DisplayName (string) - Name of the application&lt;br /&gt;  * UninstallString (string) - Path and filename of the uninstaller. You should always quote the path to make sure spaces in the path will not disrupt Windows to find the uninstaller.&lt;br /&gt;&lt;br /&gt;HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\myapp"                "DisplayName" "This is my cool application"&lt;br /&gt;HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\myapp"                "UninstallString" "$INSTDIR\uninstall.exe"&lt;br /&gt;&lt;br /&gt;Optional values&lt;br /&gt;&lt;br /&gt;Supported on: Windows XP.&lt;br /&gt;&lt;br /&gt;  * InstallLocation (string) - Installation directory ($INSTDIR)&lt;br /&gt;  * DisplayIcon (string) - Path, filename and index of of the icon that will be displayed next to your application name&lt;br /&gt;&lt;br /&gt;  * Publisher (string) - (Company) name of the publisher&lt;br /&gt;&lt;br /&gt;  * ModifyPath (string) - Path and filename of the application modify program&lt;br /&gt;  * InstallSource (string) - Location where the application was installed from&lt;br /&gt;&lt;br /&gt;  * ProductID (string) - Product ID of the application&lt;br /&gt;  * RegOwner (string) - Registered owner of the application&lt;br /&gt;  * RegCompany (string) - Registered company of the application&lt;br /&gt;&lt;br /&gt;  * HelpLink (string) - Link to the support website&lt;br /&gt;  * HelpTelephone (string) - Telephone number for support&lt;br /&gt;&lt;br /&gt;  * URLUpdateInfo (string) - Link to the website for application updates&lt;br /&gt;  * URLInfoAbout (string) - Link to the application home page&lt;br /&gt;&lt;br /&gt;  * DisplayVersion (string) - Displayed version of the application&lt;br /&gt;  * VersionMajor (DWORD) - Major version number of the application&lt;br /&gt;  * VersionMinor (DWORD) - Minor version number of the application&lt;br /&gt;&lt;br /&gt;  * NoModify (DWORD) - 1 if uninstaller has no option to modify the installed application&lt;br /&gt;  * NoRepair (DWORD) - 1 if the uninstaller has no option to repair the installation&lt;br /&gt;&lt;br /&gt;If both NoModify and NoRepair are set to 1, the button displays "Remove" instead of "Modify/Remove".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Supported on: Windows XP Service Pack 2.&lt;br /&gt;&lt;br /&gt;  * ParentKeyName (string) - If the program is an update of a parent program, specify the parent program subkey name. If "OperatingSystem", it's an update for Windows.&lt;br /&gt;  * ParentDisplayName (string) - If the program is an update of a parent program, specify the parent program name (as specified on the parent's "DisplayName").&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114571986043137070?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114571986043137070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114571986043137070' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114571986043137070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114571986043137070'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/addremove-program-registry-info.html' title='add/remove program registry info'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114550952618008930</id><published>2006-04-19T22:05:00.000-07:00</published><updated>2007-03-16T16:58:28.110-07:00</updated><title type='text'>php games</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/5.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/5.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;by Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The following are a list of free games written in PHP&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.heroesmini.com/register.php"&gt;http://www.heroesmini.com/register.php&lt;/a&gt; - Heroes of Might and Magic&lt;br /&gt;&lt;a href="http://dragon.se7enet.com/dev.php"&gt;http://dragon.se7enet.com/dev.php&lt;/a&gt; - Dragon Knight&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/blacknova"&gt;http://sourceforge.net/projects/blacknova&lt;/a&gt; - black nova Traders&lt;br /&gt;&lt;a href="http://www.0php.com/reviews/0171.php"&gt;http://www.0php.com/reviews/0171.php&lt;/a&gt; - hangman&lt;br /&gt;&lt;a href="http://www.0php.com/reviews/0172.php"&gt;http://www.0php.com/reviews/0172.php&lt;/a&gt; - anoi towers&lt;br /&gt;&lt;a href="http://www.geocities.com/markoriedelde/life/index.html"&gt;http://www.geocities.com/markoriedelde/life/index.html&lt;/a&gt; - Life&lt;br /&gt;&lt;a href="http://www.geocities.com/markoriedelde/Minesweeper/index.html"&gt;http://www.geocities.com/markoriedelde/Minesweeper/index.html&lt;/a&gt; - minesweeper&lt;br /&gt;&lt;a href="http://www.chipmunk-scripts.com/scripts/riddles.php"&gt;http://www.chipmunk-scripts.com/scripts/riddles.php&lt;/a&gt; - chipmunk riddles&lt;br /&gt;&lt;a href="http://www.chipmunk-scripts.com/killmonster/login.php"&gt;http://www.chipmunk-scripts.com/killmonster/login.php&lt;/a&gt; - kill monster&lt;br /&gt;&lt;a href="http://sportsphool.sourceforge.net/"&gt;http://sportsphool.sourceforge.net/&lt;/a&gt; - sportsPHool&lt;br /&gt;&lt;a href="http://www.fightwith.me.uk/"&gt;http://www.fightwith.me.uk/&lt;/a&gt; - fightclub&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Online Role Playing Games&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://phpolrpg.sourceforge.net/"&gt;http://phpolrpg.sourceforge.net/&lt;/a&gt; - PHP online RPG&lt;br /&gt;&lt;a href="http://dragon-soldier.net/"&gt;http://dragon-soldier.net/&lt;/a&gt; - dragon soldier&lt;br /&gt;&lt;a href="http://www3.kingdomofloathing.com"&gt;http://www3.kingdomofloathing.com&lt;/a&gt; - kingdom of loathing&lt;br /&gt;&lt;a href="http://www.lotgd.net/"&gt;http://www.lotgd.net/&lt;/a&gt; - legend of the green dragon&lt;br /&gt;&lt;a href="http://www.vendetta1923.com/"&gt;http://www.vendetta1923.com/&lt;/a&gt; - vendetta&lt;br /&gt;&lt;a href="http://www.thecrims.com/"&gt;http://www.thecrims.com/&lt;/a&gt; - the crims&lt;br /&gt;&lt;a href="http://www.travian.com/"&gt;http://www.travian.com/&lt;/a&gt; - travian&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Strategy&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.blacknova.net"&gt;http://www.blacknova.net&lt;/a&gt; - black nova&lt;br /&gt;&lt;a href="http://www.aatraders.com"&gt;http://www.aatraders.com&lt;/a&gt; - aatraders&lt;br /&gt;&lt;a href="http://www.quantum-star.com"&gt;http://www.quantum-star.com&lt;/a&gt;  - quantum-star&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Other &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://deepdungeons.sourceforge.net/"&gt;http://deepdungeons.sourceforge.net/&lt;/a&gt; - This is a desktop app written in PHP+GTK it is called Deep Dungeons.&lt;br /&gt;&lt;a href="http://www.32cards.com"&gt;http://www.32cards.com&lt;/a&gt; - 2006 world cup game based on the PECL extension winbinder.&lt;br /&gt;&lt;a href="http://www.ogame.org/"&gt;http://www.ogame.org/&lt;/a&gt; - strategic space simulation game&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114550952618008930?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114550952618008930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114550952618008930' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114550952618008930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114550952618008930'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/php-games.html' title='php games'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114550740623919352</id><published>2006-04-19T21:29:00.000-07:00</published><updated>2006-04-26T20:27:48.616-07:00</updated><title type='text'>free RSS to HTML PHP script</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/emblem.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/6545/2077/320/emblem.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;By Justin Silverton&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;Introduction &lt;/b&gt;&lt;br /&gt;               &lt;br /&gt;                        FeedForAll has made available a free PHP program                                  called rss2html.php, which can be used by webmasters                                  to automatically display RSS feeds on their website.                                  The resulting webpage will always show the RSS                                  feed's most current data. The advantage of using                                  the rss2html.php script is that the resulting                                  webpage's contents will always be up to date,                                  and can be easily spidered by search engines.                         &lt;br /&gt;&lt;br /&gt;it can be found &lt;a href="http://www.feedforall.com"&gt;Here&lt;/a&gt;&lt;br /&gt;               &lt;br /&gt;                        &lt;b&gt;&lt;a name="uses"&gt;&lt;/a&gt;Uses&lt;br /&gt;                        &lt;/b&gt;&lt;br /&gt;                        - Create a webpage with an RSS feed's information                         &lt;br /&gt;                        - Insert an RSS feed's information into a location                                  in an existing webpage&lt;br /&gt;               &lt;br /&gt;                        &lt;b&gt;Templates &lt;/b&gt;&lt;br /&gt;               &lt;br /&gt;                        FeedForAll's rss2html.php script uses templates                                  to generate its output. The templates allow you                                  to easily control what the resulting webpage will                                  look like. A template can be used to generate                                  a complete webpage, or a portion of a webpage                                  like a table (which can then be included inside                                  an existing webpage). The template's syntax is                                  exactly the same as the syntax used in FeedForAll's                                  export functions.&lt;br /&gt;               &lt;br /&gt;                        Templates are simply standard HTML documents,                                  with special variables inserted where the RSS                                  feed's data should appear. Usually the easiest                                  way to create a template is to create a sample                                  webpage with some real data in it, and then replace                                  the feed's data with template variables, or modify                                  an existing webpage, by adding template variables.                                  Here is a list of the variables supported by FeedForAll's                                  rss2html.php script:&lt;br /&gt;               &lt;br /&gt;                        &lt;b&gt;~~~FeedTitle~~~ &lt;/b&gt;(The feed's title)&lt;br /&gt;                        &lt;b&gt;~~~FeedDescription~~~&lt;/b&gt; (the feed's description)&lt;br /&gt;                        &lt;b&gt;~~~FeedContentEncoded~~~&lt;/b&gt;(the feed's description                                  for the ContentEncoded field)&lt;br /&gt;               &lt;br /&gt;                        &lt;b&gt;~~~FeedLink~~~&lt;/b&gt; (the feed's link)&lt;br /&gt;                        &lt;b&gt;~~~FeedPubDate~~~&lt;/b&gt; (the feed's pub date/time                                  in RSS format)&lt;br /&gt;                        &lt;b&gt;~~~FeedPubLongDate~~~&lt;/b&gt; (the feed's date                                  in your Windows long date format) &lt;b&gt;~~~FeedPubShortDate~~~&lt;/b&gt;                                  (the feed's date in your Windows short date format)&lt;br /&gt;                        &lt;b&gt;~~~FeedPubLongTime~~~&lt;/b&gt; (the feed's time                                  in your Windows long time format)&lt;br /&gt;                        &lt;b&gt;~~~FeedPubShortTime~~~&lt;/b&gt; (the feed's time                                  in your Windows short time format)&lt;br /&gt;                        &lt;b&gt;~~~FeedImageUrl~~~&lt;/b&gt; (the URL to the feed's                                  image)&lt;br /&gt;                        &lt;b&gt;~~~FeedImageTitle~~~&lt;/b&gt; (the title for the                                  feed's image)&lt;br /&gt;                        &lt;b&gt;~~~FeedImageLink~~~&lt;/b&gt; (the link associated                                  with the feed's image)                                &lt;p&gt;&lt;br /&gt;                        &lt;b&gt;~~~FeedMaxItems=X~~~&lt;/b&gt; (the maximum number                                  of items to appear on the webpage - replace 'X'                                  with a number)&lt;br /&gt;                        &lt;b&gt;~~~SortByPubDate~~~&lt;/b&gt;(the items will be sorted                                  by their PubDate, before they are displayed -                                  newest first)&lt;br /&gt;                        &lt;b&gt;~~~NoFutureItems~~~&lt;/b&gt;(items with PubDates                                  that are in the future will not be displayed until                                  that date/time)&lt;br /&gt;               &lt;br /&gt;                        &lt;b&gt;~~~BeginItemsRecord~~~&lt;/b&gt; (repeat everything                                  between this and the end marker, for each item)&lt;br /&gt;                        &lt;b&gt;~~~EndItemsRecord~~~&lt;/b&gt; (repeat everything                                  between this and the start marker, for each item)                         &lt;br /&gt;                        &lt;b&gt;~~~BeginAlternateItemsRecord~~~ &lt;/b&gt;(separates                                  the ItemsRecord into alternating halves) &lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                        &lt;b&gt;~~~ItemTitle~~~&lt;/b&gt; (the item's title)&lt;br /&gt;                        &lt;b&gt;~~~ItemDescription~~~&lt;/b&gt; (the item's description)&lt;br /&gt;                        &lt;b&gt;~~~ItemLink~~~&lt;/b&gt; (the item's link)&lt;br /&gt;                        &lt;b&gt;~~~ItemPubDate~~~ &lt;/b&gt;(the item's pub date/time                                  in RSS format)&lt;br /&gt;                        &lt;b&gt;~~~ItemPubLongDate~~~&lt;/b&gt; (the items's date                                  in your Windows long date format)&lt;br /&gt;                        &lt;b&gt;~~~ItemPubShortDate~~~ &lt;/b&gt;(the item's date                                  in your Windows short date format)&lt;br /&gt;                        &lt;b&gt;~~~ItemPubLongTime~~~&lt;/b&gt; (the item's time                                  in your Windows long time format)&lt;br /&gt;                        &lt;b&gt;~~~ItemPubShortTime~~~ &lt;/b&gt;(the item's time                                  in your Windows short time format)&lt;br /&gt;                        &lt;b&gt;~~~ItemEnclosureUrl~~~&lt;/b&gt; (the item's enclosure                                  URL)&lt;br /&gt;                        &lt;b&gt;~~~ItemGuid~~~&lt;/b&gt;(the item's GUID field value)&lt;br /&gt;               &lt;br /&gt;                        When the rss2html.php script runs, it will substitute                                  information from the RSS feed into the location                                  wherever a variable is found. For example, every                                  time ~~~FeedTitle~~~ is found in the template's                                  text, the Title from the RSS feed will be substituted.&lt;/p&gt;&lt;br /&gt;&lt;b&gt;Running rss2html.php                                  from FeedForAll's public server &lt;/b&gt;                               &lt;p&gt;If your webserver doesn't support PHP, then you                                  can run the rss2html.php script on FeedForAll's                                  public server instead. All you need to do is setup                                  a link on your website to access the script and                                  resulting webpage. &lt;/p&gt;                               &lt;p&gt; &lt;/p&gt;                               &lt;p&gt;&lt;b&gt;Syntax: &lt;/b&gt;&lt;/p&gt;                               &lt;p&gt;http://scripts.rss2html.com/public/rss2html.php?XMLFILE=&lt;your-rss-feed&gt;&amp;TEMPLATE=&lt;your-template&gt;&amp;amp;MAXITEMS=&lt;maxitems&gt;&lt;/maxitems&gt;&lt;/your-template&gt;&lt;/your-rss-feed&gt;&lt;/p&gt;                               &lt;p&gt; &lt;/p&gt;                               &lt;p&gt;The above URL should all be on one line, with                                  no spaces. &lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Replace '&lt;your-rss-feed&gt;' with the full                                  URL to your RSS feed (ie. http://www.mydomain.com/myfeed.xml)&lt;/your-rss-feed&gt;&lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Replace '&lt;your-template&gt;' with the full                                  URL to the webpage template you want to use (ie.                                  http://mydomain.com/mytemplate.htm)&lt;/your-template&gt;&lt;/p&gt;                               &lt;p&gt; &lt;/p&gt;                               &lt;p&gt;Replace '&lt;max-items&gt;' with the maximium                                  number of items from your RS feed you want included                                  on the webpage. The MAXITEMS variable is optional.                                  If it is not included, all the RSS feed items                                  will be included.&lt;/max-items&gt;&lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Sample:&lt;a href="http://feedforall.com/rss2html.php?XMLFILE=http://www.rss-specifications.com/blog-feed.xml&amp;TEMPLATE=http://www.rss-specifications.com/template.htm&amp;amp;MAXITEMS=10" target="_blank"&gt;&lt;br /&gt;http://feedforall.com/rss2html.php?XMLFILE=http://www.rss-specifications.com/blog-feed.xml&amp;TEMPLATE=http://www.rss-specifications.com/template.htm&amp;amp;MAXITEMS=10 &lt;/a&gt;&lt;br /&gt;                   &lt;br /&gt;                        &lt;/p&gt;                               &lt;p&gt;&lt;b&gt;&lt;a name="own"&gt;&lt;/a&gt;Running rss2html.php from                                  your own webserver &lt;/b&gt;&lt;br /&gt;                          Probably the best way to use rss2html.php is to                                  upload it to your own webserver. This gives you                                  two ways to access the script. First, you can                                  setup a link on your webpage to access the script                                  and resulting webpage. &lt;/p&gt;                               &lt;p&gt; &lt;/p&gt;                               &lt;p&gt;http://&lt;your-domain&gt;/rss2html.php?XMLFILE=&lt;your-rss-feed&gt;&amp;TEMPLATE=&lt;your-template&gt;&amp;amp;MAXITEMS=&lt;maxitems&gt; &lt;/maxitems&gt;&lt;/your-template&gt;&lt;/your-rss-feed&gt;&lt;/your-domain&gt;&lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Replace '&lt;your-domain&gt;' with the domain                                  of your website&lt;/your-domain&gt;&lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Replace '&lt;your-rss-feed&gt;' with the full                                  URL to your RSS feed (i.e. http://www.mydomain.com/myfeed.xml)&lt;/your-rss-feed&gt;&lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Replace '&lt;your-template&gt;' with the full                                  URL to the webpage template you want to use (i.e.                                  http://www.mydomain.com/mytemplate.htm)&lt;/your-template&gt;&lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Replace '&lt;max-items&gt;' with the maximium                                  number of items from your RS feed you want included                                  on the webpage. The MAXITEMS variable is optional.                                  If it is not included, all the RSS feed items                                  will be included.&lt;/max-items&gt;&lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          &lt;b&gt;Sample:&lt;/b&gt;&lt;a href="http://feedforall.com/rss2html.php?XMLFILE=blog-feed.xml&amp;TEMPLATE=samplefeedtemplate.htm&amp;amp;MAXITEMS=10" target="_blank"&gt;&lt;br /&gt;http://feedforall.com/rss2html.php?XMLFILE=blog-feed.xml&amp;TEMPLATE=samplefeedtemplate.htm&amp;amp;MAXITEMS=10&lt;/a&gt;&lt;br /&gt;                   &lt;br /&gt;                   &lt;br /&gt;                          The second option is to edit the settings inside                                  of the rss2html.php script itself, and then just                                  access the script as if it were a regular webpage.                           &lt;br /&gt;                   &lt;br /&gt;                          With a text editor open up the rss2html.php file.                                  Look for the line near the beginning that looks                                  like this: &lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          $XMLfilename = "sample.xml"; &lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Replace sample.xml with either the local path                                  or full URL to your RSS feed file.&lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          Next, find the line that looks like this: &lt;/p&gt;                               &lt;p&gt;&lt;br /&gt;                          $TEMPLATEfilename = "BasicWebpage.htm";&lt;br /&gt;                   &lt;br /&gt;                          Replace BasicWebpage.htm with either the local                                  path or full URL to your template file.&lt;br /&gt;                   &lt;br /&gt;                          Finally, if you want to specify the maximum number                                  of items to include from your feed, find the line                                  that looks like this:&lt;br /&gt;                   &lt;br /&gt;                          $FeedMaxItems = 10000;&lt;br /&gt;                   &lt;br /&gt;                          Replace 10000 with the maximum number of items                                  you want.&lt;br /&gt;                   &lt;br /&gt;                          Save the file with a new name (what you want to                                  call it on your website), but make sure to keep                                  the .php extension.&lt;br /&gt;                   &lt;br /&gt;                          For example, if you named it 'myfeed.php', you                                  can now access it from your browser by typing:                                  http://&lt;your-domain&gt;/myfeed.php&lt;br /&gt;                   &lt;br /&gt;                          &lt;b&gt;Sample:&lt;/b&gt;&lt;br /&gt;                          &lt;a href="http://www.feedforall.com/blog.php" target="_blank"&gt;http://www.feedforall.com/blog.php                                  &lt;/a&gt;&lt;/your-domain&gt;&lt;/p&gt;                               &lt;p&gt;&lt;b&gt;&lt;a name="samples"&gt;&lt;/a&gt;Examples of the RSS to                                  HTML PHP script in action: &lt;/b&gt; &lt;/p&gt;                               &lt;p&gt;&lt;a href="http://www.feedforall.com/blog.htm" target="_blank"&gt;http://www.feedforall.com/blog.htm&lt;/a&gt;                                  (FeedForAll's main RSS feed, using the rss2html.php                                  script) &lt;/p&gt;                               &lt;p&gt;&lt;a href="http://www.feedforall.com/public/layouts.htm" target="_blank"&gt;http://www.feedforall.com/public/layouts.htm&lt;/a&gt;                                  (lots of sample pages) &lt;/p&gt;                               &lt;p&gt;&lt;a href="http://www.small-business-software.net/" target="_blank"&gt;http://www.small-business-software.net&lt;/a&gt;                                  (the main page is actually the rss2html.php script                                  being run) &lt;/p&gt;                               &lt;p&gt;&lt;a href="http://www.create-rss.com/" target="_blank"&gt;http://www.create-rss.com                                  &lt;/a&gt;(the main page is actually the rss2html.php                                  script being run) &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114550740623919352?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114550740623919352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114550740623919352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114550740623919352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114550740623919352'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/free-rss-to-html-php-script.html' title='free RSS to HTML PHP script'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114543257437379152</id><published>2006-04-19T00:38:00.000-07:00</published><updated>2006-05-29T22:51:03.966-07:00</updated><title type='text'>RDP Server for linux</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/screenshot.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/screenshot.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;While looking through the various open source projects on sourceforge.net, I found a very interesting application: an RDP server for linux. it's called XRDP, and it is available &lt;a href="http://xrdp.sourceforge.net"&gt;Here&lt;/a&gt;. Why do you need this? It will allow you to connect to a linux box using the RDP client built into windows.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How it works&lt;br /&gt;&lt;/strong&gt;&lt;p&gt;Xrdp is the main server accepting connections from RDP clients. Xrdp contains the RDP, security, MCS, ISO, and TCP layers, a simple window manager and a few controls. Its a multi threaded single process server. It is in this process were the central management of the sessions are maintained. Central management includes shadowing a session and administrating pop ups to users. xrdp is control by the configuration file xrdp.ini.&lt;/p&gt;&lt;p&gt;RDP has 3 security levels between the RDP server and RDP client. Low, medium and high. Low is 40 bit, data from the client to server is encrypted, Medium is 40 bit encryption both ways and High is 128 bit encryption both ways. xrdp currently only supports low encryption. RSA key exchange is used with both client and server randoms to establish the RC4 keys before the client connect.&lt;/p&gt;&lt;p&gt;Modules are loaded at runtime to provide the real functionality. Many different modules can be created to present one of many different desktops to the user. The modules are loadable to conserve memory and support both GPL and non GPL modules.&lt;/p&gt;&lt;p&gt;Multi threaded to provide optimal user performance. One client can't slow them all down. One multi threaded process is also required for session shadowing with any module. The module doesn't have to consider shadowing, the xrdp server does it. For example, you could shadow a VNC, RDP or a custom module session all from the same shadowing tool.&lt;/p&gt;&lt;p&gt;Build in window manager for sending pop ups to any user running any module. Also can be user to provide connection errors or prompts.&lt;/p&gt;&lt;p&gt;Libvnc, a VNC module for xrdp. Libvnc provides a connection to VNC servers. Its a simple client only supporting a few VNC encodings(raw, cursor, copyrect). Emphasis on being small and fast. Normally, the xrdp server and the Xvnc server are the same machine so bitmap compression encodings would only slow down the session.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;Librdp, an RDP module for xrdp. Librdp provides a connection to RDP servers. It only supports RDP4 connections currently.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Sesman, the session manager. Sesman is xrdp's session manager. xrdp connect to sesman to verify the user name / password, and also starts the user session if credentials are ok. This is a multi process / Linux only session manager. Sessions can be started or viewed from the command line.&lt;/p&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Screenshots&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/screenshot_fedora.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/screenshot_fedora.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114543257437379152?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114543257437379152/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114543257437379152' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114543257437379152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114543257437379152'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/rdp-server-for-linux.html' title='RDP Server for linux'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114538029117677708</id><published>2006-04-18T10:11:00.000-07:00</published><updated>2006-06-14T16:58:28.453-07:00</updated><title type='text'>migrating from Microsoft access to mysql</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Why use mysql instead of access?&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Cost&lt;/strong&gt;. MySQL is free. Access is not. Mysql can also run on a variety of hardware and operating systems, which does not limit you to proprietary software.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Multiple-user access.&lt;/strong&gt;&lt;br /&gt;MySQL can handle many simultaneous users. It was designed from the ground up to run in a shared environment that is capable of taking on a large numbers of clients.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Management of large databases&lt;/strong&gt;. MySQL can manage gigabytes of data, and more. This is possible in access, but not recommended.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Security&lt;/strong&gt;. When Access tables are stored locally, anyone can run Access, and see your tables. It's possible to assign a database a password, but many people forget to do this. When your tables are stored in MySQL, the MySQL server manages security. Anyonetrying to access your data must know the proper user&lt;br /&gt;name and password.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Centralized backup location&lt;/strong&gt;. If individual Access users each store their data locally, backups can be more complicated: 200 users means 200 table backups. While some sites address this problem through the use of network backups, others deal with it by making backups the responsibility of individual machine owners--which usually means no backups at all. Mysql allows you to have one centralized location that can be backed up on a regular basis by a system administrator or DBA.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Manually transferring your data&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;One way to transfer your data is export all the data from each table (using the file-&gt;export command) to a comma delimited text file (CSV). It can then be imported back into mysql using the following commands (from the mysql console client):&lt;br /&gt;&lt;br /&gt;mysql&gt; use mydatabase;&lt;br /&gt;mysql&gt; LOAD DATA LOCAL INFILE 'my_access_table.txt'&lt;br /&gt;-&gt; INTO TABLE mytable&lt;br /&gt;-&gt; FIELDS TERMINATED BY ',' ENCLOSED BY '"'&lt;br /&gt;-&gt; LINES TERMINATED BY '\r\n';&lt;br /&gt;&lt;br /&gt;you could also use mysqlimport&lt;br /&gt;&lt;br /&gt;mysqlimport --local --fields-terminated-by=,&lt;br /&gt;--fields-enclosed-by='"'&lt;br /&gt;--lines-terminated-by='\r\n'&lt;br /&gt;mydatabase my_access_table.txt&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;using a program&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The following are program you can use to transfer the tables for you:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://www.dbtools.com.br/"&gt;DBTools&lt;/a&gt; (free)&lt;/strong&gt; Works with Access97, Access2000. DBTools actually is intended primarily as an application for administering MySQL, but it includes data import capabilities that can be used to read Access databases for transfer to MySQL. (It can also read data from other sources such as Excel spreadsheets, making it particularly useful for transferring to MySQL information that is stored in a variety of formats.) Because DBTools reads Access databases directly, you can use it to migrate Access tables even if you don't have Access installed locally, as long as you have the database files containing the tables to be transferred. DBTools does not require ODBC.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://www.mysqlfront.de/"&gt;MySQLFront&lt;/a&gt; (free 30 day trial)&lt;/strong&gt; MySQLFront is similar in many ways to DBTools. It can read Access97 and Access2000 files directly. If ODBC is installed, MySQLFront can import information into MySQL from ODBC data sources over the network.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114538029117677708?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114538029117677708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114538029117677708' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114538029117677708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114538029117677708'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/migrating-from-microsoft-access-to.html' title='migrating from Microsoft access to mysql'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114487303964466603</id><published>2006-04-14T12:08:00.000-07:00</published><updated>2006-07-23T12:16:25.076-07:00</updated><title type='text'>PHP vs perl</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;if you have a php, programming, or open source related blog, email me your url here: &lt;/strong&gt;&lt;a href="mailto:justin@whenpenguinsattack.com"&gt;&lt;strong&gt;justin@whenpenguinsattack.com&lt;/strong&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PHP and perl are both powerful languages used successfully in a server environment. Here are some brief differences between the two languages:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;PHP is built from the ground-up with database functionality built in, particularly MySQL functionality. Perl is not.&lt;/li&gt;&lt;li&gt;PHP code gets embedded into HTML pages, unlike Perl. This makes it very fast to code web pages and fast to deploy a new site, thus speeding up Web development and lowering overall cost of ownership. An important code management technique for programmers is separating code from data. This allows us to make changes to the code or data without affecting the other. PHP uses the tags to indicate "code inside". In Perl, however, programmers are encouraged to use print statements to generate the HTML. True it is possible to implement templates in Perl (with more difficulty than in PHP) to separate code and HTML, but 90% of sample Perl code on the web doesn't do that.&lt;/li&gt;&lt;li&gt;PHP is secure. Perl scripts tend to have more security holes. This is because PHP has built-in a lot of the internal operations of dealing with web page requests and serving information.&lt;/li&gt;&lt;li&gt;PHP is easy to learn in comparison to Perl. It's easier to learn than C, Python, Java, and most other programming languages used in web development, for that matter. The Perl style of programming is unique, and thus not universally applicable to or from other programming languages. Accessing web form variables in PHP is straightforward, but in Perl requires either detailed knowledge of either HTTP header formats or one of many Perl CGI libraries.&lt;/li&gt;&lt;li&gt;PHP takes less "overhead" than Perl, meaning that PHP scripts will run faster than CGI scripts written in Perl, and you'll be able to handle more simultaneous users on your site. &lt;/li&gt;&lt;li&gt;PHP code tends to be more consistent and modular than Perl.&lt;/li&gt;&lt;/ul&gt;some other differences can also be found here: &lt;a href="http://tnx.nl/php"&gt;http://tnx.nl/php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A few of them are listed below (the rest can be found at the website listed above):&lt;br /&gt;&lt;br /&gt;&lt;h2 id="case"&gt;PHP has separate functions for case insensitive operations&lt;/h2&gt;&lt;p&gt;(This can be argued both ways. Some think it's good to have functions that combine functions, even if that means having dozens of extra names to remember) &lt;/p&gt;&lt;p&gt;In Perl, you use a double lc() (lowercase) or the /i flag where PHP usually provides a case insensitive variant. The case-insensitive versions have very inconsistent naming. &lt;/p&gt;&lt;pre&gt;Perl: $foo cmp $bar                            lc $foo cmp lc $bar&lt;br /&gt;PHP:  strcmp($foo, $bar)                       strcasecmp($foo, $bar)&lt;br /&gt;&lt;br /&gt;Perl: index($foo, $bar)                        index(lc $foo, lc $bar)&lt;br /&gt;PHP:  strpos($foo, $bar)                       stripos($foo, $bar)&lt;br /&gt;&lt;br /&gt;Perl: $foo =~ s/foo/bar/                       $foo =~ s/foo/bar/i&lt;br /&gt;PHP:  $foo = str_replace('foo', 'bar', $foo)   $foo = str_ireplace(...)&lt;br /&gt;PHP:  $foo = ereg_replace('foo', 'bar' ,$foo)  $foo = eregi_replace(...)&lt;br /&gt;&lt;/pre&gt;&lt;h2 id="names"&gt;PHP has inconsistent function naming&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Case insensitive functions have the 'i' or 'case' at different positions in their names.&lt;/li&gt;&lt;li&gt;There is no apparent system in underscore(s) versus no underscore(s): &lt;pre&gt;underscore               no underscore:&lt;br /&gt;&lt;br /&gt;stream_get_line          readline&lt;br /&gt;disk_free_space          diskfreespace&lt;br /&gt;is_object                isset&lt;br /&gt;mcal_day_of_week         jddayofweek&lt;br /&gt;set_error_handler        setlocale&lt;br /&gt;snmp_get_quick_print     snmpget&lt;br /&gt;get_browser              getallheaders&lt;br /&gt;base64_encode            urlencode&lt;br /&gt;image_type_to_mime_type  imagetypes&lt;br /&gt;msql_num_fields          mysql_numfields&lt;br /&gt;php_uname                phpversion&lt;br /&gt;strip_tags               stripslashes&lt;br /&gt;bind_textdomain_codeset  bindtextdomain&lt;br /&gt;cal_to_jd                gregoriantojd&lt;br /&gt;str_rot13                strpos&lt;br /&gt;&lt;/pre&gt;Perl has no core function names with underscores in them. &lt;/li&gt;&lt;li&gt;PHP has unlink, link and rename (system calls), but touch (the system call is utime, not touch).&lt;/li&gt;&lt;li&gt;And they can't decide on word order: &lt;ul&gt;&lt;li&gt;object verb: base64_decode, iptcparse, str_shuffle, var_dump&lt;/li&gt;&lt;li&gt;verb object: create_function, recode_string&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Perl core functions are all "verb object" except the superseded dbm* functions. (Note that sys is a prefix, not an object. And that flock and lstat were named after the system calls. shm* and msg* are library calls) &lt;/p&gt;&lt;/li&gt;&lt;li&gt;"to" or "2"? &lt;p&gt;ascii2ebcdic, bin2hex, deg2rad, ip2long, cal_to_jd (jdto*, *tojd), strtolower, strtotime, &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="scope"&gt;PHP has no lexical scope&lt;/h2&gt;&lt;p&gt;Perl has lexical scope and dynamic scope. PHP doesn't have these. &lt;/p&gt;&lt;p&gt;For an explanation of why lexical scope is important, see &lt;a href="http://perl.plover.com/FAQs/Namespaces.html"&gt;Coping with Scoping&lt;/a&gt;. &lt;/p&gt;&lt;pre&gt;                       PHP  Perl&lt;br /&gt;Superglobal            Yes  Yes [1]&lt;br /&gt;Global                 Yes  Yes&lt;br /&gt;Function local         Yes  Yes [2]&lt;br /&gt;Lexical (block local)  No   Yes&lt;br /&gt;Dynamic                No   Yes&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;[1] Perl has variables that are always in the main:: namespace. These are like PHP's superglobals.&lt;br /&gt;[2] Using a lexical variable in a sub routine's block, you get a function local variable. &lt;/p&gt;&lt;h2 id="bloat"&gt;PHP has too many functions in the main namespace&lt;/h2&gt;&lt;p&gt;(Using the core binaries compiled with all possible extensions in the core distribution, using recent versions in November 2003.) &lt;/p&gt;&lt;pre&gt;Number of PHP  main functions: 3079 [1]&lt;br /&gt;Number of Perl main functions:  206 [2]&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;Median PHP  function name length: 13&lt;br /&gt;Mean   PHP  function name length: 13.67&lt;br /&gt;Median Perl function name length:  6&lt;br /&gt;Mean   Perl function name length:  6.22&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Note that Perl has short syntax equivalents for some functions: &lt;/p&gt;&lt;pre&gt;readpipe('ls -l') ==&gt; `ls -l`&lt;br /&gt;glob('*.txt')     ==&gt; &lt;*.txt&gt;&lt;br /&gt;readline($fh)     ==&gt; &lt;$fh&gt;&lt;br /&gt;quotemeta($foo)   ==&gt; "\Q$foo"&lt;br /&gt;lcfirst($foo)     ==&gt; "\l$foo"  (lc is \L)&lt;br /&gt;ucfirst($foo)     ==&gt; "\u$foo"  (uc is \U)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;[1] Source: &lt;a href="http://www.php.net/quickref.php"&gt;PHP Quick Reference&lt;/a&gt;&lt;br /&gt;[2] Source: &lt;a href="http://tnx.nl/func"&gt;perldoc perlfunc&lt;/a&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114487303964466603?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114487303964466603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114487303964466603' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114487303964466603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114487303964466603'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/php-vs-perl.html' title='PHP vs perl'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114487489839169045</id><published>2006-04-12T13:46:00.000-07:00</published><updated>2006-10-31T13:57:34.066-08:00</updated><title type='text'>10 PHP speed improvement tips for apache</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;A French Translation can be found here: &lt;/strong&gt;&lt;a href="http://www.vecteur-renaissance.com/vhoen/index.php/2006/04/15/27-10-conseils-pour-accelerer-des-scripts-php"&gt;&lt;strong&gt;http://www.vecteur-renaissance.com/vhoen/index.php/2006/04/15/27-10-conseils-pour-accelerer-des-scripts-php&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A PHP script will be served at least 5-10 times slower than a static HTML page by Apache. Try to use more static HTML pages and fewer scripts. &lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Enable the compression of HTML by putting in your php.ini: &lt;p&gt;&lt;code&gt;output_handler = ob_gzhandler&lt;/code&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Install a PHP caching suite. I have personally used zend (commercial), turck mmcache, and ioncube, and they all work very well. &lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Switch from file based sessions to shared memory sessions. Compile PHP with the &lt;i&gt;--with-mm &lt;/i&gt;option and set &lt;i&gt;session.save_handler=mm &lt;/i&gt;in php.ini. This can drastically improve session management performance.&lt;/li&gt;&lt;li&gt;Another caching technique that can be used when you have pages that don't change too often is to cache the HTML output of your PHP pages. (a list of template solutions is posted within one of my previous articles). &lt;/li&gt;&lt;li&gt;Use output buffering (See &lt;a href="http://php.net/ob_start"&gt;ob_start&lt;/a&gt;). This will speed up your PHP code by 5-15% if you frequently print or echo in your code.&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;On Windows, &lt;a href="http://www.fastcgi.com/"&gt;FastCGI&lt;/a&gt; is the highest performance way of running PHP with Apache. &lt;span style="color:maroon;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;In PHP4, objects and arrays should be passed to functions by reference (with &amp;), and everything else by value. In PHP5, objects are already passed by reference. Here is an example:&lt;br /&gt;&lt;pre&gt;function &amp;amp;testfunc(&amp;$test_array)&lt;br /&gt;{&lt;br /&gt;return $test_array;&lt;br /&gt;}&lt;br /&gt;$new_variable =&amp; testfunc($my_testarr);&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Don't use images when text will do. Reduce your image sizes with a software like MacroMedia Fireworks or imagemagick.&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;If possible, Run your database server on a different machine. If all static content is served from another server, then you can turn off KeepAlives&lt;i&gt; &lt;/i&gt;in httpd.conf to speed up client disconnects. &lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114487489839169045?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114487489839169045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114487489839169045' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114487489839169045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114487489839169045'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/10-php-speed-improvement-tips-for.html' title='10 PHP speed improvement tips for apache'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114482725087857958</id><published>2006-04-12T00:29:00.000-07:00</published><updated>2006-04-12T09:38:07.430-07:00</updated><title type='text'>programming in python</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;What is python?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;some interesting facts about python from wikipedia.com:&lt;br /&gt;&lt;br /&gt;Python is a multi-paradigm language. This means that, rather than forcing coders to adopt one particular style of coding, it permits several. Object orientation, structured programming, functional programming, aspect-oriented programming, and more recently, design by contract are all supported. Python is dynamically type-checked and uses garbage collection for memory management. An important feature of Python is dynamic name resolution, which binds method and variable names during program execution.&lt;br /&gt;&lt;br /&gt;While offering choice in coding methodology, Python's designers reject exuberant syntax, such as in Perl, in favor of a sparser, less cluttered one. As with Perl, Python's developers expressly promote a particular "culture" or ideology based on what they want the language to be, favoring language forms they see as "beautiful", "explicit" and "simple". For the most part, Perl and Python users differ in their interpretation of these terms and how they are best implemented (see TIMTOWTDI and PythonPhilosophy).&lt;br /&gt;&lt;br /&gt;Another important goal of the Python developers is making Python fun to use. This is reflected in the origin of the name (after the television series Monty Python's Flying Circus), in the common practice of using Monty Python references in example code, and in an occasionally playful approach to tutorials and reference materials. For example, the metasyntactic variables often used in Python literature are spam and eggs, instead of the traditional foo and bar.&lt;br /&gt;&lt;br /&gt;Python is sometimes referred to as a "scripting language". In practice, it is used as a dynamic programming language for both application development and occasional scripting. Python has been used to develop many large software projects such as the Zope application server and the Mnet and BitTorrent file sharing systems. It is also extensively used by Google. [1]&lt;br /&gt;&lt;br /&gt;Another important goal of the language is ease of extensibility. New built-in modules are easily written in C or C++. Python can also be used as an extension language for existing modules and applications that need a programmable interface.&lt;br /&gt;&lt;br /&gt;Though the design of Python is somewhat hostile to functional programming and the Lisp tradition, there are significant parallels between the philosophy of Python and that of minimalist Lisp-family languages such as Scheme. Many past Lisp programmers have found Python appealing for this reason.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Downloading&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Python can be found &lt;a href="http://www.python.org"&gt;Here&lt;/a&gt; (windows and *nix flavors)&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;A Simple Example&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;operation = raw_input('Operation: ')&lt;br /&gt;First = raw_input('Enter First number: ')&lt;br /&gt;Second = raw_input('Enter Second number: ')&lt;br /&gt;&lt;br /&gt;if operation == "+":&lt;br /&gt;Answer = int(First) + int(Second)&lt;br /&gt;elif operation == "-":&lt;br /&gt;Answer = int(First) - int(Second)&lt;br /&gt;elif operation == "*":&lt;br /&gt;Answer = int(First) * int(Second)&lt;br /&gt;elif operation == "/":&lt;br /&gt;Answer = int(First) / int(Second)&lt;br /&gt;else:&lt;br /&gt;print "An Error has occured"&lt;br /&gt;print 'First Number: %s Second Number: %s Operator: %s' % (Answer, First, Second, operation)&lt;br /&gt;&lt;br /&gt;The first part operation = raw_input('Operation: ') will assign the value someone types in to the variable operation so you can type +,-,* and /.&lt;br /&gt;&lt;br /&gt;In the second part: First = raw_input('First number: ') and Second = raw_input('Second number: ')&lt;br /&gt;&lt;br /&gt;int(First) and int(Second) converts the incoming variables to integers, so their respective operations can be calculated and stored in the Answer variable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114482725087857958?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114482725087857958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114482725087857958' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114482725087857958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114482725087857958'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/programming-in-python_12.html' title='programming in python'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114463582746994886</id><published>2006-04-09T19:21:00.000-07:00</published><updated>2006-09-13T12:15:41.680-07:00</updated><title type='text'>lighttpd vs apache</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;br /&gt;&lt;br /&gt;What is lighttpd?&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;it is designed and optimized for high performance environments. With a small memory footprint compared to other web-servers, effective management of the cpu-load, and advanced feature set (FastCGI, CGI, Auth, Output-Compression, URL-Rewriting and many more) LightTPD is the perfect solution for every server that is suffering load problems. And best of all it's Open Source licensed under the &lt;a href="http://www.lighttpd.net/download/COPYING"&gt;revised BSD license&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It can be downloaded &lt;a href="http://www.lighttpd.net/"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;h1 class="Headline"&gt;&lt;span style="font-size:85%;"&gt;PHP Performance&lt;/span&gt;&lt;/h1&gt;&lt;h2 class="TextNormal"&gt;&lt;span style="font-size:85%;"&gt;Description&lt;/span&gt; &lt;/h2&gt;&lt;h2 class="TextNormal"&gt;&lt;span style="font-size:85%;"&gt;Equipment&lt;/span&gt; &lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Netgear GS108 8-Port Switch&lt;/li&gt;&lt;li&gt;Server:&lt;br /&gt;AMD Athlon XP 2000+ (1666 MHz)&lt;br /&gt;512 Mb RAM&lt;br /&gt;IBM IC35L060AVVA07-0&lt;br /&gt;Intel EtherExpress 1000&lt;br /&gt;Linux 2.6.6 &lt;/li&gt;&lt;li&gt;Test Host:&lt;br /&gt;Via Samual 2 (600MHz)&lt;br /&gt;256 Mb RAM&lt;br /&gt;Via Rhine III&lt;br /&gt;(this is a VIA EPIA CL board) &lt;/li&gt;&lt;/ul&gt;&lt;p class="TextNormal"&gt;The benchmark follows the rules of: &lt;/p&gt;&lt;p class="TextNormal"&gt;&lt;a href="http://turck-mmcache.sourceforge.net/index_old.html"&gt;http://turck-mmcache.sourceforge.net/index_old.html&lt;/a&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;phpmy == phpMyAdmin 2.5.7-pl1&lt;/li&gt;&lt;li&gt;php 4.3.6 with turckmm 2.4.3&lt;/li&gt;&lt;li&gt;lighttpd 1.2.4 with php via FastCGI&lt;/li&gt;&lt;li&gt;apache 1.3.28 with php via apxs&lt;/li&gt;&lt;li&gt;lighttpd: /usr/sbin/ab -dS -n 200 -c 1 &lt;a href="http://192.168.0.2:1025/phpmy/index.php"&gt;http://192.168.0.2:1025/phpmy/index.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt;apache: /usr/sbin/ab -dS -n 200 -c 1 &lt;a href="http://192.168.0.2/phpmy/index.php"&gt;http://192.168.0.2/phpmy/index.php&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 class="TextNormal"&gt;&lt;span style="font-size:100%;"&gt;lighttpd&lt;/span&gt; &lt;/h3&gt;&lt;pre&gt;Concurrency Level:      1&lt;br /&gt;Time taken for tests:   2.209 seconds&lt;br /&gt;Complete requests:      200&lt;br /&gt;Failed requests:        0&lt;br /&gt;Broken pipe errors:     0&lt;br /&gt;Total transferred:      503000 bytes&lt;br /&gt;HTML transferred:       481400 bytes&lt;br /&gt;Requests per second:    90.54 [#/sec] (mean)&lt;br /&gt;Time per request:       11.04 [ms] (mean)&lt;br /&gt;Time per request:       11.04 [ms] (mean, across all concurrent&lt;br /&gt;requests)&lt;br /&gt;Transfer rate:          227.70 [Kbytes/sec] received&lt;br /&gt;&lt;/pre&gt;&lt;h3 class="TextNormal"&gt;&lt;span style="font-size:100%;"&gt;Apache&lt;/span&gt; &lt;/h3&gt;&lt;pre&gt;Concurrency Level:      1&lt;br /&gt;Time taken for tests:   2.789 seconds&lt;br /&gt;Complete requests:      200&lt;br /&gt;Failed requests:        0&lt;br /&gt;Broken pipe errors:     0&lt;br /&gt;Total transferred:      518600 bytes&lt;br /&gt;HTML transferred:       480400 bytes&lt;br /&gt;Requests per second:    71.71 [#/sec] (mean)&lt;br /&gt;Time per request:       13.95 [ms] (mean)&lt;br /&gt;Time per request:       13.95 [ms] (mean, across all concurrent&lt;br /&gt;requests)&lt;br /&gt;Transfer rate:          185.94 [Kbytes/sec] received&lt;br /&gt;&lt;/pre&gt;&lt;p class="TextNormal"&gt;Doing the test via the loopback-interface on the Server-Host doesn't change the numbers dramaticly (+4-5 req/s) &lt;/p&gt;&lt;h2 class="TextNormal"&gt;&lt;span style="font-size:100%;"&gt;Conclusion&lt;/span&gt; &lt;/h2&gt;&lt;p class="TextNormal"&gt;lighttpd + fastcgi is more than 25% faster than apache + mod_php4. &lt;/p&gt;&lt;p class="TextNormal"&gt;For static files we already know that lighttpd is 4-6 times faster. &lt;/p&gt;&lt;a name="4"&gt;&lt;/a&gt;&lt;h1 class="Headline"&gt;&lt;span style="font-size:100%;"&gt;CPU-Utilization&lt;/span&gt;&lt;/h1&gt;&lt;h2 class="TextNormal"&gt;&lt;span style="font-size:85%;"&gt;Description&lt;/span&gt; &lt;/h2&gt;&lt;p class="TextNormal"&gt;The purpose of the benchmark run was find out which opensource webserver leaves the system enough power to do additional work like handling php request and the like. It allows to estimate how the server would perform in a gigabit network. &lt;/p&gt;&lt;h2 class="TextNormal"&gt;&lt;span style="font-size:85%;"&gt;Equipment&lt;/span&gt; &lt;/h2&gt;&lt;p class="TextNormal"&gt;The network was equipped with really cheap 100Mbit components like &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Netgear DS108 8-port Hub&lt;/li&gt;&lt;li&gt;Server:&lt;br /&gt;AMD Athlon 1666 MHz&lt;br /&gt;512 Mb RAM&lt;br /&gt;IBM IC35L060AVVA07-0&lt;br /&gt;SiS900 &lt;/li&gt;&lt;li&gt;Client:&lt;br /&gt;AMD Duron 1300 MHz&lt;br /&gt;256 Mb RAM&lt;br /&gt;Maxtor 33073H3&lt;br /&gt;SiS900 &lt;/li&gt;&lt;/ul&gt;&lt;p class="TextNormal"&gt;The benchmark consisted of 8 runs of apache-bench from the client against the server. &lt;i&gt;index.html&lt;/i&gt; is about 4kbyte large, &lt;i&gt;dummy.out&lt;/i&gt; has a size of 100.000 bytes. Each run is about 10s long for 4k and 60s for 100k. &lt;/p&gt;&lt;pre&gt;/usr/sbin/ab    -n 10000 -c  100 http://192.168.2.10:1030/index.html&lt;br /&gt;/usr/sbin/ab -k -n 10000 -c  100 http://192.168.2.10:1030/index.html&lt;br /&gt;/usr/sbin/ab    -n 10000 -c 1000 http://192.168.2.10:1030/index.html&lt;br /&gt;/usr/sbin/ab -k -n 10000 -c 1000 http://192.168.2.10:1030/index.html&lt;br /&gt;/usr/sbin/ab    -n  5000 -c  100 http://192.168.2.10:1030/dummy.out&lt;br /&gt;/usr/sbin/ab -k -n  5000 -c  100 http://192.168.2.10:1030/dummy.out&lt;br /&gt;/usr/sbin/ab    -n  5000 -c 1000 http://192.168.2.10:1030/dummy.out&lt;br /&gt;/usr/sbin/ab -k -n  5000 -c 1000 http://192.168.2.10:1030/dummy.out&lt;br /&gt;&lt;/pre&gt;&lt;p class="TextNormal"&gt;Each server was started within 'time' to get the user- and sys-time for the statistics. &lt;/p&gt;&lt;pre&gt;time ./lighttpd -D -f ./lighttpd.conf&lt;br /&gt;time ./mathopd -n -f ./mathopd.conf&lt;br /&gt;time ./thttpd -p 1027 -d /home/weigon/wwwroot/servers&lt;/pre&gt;&lt;pre&gt;/grisu.home.kneschke.de/pages/ -l /dev/null -D&lt;br /&gt;time ./src/boa -d -f boa.conf -c ./&lt;br /&gt;&lt;/pre&gt;&lt;h2 class="TextNormal"&gt;&lt;span style="font-size:100%;"&gt;Conclusion&lt;/span&gt; &lt;/h2&gt;&lt;p class="TextNormal"&gt;&lt;b&gt;boa&lt;/b&gt; performs fine but has a lot of work to do in user-mode when handling 1000 parallel connections. The network saturation for small files can be improved for keep-alive mode. &lt;/p&gt;&lt;p class="TextNormal"&gt;&lt;b&gt;thttpd&lt;/b&gt; can't saturate the 100Mbit network because is still lacking keep-alive support. &lt;/p&gt;&lt;p class="TextNormal"&gt;&lt;b&gt;lighttpd&lt;/b&gt; perfoms fine in all sections. &lt;b&gt;apache&lt;/b&gt; uses far to much system resources but is stable. &lt;b&gt;monkey&lt;/b&gt; failed in all tests. &lt;/p&gt;&lt;p class="TextNormal"&gt;&lt;b&gt;mathopd&lt;/b&gt; was tested the wrong way and was removed from the benchmark for now. &lt;/p&gt;&lt;h2 class="TextNormal"&gt;&lt;span style="font-size:100%;"&gt;Results&lt;/span&gt; &lt;/h2&gt;&lt;h3 class="TextNormal"&gt;&lt;span style="font-size:100%;"&gt;lighttpd 1.0.2&lt;/span&gt;&lt;br /&gt;&lt;/h3&gt;&lt;pre&gt;        con   user         sys        [#/sec]     [Kbytes/sec]&lt;br /&gt;4k file&lt;br /&gt;     100  0m0.260s     0m0.880s   1488.54     6889.75&lt;br /&gt;keepalive  100  0m0.260s     0m0.870s   1788.59     8290.74&lt;br /&gt;    1000  0m0.350s     0m1.350s   1278.77     5983.60&lt;br /&gt;keepalive 1000  0m0.410s     0m2.380s   1732.20     8333.10&lt;br /&gt;&lt;br /&gt;100k files&lt;br /&gt;     100  0m0.490s     0m5.730s     81.67     8207.19&lt;br /&gt;keepalive  100  0m0.250s     0m5.620s     85.16     8573.19&lt;br /&gt;    1000  0m0.920s     0m48.470s    77.04     8096.55&lt;br /&gt;keepalive 1000  0m0.830s     0m41.480s    79.54     8552.96&lt;br /&gt;&lt;/pre&gt;&lt;h3 class="TextNormal"&gt;&lt;span style="font-size:100%;"&gt;thttpd 2.23b&lt;/span&gt;&lt;br /&gt;&lt;/h3&gt;&lt;pre&gt;        con   user         sys        [#/sec]     [Kbytes/sec]&lt;br /&gt;4k file&lt;br /&gt;     100  0m0.280s     0m0.960s   1481.26     6814.43&lt;br /&gt;    1000  0m0.310s     0m1.270s   1300.39     6096.46&lt;br /&gt;100k files&lt;br /&gt;     100  0m0.770s     0m5.870s     80.85     8130.32&lt;br /&gt;1000  0m1.360s     0m51.270s    76.92     8085.59&lt;br /&gt;&lt;/pre&gt;&lt;h3 class="TextNormal"&gt;&lt;span style="font-size:100%;"&gt;Boa/0.94.14rc16&lt;/span&gt;&lt;br /&gt;&lt;/h3&gt;&lt;pre&gt;        con   user         sys        [#/sec]     [Kbytes/sec]&lt;br /&gt;4k file&lt;br /&gt;     100  0m0.420s     0m0.940s   1485.00     6778.21&lt;br /&gt;keepalive  100  0m0.300s     0m0.790s   1466.92     6790.01&lt;br /&gt;    1000  0m0.330s     0m1.180s   1305.14     5986.00&lt;br /&gt;keepalive 1000  0m0.900s     0m3.360s   1552.07     7529.29&lt;br /&gt;&lt;br /&gt;100k files&lt;br /&gt;     100  0m1.000s     0m6.330s     81.33     8166.78&lt;br /&gt;keepalive  100  0m0.890s     0m6.240s     85.16     8567.05&lt;br /&gt;    1000  0m10.790s    0m47.700s    78.70     8137.15&lt;br /&gt;keepalive 1000  0m10.630s    0m46.600s    82.28     8512.32 [*]&lt;br /&gt;[*] failed requests&lt;span style="font-size:100%;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold;font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold;font-size:100%;" &gt;Apache 1.3.28&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Georgia,serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;As apache is a (pre-)forking server it is not that easy to measure&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p class="TextNormal"&gt;the time used by all childs in user- and kernel-mode. That's why we use a&lt;br /&gt;&lt;i&gt;guessed&lt;/i&gt; takes from top. This might not be completly correct but should&lt;br /&gt;give you the right impression.&lt;br /&gt;&lt;/p&gt;&lt;p class="TextNormal"&gt;100% CPU Usage means that full 7-8s that the rest runs for the small files&lt;br /&gt;are spent for handling requests. Just check the servers above to see that&lt;br /&gt;same job can be done in 1 second.&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;          con   CPU Usage               [#/sec]     [Kbytes/sec]&lt;br /&gt;4k file&lt;br /&gt;     100       100%               1482.80     6847.20&lt;br /&gt;keepalive  100        80%               1466.92     6790.01&lt;br /&gt;    1000       100%               1318.74     6094.71&lt;br /&gt;keepalive 1000        90%               1887.50     8797.84&lt;br /&gt;&lt;br /&gt;100k files&lt;br /&gt;     100        30%                 81.80     8227.11&lt;br /&gt;keepalive  100        30%                 86.71     8741.96 [*]&lt;br /&gt;    1000        33%                 81.80     8258.31&lt;br /&gt;keepalive 1000        33%                 90.87     9225.39 [*]&lt;br /&gt;[*] failed requests&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114463582746994886?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114463582746994886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114463582746994886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114463582746994886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114463582746994886'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/lighttpd-vs-apache.html' title='lighttpd vs apache'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114430177047893314</id><published>2006-04-05T22:35:00.000-07:00</published><updated>2006-05-02T00:35:09.713-07:00</updated><title type='text'>How to install postgres 8 on Mac OS X</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/images.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/images.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;step 1&lt;/span&gt;: install the fink project, available &lt;a href="http://fink.sourceforge.net/"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;from the fink website: "The Fink project wants to bring the full world of Unix &lt;a href="http://www.opensource.org/"&gt;Open Source&lt;/a&gt; software to &lt;a href="http://www.opensource.apple.com/"&gt;Darwin&lt;/a&gt; and &lt;a href="http://www.apple.com/macosx/"&gt;Mac OS X&lt;/a&gt;. We modify Unix software so that it compiles and runs on Mac OS X ("port" it) and make it available for download as a coherent distribution. Fink uses &lt;a href="http://www.debian.org/"&gt;Debian&lt;/a&gt; tools like dpkg and apt-get to provide powerful binary package management. You can choose whether you want to download precompiled binary packages or build everything from source"&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 2&lt;/span&gt;: (install readline) (within a terminal) sudo /sw/bin/fink install readline&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 3&lt;/span&gt;: give yourself root access with sudo and download the latest version of postgres with curl&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;note&lt;/span&gt;: this can be extracted into any directory, I just chose to use /usr/local/postgres_src&lt;br /&gt;&lt;br /&gt;mkdir /usr/local/postgres_src&lt;br /&gt;cd /usr/local/postgres_src&lt;br /&gt;sudo sh&lt;br /&gt;curl -O ftp://ftp.us.postgresql.org/pub/PostgreSQL/source/v8.1.3/postgresql-8.1.3.tar.gz&lt;br /&gt;tar -xzvf postgresql-8.1.3.tar.gz&lt;br /&gt;cd postgresql-8.1.3&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 4: &lt;/span&gt;make and configure postgres 8&lt;br /&gt;&lt;br /&gt;(within the postgres-8.1.3 directory)&lt;br /&gt;./configure --with-includes=/sw/include/ --with-libraries=/sw/lib&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 5:&lt;/span&gt; add a new user that will have permissions on the database.&lt;br /&gt;&lt;br /&gt;This can be done by going into System-&gt;Preferences-&gt;Accounts and "New User". Call this new user "postgres".&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 6&lt;/span&gt;: Create postgres data directories and change the ownership to the postgre user that was created in step 5.&lt;br /&gt;&lt;br /&gt;mkdir /usr/local/pgsql/data&lt;br /&gt;chown postgres /usr/local/pgsql/data&lt;br /&gt;&lt;br /&gt;Login to the postgres user account&lt;br /&gt;&lt;br /&gt;su -l postgres&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 7: &lt;/span&gt;initialize the database&lt;br /&gt;&lt;br /&gt;/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 8&lt;/span&gt;: start the server&lt;br /&gt;&lt;br /&gt;/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 9&lt;/span&gt;: start creating tables&lt;br /&gt;&lt;br /&gt;createdb test&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Step 10&lt;/span&gt;: start executing commands on the newly created table. Postgres is now installed.&lt;br /&gt;&lt;br /&gt;psql test (psql is a command-line utility for executing sql commands)&lt;br /&gt;&lt;br /&gt;create table newtable (name varchar, email varchar);&lt;br /&gt;&lt;br /&gt;insert into newtable (name,address) values ('John','john@email.com');&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114430177047893314?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114430177047893314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114430177047893314' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114430177047893314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114430177047893314'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/how-to-install-postgres-8-on-mac-os-x.html' title='How to install postgres 8 on Mac OS X'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114403322967262520</id><published>2006-04-02T19:59:00.000-07:00</published><updated>2006-05-11T19:04:14.536-07:00</updated><title type='text'>How to cache smarty templates</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/smarty-logo-orange.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/6545/2077/320/smarty-logo-orange.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;By Justin Silverton&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Following is taken from the smarty manual:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What is caching?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Caching is used to speed up a call to display() or fetch() by saving its output to a file. If a cached version of the call is available, that is displayed instead of regenerating the output. Caching can speed things up tremendously, especially templates with longer computation times. Since the output of display() or fetch() is cached, one cache file could conceivably be made up of several template files, config files, etc.&lt;br /&gt;&lt;br /&gt;Since templates are dynamic, it is important to be careful what you are caching and for how long. For instance, if you are displaying the front page of your website that does not change its content very often, it might work well to cache this page for an hour or more. On the other hand, if you are displaying a page with a weather map containing new information by the minute, it would not make sense to cache this page.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Setting it up&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The first thing to do is enable caching by setting $caching = 1 (or 2).&lt;br /&gt;&lt;br /&gt;Example: setting up caching&lt;br /&gt;&lt;br /&gt;caching = true;&lt;br /&gt;&lt;br /&gt;$smarty-&gt;display('index.tpl');&lt;br /&gt;?&gt;&lt;br /&gt;&lt;br /&gt;With caching enabled, the function call to display('index.tpl') will render the template as usual, but also saves a copy of its output to a file (a cached copy) in the $cache_dir. Upon the next call to display('index.tpl'), the cached copy will be used instead of rendering the template again.&lt;br /&gt;&lt;br /&gt;Technical Note: The files in the $cache_dir are named similar to the template name. Although they end in the ".php" extention, they are not really executable php scripts. Do not edit these files!&lt;br /&gt;&lt;br /&gt;Each cached page has a limited lifetime determined by $cache_lifetime. The default value is 3600 seconds, or 1 hour. After that time expires, the cache is regenerated. It is possible to give individual caches their own expiration time by setting $caching = 2. See $cache_lifetime for more details.&lt;br /&gt;&lt;br /&gt;example: setting up cache lifetime&lt;br /&gt;&lt;br /&gt;caching = 2; // lifetime is per cache&lt;br /&gt;&lt;br /&gt;// set the cache_lifetime for index.tpl to 5 minutes&lt;br /&gt;$smarty-&gt;cache_lifetime = 300;&lt;br /&gt;$smarty-&gt;display('index.tpl');&lt;br /&gt;&lt;br /&gt;// set the cache_lifetime for home.tpl to 1 hour&lt;br /&gt;$smarty-&gt;cache_lifetime = 3600;&lt;br /&gt;$smarty-&gt;display('home.tpl');&lt;br /&gt;&lt;br /&gt;// NOTE: the following $cache_lifetime setting will not work when $caching = 2.&lt;br /&gt;// The cache lifetime for home.tpl has already been set&lt;br /&gt;// to 1 hour, and will no longer respect the value of $cache_lifetime.&lt;br /&gt;// The home.tpl cache will still expire after 1 hour.&lt;br /&gt;$smarty-&gt;cache_lifetime = 30; // 30 seconds&lt;br /&gt;$smarty-&gt;display('home.tpl');&lt;br /&gt;?&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Caching Tips&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Smarty caching can improve performance tremendously, but it doesn't always work the way that you think it should. In the following situation (which I have seen recently):&lt;br /&gt;&lt;br /&gt;example:  within (main.tpl) (this is a file named main.tpl)&lt;br /&gt;       {if some action}   &lt;br /&gt;        {include file="menu1.tpl"}&lt;br /&gt;       {elseif some other action}&lt;br /&gt;        {include file="menu2.tpl"}&lt;br /&gt;       {/if}&lt;br /&gt;&lt;br /&gt;If the main template file (main.tpl) is cached, the includes template files will not get called properly.  My solution is to separate the main file into cached and non-cached parts:&lt;br /&gt;&lt;br /&gt;(within the PHP file that calls your smarty templates)&lt;br /&gt;&lt;br /&gt;//do this on any separate template file that you want cached&lt;br /&gt;$smarty-&gt;caching = true; &lt;br /&gt;//the fetch command puts the output of a template file into a variable rather than //the screen&lt;br /&gt;$menu1 = $smarty-&gt;fetch('menu1.tpl'); &lt;br /&gt;$smarty-&gt;assign('menu1',$menu1); &lt;br /&gt;$menu2 = $smarty-&gt;fetch('menu2.tpl'); &lt;br /&gt;$smarty-&gt;assign('menu2',$menu2); &lt;br /&gt;&lt;br /&gt;//set the main caching file to false&lt;br /&gt;$smarty-&gt;caching = false; &lt;br /&gt;$smarty-&gt;display('main.tpl');&lt;br /&gt;&lt;br /&gt;(within the new main.tpl)&lt;br /&gt;       {if some action}   &lt;br /&gt;        {$menu1}&lt;br /&gt;       {elseif some other action}&lt;br /&gt;        {$menu2}&lt;br /&gt;       {/if}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114403322967262520?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114403322967262520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114403322967262520' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114403322967262520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114403322967262520'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/04/how-to-cache-smarty-templates.html' title='How to cache smarty templates'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114379034940747489</id><published>2006-03-30T23:32:00.000-08:00</published><updated>2006-05-11T23:00:18.913-07:00</updated><title type='text'>PHP editor bonanza</title><content type='html'>&lt;span style="font-weight: bold;"&gt;By Justin Silverton&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The following is a list of PHP editors (commercial and freeware)&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;, &lt;/span&gt;&lt;/span&gt;with reviewed links to php-editors.com&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;table align="center" border="0" cellpadding="6" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr class="bold" height="20"&gt; &lt;td&gt;&lt;b&gt;Editor Name&lt;/b&gt;&lt;/td&gt; &lt;td&gt;&lt;b&gt;Version&lt;/b&gt;&lt;/td&gt; &lt;td width="90"&gt;&lt;b&gt;License&lt;/b&gt;&lt;/td&gt; &lt;td width="90"&gt;&lt;b&gt;Platform/OS&lt;/b&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;b&gt;Our Rating&lt;/b&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;b&gt;User Rating&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=1"&gt;PHP Edit&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.2.5 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.55&lt;/b&gt;&lt;br /&gt;(125 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=2"&gt;Dreamweaver&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;8 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;3.98&lt;/b&gt;&lt;br /&gt;(58 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=17"&gt;NuSphere PhpED&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.27&lt;/b&gt;&lt;br /&gt;(73 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=40"&gt;Maguma Workbench&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;2.6 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;Linux&lt;br /&gt;Mac&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.11&lt;/b&gt;&lt;br /&gt;(9 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=92"&gt;emacs&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;21 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Mac&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.07&lt;/b&gt;&lt;br /&gt;(13 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=91"&gt;ActiveState Komodo&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3.5 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Commercial&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.57&lt;/b&gt;&lt;br /&gt;(21 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=98"&gt;PHP Designer 2005&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3.0.6 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.74&lt;/b&gt;&lt;br /&gt;(2329 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=164"&gt;Komodo&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3.1 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;Linux&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.13&lt;/b&gt;&lt;br /&gt;(22 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=234"&gt;TSW WebCoder 2005&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;2005 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Commercial&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;5/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;2&lt;/b&gt;&lt;br /&gt;(4 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=5"&gt;VIM&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;6.1 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.23&lt;/b&gt;&lt;br /&gt;(146 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=6"&gt;DzSoft PHP Editor&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.4 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.54&lt;/b&gt;&lt;br /&gt;(22 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=33"&gt;Davor's PHP Constructor&lt;/a&gt;  &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;1.0 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;3.75&lt;/b&gt;&lt;br /&gt;(4 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=7"&gt;Edit Plus&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;2.11 SR-2 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.67&lt;/b&gt;&lt;br /&gt;(80 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=8"&gt;HTML-Kit&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;292 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.48&lt;/b&gt;&lt;br /&gt;(43 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=10"&gt;PHP Expert Editor&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;2.5 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.39&lt;/b&gt;&lt;br /&gt;(81 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=12"&gt;Anjuta&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;1.0.1 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;3.66&lt;/b&gt;&lt;br /&gt;(6 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=14"&gt;Bluefish&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;0.12 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;3.97&lt;/b&gt;&lt;br /&gt;(34 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=15"&gt;Quanta Plus&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3.2.1 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.59&lt;/b&gt;&lt;br /&gt;(61 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=16"&gt;Zend Studio&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;5 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Mac&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;3.93&lt;/b&gt;&lt;br /&gt;(143 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=21"&gt;Kate&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;2.2 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.11&lt;/b&gt;&lt;br /&gt;(18 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=24"&gt;Maguma Studio Free&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.1.0 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;3.89&lt;/b&gt;&lt;br /&gt;(47 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=100"&gt;PHP Editor by EngInSite&lt;/a&gt;  &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;3&lt;/b&gt;&lt;br /&gt;(4 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=28"&gt;PHP Eclipse&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.06a &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.28&lt;/b&gt;&lt;br /&gt;(70 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=29"&gt;Xored:: WebStudio&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;0.3.4 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;3.92&lt;/b&gt;&lt;br /&gt;(25 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=30"&gt;SciTE&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.53 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.57&lt;/b&gt;&lt;br /&gt;(56 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=31"&gt;VS.Php&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;Beta 3 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Commercial&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.57&lt;/b&gt;&lt;br /&gt;(19 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=41"&gt;Maguma Studio Pro&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.3.X &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4&lt;/b&gt;&lt;br /&gt;(8 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=52"&gt;Macromedia HomeSite&lt;/a&gt;  &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;5.5 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.5&lt;/b&gt;&lt;br /&gt;(14 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=56"&gt;TextPad&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4.7.2 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.51&lt;/b&gt;&lt;br /&gt;(27 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=66"&gt;PHP Edit&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;1.0 Stable &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.44&lt;/b&gt;&lt;br /&gt;(78 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=102"&gt;EngInSite Editor for  PHP&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;2.2 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.31&lt;/b&gt;&lt;br /&gt;(22 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=3"&gt;BBedit&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;7.0 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Mac&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.47&lt;/b&gt;&lt;br /&gt;(17 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=4"&gt;BBedit Lite&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;6.1 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Mac&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.55&lt;/b&gt;&lt;br /&gt;(9 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=11"&gt;Cooledit&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3.17.7 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;3&lt;/b&gt;&lt;br /&gt;(2 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=13"&gt;Nedit&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;5.3 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.57&lt;/b&gt;&lt;br /&gt;(7 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=59"&gt;PSPad&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4.3.0 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.67&lt;/b&gt;&lt;br /&gt;(76 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=18"&gt;PHP Coder&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;3.89&lt;/b&gt;&lt;br /&gt;(64 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=25"&gt;AceHTML Pro&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;5 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4&lt;/b&gt;&lt;br /&gt;(10 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=35"&gt;Top PHP Studio&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;v1.19.6 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.33&lt;/b&gt;&lt;br /&gt;(6 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=34"&gt;jEdit&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;4.1 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Mac&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.62&lt;/b&gt;&lt;br /&gt;(72 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=39"&gt;SubEthaEdit&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.1.5 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Mac&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.5&lt;/b&gt;&lt;br /&gt;(10 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=43"&gt;umdev&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;2004 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Shareware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;2.33&lt;/b&gt;&lt;br /&gt;(3 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=44"&gt;Dev-PHP&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3.0 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.48&lt;/b&gt;&lt;br /&gt;(56 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=45"&gt;Crimson Editor&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3.60 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.70&lt;/b&gt;&lt;br /&gt;(47 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=46"&gt;PHP Processor&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.2 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Shareware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;5&lt;/b&gt;&lt;br /&gt;(1 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=51"&gt;tsWebEditor&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;2 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.61&lt;/b&gt;&lt;br /&gt;(13 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=54"&gt;Svoi.NET - PHP Edit XP&lt;/a&gt;  &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4.0 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.16&lt;/b&gt;&lt;br /&gt;(18 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=61"&gt;ConTEXT&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;0.97.4 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.70&lt;/b&gt;&lt;br /&gt;(24 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=73"&gt;PHP Side (Simple IDE)&lt;/a&gt;  &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;0.4 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.07&lt;/b&gt;&lt;br /&gt;(13 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=74"&gt;HAPedit&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3.1 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.44&lt;/b&gt;&lt;br /&gt;(18 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=76"&gt;EmEditor&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;4.0 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;Shareware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4&lt;/b&gt;&lt;br /&gt;(4 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=94"&gt;Roadsend Studio&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;1.1.1 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;1&lt;/b&gt;&lt;br /&gt;(1 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=82"&gt;TruStudio&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.0.0. &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Mac&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;3.33&lt;/b&gt;&lt;br /&gt;(9 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=111"&gt;Smultron&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;1.0.1 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Mac&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.28&lt;/b&gt;&lt;br /&gt;(7 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=136"&gt;PHP backend generator&lt;/a&gt;  &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;0.9 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Mac&lt;br /&gt;Other&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;1&lt;/b&gt;&lt;br /&gt;(1 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=218"&gt;PHPMaker&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3.2 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Shareware&lt;br /&gt;Commercial&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;5&lt;/b&gt;&lt;br /&gt;(1 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=225"&gt;Pidela&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;0.1 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;Unix&lt;br /&gt;Linux&lt;br /&gt;Mac&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;3/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;1&lt;/b&gt;&lt;br /&gt;(1 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row1" height="20"&gt; &lt;td class="row1" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=9"&gt;Arisesoft Winsyntax&lt;/a&gt; &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;2 &lt;/td&gt; &lt;td class="row1" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;2/5 &lt;/td&gt; &lt;td class="row1" align="center" valign="top"&gt;&lt;b&gt;4.12&lt;/b&gt;&lt;br /&gt;(25 votes)&lt;/td&gt;&lt;/tr&gt; &lt;tr class="row2" height="20"&gt; &lt;td class="row2" align="left" valign="top"&gt;&lt;a href="http://www.php-editors.com/review/?editor=101"&gt;SEG&lt;/a&gt; &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;1.0.1 &lt;/td&gt; &lt;td class="row2" valign="top"&gt;Freeware&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" valign="top"&gt;Windows&lt;br /&gt;&lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;2/5 &lt;/td&gt; &lt;td class="row2" align="center" valign="top"&gt;&lt;b&gt;4.46&lt;/b&gt;&lt;br /&gt;(13 votes)&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114379034940747489?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114379034940747489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114379034940747489' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114379034940747489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114379034940747489'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/php-editor-bonanza.html' title='PHP editor bonanza'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114370723179872189</id><published>2006-03-30T00:26:00.000-08:00</published><updated>2006-03-30T00:47:08.413-08:00</updated><title type='text'>The early days of slashdot</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;I have been a regular reader (and occasional poster) of the popular tech site &lt;a href="http://www.slashdot.org"&gt;http://www.slashdot.org&lt;/a&gt; since 2000. Recently, I searched archive.org for the earliest version of the site I could find.&lt;br /&gt;&lt;br /&gt;Here is a link: &lt;a href="http://web.archive.org/web/19980113191222/http://slashdot.org/"&gt;http://web.archive.org/web/19980113191222/http://slashdot.org/&lt;/a&gt;&lt;br /&gt;it is slashdot.org on January 13th, 1998&lt;br /&gt;&lt;br /&gt;Some interesting archived article summaries taken from the above link:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;IE Takes the Lead?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Contributed by &lt;a href="http://web.archive.org/web/19980113193249/http://slashdot.org/malda/"&gt;CmdrTaco&lt;/a&gt; on Fri Jan 09 at 2:09PM EST From the fun-with-numbers dept&lt;a href="mailto:DaveF@LSWebTour.com"&gt;David Fagan&lt;/a&gt; wrote in to tell us about &lt;a href="http://web.archive.org/web/19980113193249/http://www.news.com/News/Item/0,4,17948,00.html?latest"&gt;this article&lt;/a&gt; where it is reported than recent statistics show that IE4 is out on top in the browser battle with 63% of the traffic at various high traffic sites. I don't put a lot of weight in these stats, but this is a pretty significant number.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Intel Releases 266 Pentium&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Contributed by &lt;a href="http://slashdot.org/malda/"&gt;CmdrTaco&lt;/a&gt; on Fri Jan 09 at 12:29PM EST From the pushing-but-not-hard deptIntel is releasing the 266Mhz version of the possibly immortal Pentium line of CPUs. Supposedly this chip is primarily for the Laptop world. Interesting timing considering how hard Intel is pushing the P2 lines of chips, and the next generation of that line that is due out soon. Thanks to &lt;a href="mailto:DaveF@LSWebTour.com"&gt;David Fagan&lt;/a&gt; for alerting us.&lt;br /&gt;&lt;br /&gt;(a direct link to an article posted by cmdr taco about the current state slashdot):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://web.archive.org/web/19980113194013/slashdot.org/slashdot.cgi?mode=article&amp;artnum=00000425"&gt;http://web.archive.org/web/19980113194013/slashdot.org/slashdot.cgi?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://web.archive.org/web/19980113194013/slashdot.org/slashdot.cgi?mode=article&amp;amp;artnum=00000425"&gt;mode=article&amp;amp;artnum=00000425&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114370723179872189?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114370723179872189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114370723179872189' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114370723179872189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114370723179872189'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/early-days-of-slashdot.html' title='The early days of slashdot'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114352830356687449</id><published>2006-03-27T22:44:00.000-08:00</published><updated>2006-05-05T19:12:46.080-07:00</updated><title type='text'>Flickr.com  - PHP/mysql case study</title><content type='html'>&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Carl Henderson from Flickr.com, a very popular photo blogging service has released a pdf (not sure exactly when this was actually released) detailing the issues they faced with having a high-traffic website.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;original PDF can be downloaded &lt;a href="http://www.niallkennedy.com/blog/uploads/flickr_php.pdf"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;some interesting points taken from this pdf are below.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Classes, libraries, and systems used&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;1) smarty for templating&lt;br /&gt;2) PEAR and XML for Email parsing&lt;br /&gt;3) perl for controlling&lt;br /&gt;4) imagemagick for image processing&lt;br /&gt;5) mysql (4.0/innoDb)&lt;br /&gt;6) java, for node service&lt;br /&gt;7) apache 2 and redhat linux&lt;br /&gt;&lt;br /&gt;8) 60,000 lines of PHP code&lt;br /&gt;9) 60,000 lines of templates&lt;br /&gt;10) 70 custom smarty functions/modifiers&lt;br /&gt;11) 25,000 DB transactions/second at peak&lt;br /&gt;12) 1000 pages per second at peak&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;unicode support&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;1) UTF-8 pages&lt;br /&gt;2) CJKV support&lt;br /&gt;&lt;br /&gt;Tips: don't use HtmlEntities(). Also, Javascript has patchy Unicode Support&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why php was used&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;1) Everything can be stored in the database, including smarty cache&lt;br /&gt;2) a "shared nothing" approach (as long as php sessions were not used)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Mysql usage&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Select's: 44,220,588&lt;br /&gt;Insert's: 1,349,234&lt;br /&gt;update's: 1,755,503&lt;br /&gt;delete's: 318,439&lt;br /&gt;13 select's per Insert, Update, and delete&lt;br /&gt;&lt;br /&gt;Tips: many of the tables that needed to be full-text searched were de-normalized. This does waste space, but because it allowed for little or no joins, it made searching much faster.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114352830356687449?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114352830356687449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114352830356687449' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114352830356687449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114352830356687449'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/flickrcom-phpmysql-case-study.html' title='Flickr.com  - PHP/mysql case study'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114322582643584514</id><published>2006-03-24T10:38:00.000-08:00</published><updated>2006-05-12T03:05:32.100-07:00</updated><title type='text'>protecting your PHP code</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/pobs.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/pobs.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;A client of mine approached me today and was interested in releasing a PHP based product, but didn't want his source code to be viewed, in plaintext, by the people purchasing it (mainly because competitors can could easily just purchase a copy and integrate his source code into their product). So, I researched the different options available to protect source code.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What doesn't work&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The various encoders available do not work. These companies/products should just release these products as accelerators (which can improve speed by up to 10X) and not a secure and reliable way of hiding source code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.phprecovery.com"&gt;http://www.phprecovery.com&lt;/a&gt; is a website that charges money to decode the following types of encoded files (it is just an example site that I found. There are many more just like it):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Zend&lt;/li&gt;&lt;li&gt;Ioncube&lt;/li&gt;&lt;li&gt;SourceGuardian&lt;/li&gt;&lt;li&gt;TurckMM&lt;b&gt;&lt;span style="COLOR: rgb(255,0,0)"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;SourceCop&lt;/li&gt;&lt;li&gt;ScopBin &lt;/li&gt;&lt;li&gt;Zend (Gaspra) &lt;span class="style19"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Ioncube (last) &lt;/li&gt;&lt;li&gt;CodeLock&lt;b&gt;&lt;span style="COLOR: rgb(255,0,0)"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;This site has been tested and it does work. Most people would not bother with the hassle of paying someone to decode your application, but if you offer a more expensive version that includes the full source (and the price is more than it would cost to decode it), then it might just be a better solution.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;What works&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The best solution is code obfuscation. It may not be perfect, and in some instances, you may have to change your code around a little bit, but it will make it very difficult to re-use your source code.&lt;br /&gt;&lt;br /&gt;I prefer a free program called POBS, available&lt;a href="http://pobs.mywalhalla.net/"&gt; Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;How it works:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Replace names&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;POBS replaces user-defined (NOT predefined) functions, constants and variables with a MD5 key of 8 characters. (It doesn't use MD5 keys of 32 bytes, which is standard, since that would increase the size of your sourcecode). 8 bytes seems enough to give each functions or variable its unique name. MD5 is not reversible.&lt;br /&gt;&lt;br /&gt;The first letter of the new functionname is a "F", of a variable a "V" and of a constant a "C"&lt;br /&gt;&lt;br /&gt;The function with name MakeImageHtml is replaced by Fee2c1bdc&lt;br /&gt;The variable $ImgText is replaced by $V1d9d94a6&lt;br /&gt;The constant USERDIR is replaced by C389a367e&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Futher obscuring&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In addition, POBS can be instructed to concatenate lines and remove comments and indents. These are not irreversible since a person can write a program to add indents and returns. But it really makes a mess of your code and therefore furtherly discourages many wouldbe hackers from trying to reverse-engineer your code.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Exclude stuff&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;POBS allows you to indicate which user-defined variables, constants and functions need to be excluded from replacing. In the settings file "pobs-ini.inc" you can add these names to the arrays $UdExVarArray, $UdExcConstArray and $UdExcFuncArray. Do NOT use dollarsigns here.&lt;br /&gt;&lt;br /&gt;In $UdExVarArray you are allowed to use &lt;b&gt;wildcards&lt;/b&gt; in the form of an asterix (*) at the end of each variablename. I.e. params_* will exclude params_type, params_address and params_name. So if you name your variables to a certain convention you can easily and securely exclude them by group. This way you don't have to be afraid you forgot to add it to the array in case you added a new variable to your code.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Process&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;POBS consists of 2 major processes.&lt;br /&gt;&lt;br /&gt;1. POBS first scans all the files with the file-extensions allowed in the sourcedirectory. While scanning, it makes a list of userdefined variables, functions and constants it has located in your sourcecode&lt;br /&gt;&lt;br /&gt;2. POBS now knows which ones it should replace and starts writing new files in the target directory&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114322582643584514?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114322582643584514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114322582643584514' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114322582643584514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114322582643584514'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/protecting-your-php-code.html' title='protecting your PHP code'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114301085082283082</id><published>2006-03-21T22:58:00.000-08:00</published><updated>2006-09-21T22:58:44.233-07:00</updated><title type='text'>The Zend Framework</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/zend.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/zend.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The Zend Framework is a recently released (still in alpha) set of open source tools for php designed for developing Applications and Web Services.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Included Functionality&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Controller and Zend_View&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;These components provide the base for a simple MVC website and are already used on this site and several others. A front controller dispatches requests to page controllers. It is as minimalist as possible and we're working to make it even simpler. The Zend_View component provides encapsulation for view logic. It can use templates written in PHP or can be combined with a third-party template engine.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Db&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Database access is a very light layer on top of PDO. Solutions existing systems not using PDO (such as mysqli or oci8) are presently under development. Included are adapters, a profiler, a tool to assist with building everyday SELECT statements, and simple objects for working with table row data.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Feed&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The links on the sidebars of our home page are generated using Zend_Feed. This component provides a very simple way to consume RSS and Atom data from feeds. It also includes utilities for discovering feed links, importing feeds from different sources, and feeds can even be modified and saved back as valid XML.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_HttpClient&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This component provides a client for the HTTP protocol and does not require any PHP extensions. It drives our web services components. In time, we will develop support for extension-based backends such as cURL.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_InputFilter&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The input filtering component encourages the development of secure websites by providing the basic tools necessary for input filtering and validation.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Json&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Easily convert PHP structures into JSON for use in AJAX-enabled applications.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Log&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Log data to the console, flat files, or a database. Its no-frills, simple, procedural API reduces the hassle of logging to one line and is perfect for cron jobs and error logs.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Mail and Zend_Mime&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Almost every internet application needs to send email. Zend_Mail, assisted by Zend_Mime, creates email messages and sends them. It supports attachements and does all the MIME dirty work.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Pdf&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Portable Document Format (PDF) from Adobe is the de facto standard for cross-platform rich documents. Now, PHP applications can create PDF documents on the fly, without the need to call utilities from the shell, depend on PHP extensions, or pay licensing fees. Zend_PDF can even modify existing PDF documents. Create a sharp customer invoice in Adobe Photoshop, fill in the order from Zend_Pdf, and send it with Zend_Mail.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Search_Lucene&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The Apache Lucene engine is a powerful, feature-rich Java search engine that is flexible about document storage and supports many complex query types. Zend_Search_Lucene is a port of this engine written entirely in PHP 5, allowing PHP-powered websites to leverage powerful search capabilities without the need for web services or Java. Zend_Search_Lucene's file format is fully binary compatible with its Java counterpart.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_Service: Amazon, Flickr, and Yahoo!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Web services are becoming increasingly important to the PHP developer as mashups and composite applications become the standard for next generation web applications. The Zend Framework provides wrappers for service APIs from three major providers to make the as simple to use as possible. We're working on more and engaging API vendors directly to make PHP the premier platform for consuming web services.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Zend_XmlRpc&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;PHP 5's SOAP extension dramatically lowered the bar for communicating with SOAP services from PHP. Zend_XmlRpc brings the same capabilities to XML-RPC, mimmicking the SOAP extension and making these services easier to use than ever from PHP 5.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The Zend Framework looks promising, but I think that in its current state, it is more of a set of classes than an actual framework. Currently, PEAR is a much better choice in terms of community support and component availability. I am glad that Zend is continuing to embrace the open source community and I will be curious to see the future builds of this framework.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;It can be downloaded &lt;a href="http://framework.zend.com/download"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114301085082283082?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114301085082283082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114301085082283082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114301085082283082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114301085082283082'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/zend-framework.html' title='The Zend Framework'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114282588714957162</id><published>2006-03-19T19:35:00.000-08:00</published><updated>2006-04-16T23:53:03.893-07:00</updated><title type='text'>php security mistakes - part 2</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In one of my previous articles, I mentioned the top 5 security mistakes made in PHP. This article is a follow-up, with some more common security mistakes.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;System Calls&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;In PHP, there are different ways to execute system calls. The system(), exec(), and passthru() all allow you to execute operating-system commands from within your scripts.&lt;br /&gt;&lt;br /&gt;Each of these functions, if not checked, can also allow a malicious user to exploit your system and execute commands that could possible access private files and information.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Protecting your system from this attack&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;The input from the user, no matter the context, should never be trusted. PHP provides two functions, escapeshellarg() and escapeshellcmd().&lt;br /&gt;&lt;br /&gt;The escapeshellarg() function is designed to remove or otherwise eliminate any potentially harmful characters received from user input for use as arguments to system commands (in our case, the zip command).&lt;br /&gt;&lt;br /&gt;The syntax for this function is as follows:escapeshellarg($command)&lt;br /&gt;where $command is the input to clean, and the return value is the cleaned string. When executed, this function will add single quotes around the string and escape (add a slash in front of) any single quotes that exist in the string.&lt;br /&gt;&lt;br /&gt;escapeshellcmd() is similar to this function, except it will only escape characters that have a special meaning to the underlying operating system. If user input will be used as part of the argument list for a system call, the escapeshellarg() function is always the better choice.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;File Uploads&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;PHP will create a file with the uploaded content, but will not check whether the filename is valid, or if the type and size are correct&lt;br /&gt;&lt;br /&gt;A user could potentially create his own form specifying the name of some other file that contains sensitive information and submit it, resulting in the processing of that other file.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;use move_uploaded_file() or is_uploaded_file(). However, there are some other problems with user-uploaded files and check the $_FILES super global array to make sure that the user has uploaded the correct file type/size.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Including Files&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;In PHP you can include local or remote files by using include(), include_once(), require() and require_once(). It allows you to have separate files for classes, reused code and so on, increasing the maintainability and readability of your code.&lt;br /&gt;&lt;br /&gt;The concept of including remote files is dangerous in itself, though, because the remote site could be compromised or the network connection could be spoofed. In either scenario, you are injecting unknown and possibly hostile code directly into your script.&lt;br /&gt;&lt;br /&gt;Another issue to think about when including files, is if a file that is included is dependent on user input. This poses a potential securty issue, which can be fixed by verifying and cleaning incoming varialbes.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Don't trust any incoming variables ($_GET,$_POST, or $_COOKIE). These can all be set by a malicious user and possibly compromise the securty of your system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114282588714957162?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114282588714957162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114282588714957162' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114282588714957162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114282588714957162'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/php-security-mistakes-part-2.html' title='php security mistakes - part 2'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114245732792085249</id><published>2006-03-15T13:04:00.000-08:00</published><updated>2006-09-16T01:22:03.826-07:00</updated><title type='text'>php template engine roundup</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;After searching the Internet for a good template engine, I have compiled the following list:&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://smarty.php.net/"&gt;Smarty&lt;/a&gt;&lt;br /&gt;Smarty is a template engine that compiles the templates into PHP scripts, then executes those scripts. Very fast, very flexible.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.phpguru.org/static/template.html"&gt;Heyes Template Class&lt;/a&gt;&lt;br /&gt;A very easy to use, yet powerful and quick template engine that enables you to separate your page layout and design from your code.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.thewebmasters.net/php/FastTemplate.phtml"&gt;FastTemplate&lt;/a&gt;&lt;br /&gt;A simple variable interpolation template class that parses your templates for variables and spits out HTML with their values&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.maiatech.com/shellpage.php"&gt;ShellPage&lt;/a&gt;&lt;br /&gt;A simple and easy to use class that lets you make whole websites based on template files for layouts. Change the template and your whole site changes.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.script.gr/go/scripts/STP/"&gt;STP Simple Template Parser&lt;/a&gt;&lt;br /&gt;A simple, light weight and easy to use template parser class. It can assemble a page from several templates, output result pages to the browser or write them to the filesystem.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.net-track.ch/opensource/template/"&gt;OO Template Class&lt;/a&gt;&lt;br /&gt;An object oriented template class you can use in your own programs.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://sourceforge.net/projects/simpletpl"&gt;SimpleTemplate&lt;/a&gt;&lt;br /&gt;A template engine to create and structure websites and applications. It can translate and compile the templates.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.massassi.com/bTemplate/"&gt;bTemplate&lt;/a&gt;&lt;br /&gt;A small and fast template class that allows you to separate your PHP logic from your HTML presentation code.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://phpsavant.com/"&gt;Savant&lt;/a&gt;&lt;br /&gt;A powerful but lightweight PEAR-compliant template system. It is non-compiling, and uses PHP itself as its template language.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://ets.sourceforge.net/"&gt;ETS - easy template system&lt;/a&gt;&lt;br /&gt;A template system that allows you to reshuffle templates with exactly the same data.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://macdeviant.com/scripts/template/index.php"&gt;EasyTemplatePHP&lt;/a&gt;&lt;br /&gt;A simple, yet powerful templating system for your site.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://vlib.activefish.com/"&gt;vlibTemplate&lt;/a&gt;&lt;br /&gt;A fast, full featured template system that includes a caching and debugging class.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://avantemplate.sourceforge.net/"&gt;AvanTemplate&lt;/a&gt;&lt;br /&gt;A template engine that is multi-byte safe and consumes little computing resource. It supports variable replacement and content blocks that can be set to hidden or shown.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.grafxsoftware.com/product.php?id=26"&gt;Grafx Software's Fast Template&lt;/a&gt;&lt;br /&gt;A modification of the popular Fast Template system, this includes a cache function, debug console, and silent removal of unassigned dynamic blocks.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://templatepower.codocad.com/"&gt;TemplatePower&lt;/a&gt;&lt;br /&gt;A fast, simple and powerful template class. Features nested dynamic block support, block/file include support and show/hide unassigned variables.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.virtualcreations.com.au/mark/tagtemplate.htm"&gt;TagTemplate&lt;/a&gt;&lt;br /&gt;This library function was designed for use with template files and allows you to retrieve info from HTML files.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://htmltmpl.sourceforge.net/"&gt;htmltmpl: templating engine&lt;/a&gt;&lt;br /&gt;A templating engine for Python and PHP. Targeted to web application developers, who want to separate program code and design of their projects.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.cmarshall.net/DreamweaverTemplate"&gt;PHP Class for Parsing Dreamweaver templates&lt;/a&gt;&lt;br /&gt;A simple class to parse a Dreamweaver template for use in custom mods for a Gallery 2 and a WordPress blog.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.source-code.biz/"&gt;MiniTemplator (Template Engine)&lt;/a&gt;&lt;br /&gt;A compact template engine for HTML files. It features a simple syntax for template variables and blocks. Blocks can be nested.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.analysisandsolutions.com/software/layout/layout.htm"&gt;Layout Solution&lt;/a&gt;&lt;br /&gt;Simplifies website development and maintenance. It holds commonly used variables and page elements so you don't need to duplicate common layouts over and over.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://zoned.net:81/~xkahn/php/fasttemplate/"&gt;Cached Fast Template&lt;/a&gt;&lt;br /&gt;This inclusion into &lt;a class="ResourceLink" href="http://php.resourceindex.com/detail/00015.html"&gt;FastTemplate&lt;/a&gt; allows for caching of the template files, and can even cache with different specifications on separate blocks of content.&lt;br /&gt;&lt;br /&gt;&lt;a class="ResourceLink" href="http://www.tinybutstrong.com/"&gt;TinyButStrong&lt;/a&gt;&lt;br /&gt;A template engine that supports MySQL, Odbc, Sql-Server and ADODB. It includes seven methods and two properties.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sitepoint.com/article/beyond-template-engine"&gt;Brian Lozier's php based template engine&lt;/a&gt;&lt;br /&gt;Only 2k in size, very fast and object-orientated.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.phpwact.org"&gt;WACT&lt;/a&gt;&lt;br /&gt;a template engine that separates code from design.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://phptal.motion-twin.com/"&gt;PHPTAL&lt;/a&gt;&lt;br /&gt;a XML/XHTML template library for PHP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114245732792085249?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114245732792085249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114245732792085249' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114245732792085249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114245732792085249'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/php-template-engine-roundup.html' title='php template engine roundup'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114240250892950397</id><published>2006-03-14T21:57:00.000-08:00</published><updated>2006-06-14T16:12:16.683-07:00</updated><title type='text'>10 database speed tests</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;I came across the following 10 benchmark tests covering:&lt;br /&gt;&lt;br /&gt;SQLite version 3.3.3&lt;br /&gt;SQLite version 3.3.3&lt;br /&gt;SQLite version 2.8.17&lt;br /&gt;SQLite version 2.8.17&lt;br /&gt;PostgreSQL version 8.1.2&lt;br /&gt;MySQL version 5.0.18&lt;br /&gt;FirebirdSQL version 1.5.2&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;About the hardware/database settings used&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;All databases were installed with default settings.&lt;br /&gt;Tests were run on 1.6GHz Sempron with 1GB of ram and 7200rpm SATA disk running Windows 2000 + SP4 with all updates applied.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test 1: 1000 INSERTs&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');... 995 lines omittedINSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');&lt;br /&gt;&lt;br /&gt;SQLite 3.3.3 (sync):&lt;br /&gt;3.823&lt;br /&gt;SQLite 3.3.3 (nosync):&lt;br /&gt;1.668&lt;br /&gt;SQLite 2.8.17 (sync):&lt;br /&gt;4.245&lt;br /&gt;SQLite 2.8.17 (nosync):&lt;br /&gt;1.743&lt;br /&gt;PostgreSQL 8.1.2:&lt;br /&gt;4.922&lt;br /&gt;MySQL 5.0.18 (sync):&lt;br /&gt;2.647&lt;br /&gt;MySQL 5.0.18 (nosync):&lt;br /&gt;0.329&lt;br /&gt;FirebirdSQL 1.5.2:&lt;br /&gt;0.320&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test 2: 25000 INSERTs in a transaction&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;BEGIN;CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));INSERT INTO t2 VALUES(1,298361,'two hundred ninety eight thousand three hundred sixty one');... 24997 lines omittedINSERT INTO t2 VALUES(24999,447847,'four hundred forty seven thousand eight hundred forty seven');INSERT INTO t2 VALUES(25000,473330,'four hundred seventy three thousand three hundred thirty');COMMIT;&lt;br /&gt;&lt;br /&gt;SQLite 3.3.3 (sync):&lt;br /&gt;0.764&lt;br /&gt;SQLite 3.3.3 (nosync):&lt;br /&gt;0.748&lt;br /&gt;SQLite 2.8.17 (sync):&lt;br /&gt;0.698&lt;br /&gt;SQLite 2.8.17 (nosync):&lt;br /&gt;0.663&lt;br /&gt;PostgreSQL 8.1.2:&lt;br /&gt;16.454&lt;br /&gt;MySQL 5.0.18 (sync):&lt;br /&gt;7.833&lt;br /&gt;MySQL 5.0.18 (nosync):&lt;br /&gt;7.038&lt;br /&gt;FirebirdSQL 1.5.2:&lt;br /&gt;4.280&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test 3: 25000 INSERTs into an indexed table&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;BEGIN;CREATE TABLE t3(a INTEGER, b INTEGER, c VARCHAR(100));CREATE INDEX i3 ON t3(c);... 24998 lines omittedINSERT INTO t3 VALUES(24999,442549,'four hundred forty two thousand five hundred forty nine');INSERT INTO t3 VALUES(25000,423958,'four hundred twenty three thousand nine hundred fifty eight');COMMIT;&lt;br /&gt;&lt;br /&gt;SQLite 3.3.3 (sync):&lt;br /&gt;1.778&lt;br /&gt;SQLite 3.3.3 (nosync):&lt;br /&gt;1.832&lt;br /&gt;SQLite 2.8.17 (sync):&lt;br /&gt;1.526&lt;br /&gt;SQLite 2.8.17 (nosync):&lt;br /&gt;1.364&lt;br /&gt;PostgreSQL 8.1.2:&lt;br /&gt;19.236&lt;br /&gt;MySQL 5.0.18 (sync):&lt;br /&gt;11.524&lt;br /&gt;MySQL 5.0.18 (nosync):&lt;br /&gt;12.427&lt;br /&gt;FirebirdSQL 1.5.2:&lt;br /&gt;6.351&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test 4: 100 SELECTs without an index&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;SELECT count(*), avg(b) FROM t2 WHERE b&gt;=0 AND b&lt;1000;select&gt;=100 AND b&lt;1100;select&gt;=200 AND b&lt;1200;...&gt;=9700 AND b&lt;10700;select&gt;=9800 AND b&lt;10800;select&gt;=9900 AND b&lt;10900;&gt;Test 5: 100 SELECTs on a string comparison&lt;br /&gt;&lt;br /&gt;SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one%';SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%two%';SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%three%';... 94 lines omittedSELECT count(*), avg(b) FROM t2 WHERE c LIKE '%ninety eight%';SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%ninety nine%';SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one hundred%';&lt;br /&gt;&lt;br /&gt;SQLite 3.3.3 (sync):&lt;br /&gt;4.853&lt;br /&gt;SQLite 3.3.3 (nosync):&lt;br /&gt;4.868&lt;br /&gt;SQLite 2.8.17 (sync):&lt;br /&gt;4.511&lt;br /&gt;SQLite 2.8.17 (nosync):&lt;br /&gt;4.500&lt;br /&gt;PostgreSQL 8.1.2:&lt;br /&gt;6.565&lt;br /&gt;MySQL 5.0.18 (sync):&lt;br /&gt;3.424&lt;br /&gt;MySQL 5.0.18 (nosync):&lt;br /&gt;2.090&lt;br /&gt;FirebirdSQL 1.5.2:&lt;br /&gt;5.803&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test 6: INNER JOIN without an index&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;SELECT t1.a FROM t1 INNER JOIN t2 ON t1.b=t2.b;&lt;br /&gt;SQLite 3.3.3 (sync):&lt;br /&gt;14.473&lt;br /&gt;SQLite 3.3.3 (nosync):&lt;br /&gt;14.445&lt;br /&gt;SQLite 2.8.17 (sync):&lt;br /&gt;47.776&lt;br /&gt;SQLite 2.8.17 (nosync):&lt;br /&gt;47.750&lt;br /&gt;PostgreSQL 8.1.2:&lt;br /&gt;0.176&lt;br /&gt;MySQL 5.0.18 (sync):&lt;br /&gt;3.421&lt;br /&gt;MySQL 5.0.18 (nosync):&lt;br /&gt;3.443&lt;br /&gt;FirebirdSQL 1.5.2:&lt;br /&gt;0.141&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test 7: Creating an index&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;CREATE INDEX i2a ON t2(a);CREATE INDEX i2b ON t2(b);&lt;br /&gt;SQLite 3.3.3 (sync):&lt;br /&gt;0.552&lt;br /&gt;SQLite 3.3.3 (nosync):&lt;br /&gt;0.526&lt;br /&gt;SQLite 2.8.17 (sync):&lt;br /&gt;0.650&lt;br /&gt;SQLite 2.8.17 (nosync):&lt;br /&gt;0.605&lt;br /&gt;PostgreSQL 8.1.2:&lt;br /&gt;0.276&lt;br /&gt;MySQL 5.0.18 (sync):&lt;br /&gt;1.159&lt;br /&gt;MySQL 5.0.18 (nosync):&lt;br /&gt;0.275&lt;br /&gt;FirebirdSQL 1.5.2:&lt;br /&gt;0.264&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test 8: 5000 SELECTs with an index&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;SELECT count(*), avg(b) FROM t2 WHERE b&gt;=0 AND b&lt;100;select&gt;=100 AND b&lt;200;select&gt;=200 AND b&lt;300;...&gt;=499700 AND b&lt;499800;select&gt;=499800 AND b&lt;499900;select&gt;=499900 AND b&lt;500000;&gt;Test 9: 1000 UPDATEs without an index&lt;br /&gt;&lt;br /&gt;BEGIN;UPDATE t1 SET b=b*2 WHERE a&gt;=0 AND a&lt;10;update b="b*2"&gt;=10 AND a&lt;20;... b="b*2"&gt;=9980 AND a&lt;9990;update b="b*2"&gt;=9990 AND a&lt;10000;commit;&gt;Test 10: 25000 UPDATEs with an index&lt;br /&gt;&lt;br /&gt;BEGIN;UPDATE t2 SET b=271822 WHERE a=1;UPDATE t2 SET b=28304 WHERE a=2;... 24996 lines omittedUPDATE t2 SET b=442549 WHERE a=24999;UPDATE t2 SET b=423958 WHERE a=25000;COMMIT;&lt;br /&gt;&lt;br /&gt;SQLite 3.3.3 (sync):&lt;br /&gt;1.883&lt;br /&gt;SQLite 3.3.3 (nosync):&lt;br /&gt;1.894&lt;br /&gt;SQLite 2.8.17 (sync):&lt;br /&gt;1.994&lt;br /&gt;SQLite 2.8.17 (nosync):&lt;br /&gt;1.973&lt;br /&gt;PostgreSQL 8.1.2:&lt;br /&gt;23.933&lt;br /&gt;MySQL 5.0.18 (sync):&lt;br /&gt;16.348&lt;br /&gt;MySQL 5.0.18 (nosync):&lt;br /&gt;17.383&lt;br /&gt;FirebirdSQL 1.5.2:&lt;br /&gt;15.542&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test 9: 1000 UPDATEs without an index&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;BEGIN;UPDATE t1 SET b=b*2 WHERE a&gt;=0 AND a&lt;10;update b="b*2"&gt;=10 AND a&lt;20;... b="b*2"&gt;=9980 AND a&lt;9990;update b="b*2"&gt;=9990 AND a&lt;10000;commit;&gt;Test 10: 25000 UPDATEs with an index&lt;br /&gt;&lt;br /&gt;BEGIN;UPDATE t2 SET b=271822 WHERE a=1;UPDATE t2 SET b=28304 WHERE a=2;... 24996 lines omittedUPDATE t2 SET b=442549 WHERE a=24999;UPDATE t2 SET b=423958 WHERE a=25000;COMMIT;&lt;br /&gt;&lt;br /&gt;SQLite 3.3.3 (sync):    &lt;br /&gt;3.153 &lt;br /&gt;SQLite 3.3.3 (nosync):    &lt;br /&gt;3.088 &lt;br /&gt;SQLite 2.8.17 (sync):    &lt;br /&gt;3.993 &lt;br /&gt;SQLite 2.8.17 (nosync):    &lt;br /&gt;3.983 &lt;br /&gt;PostgreSQL 8.1.2:    &lt;br /&gt;5.740 &lt;br /&gt;MySQL 5.0.18 (sync):    &lt;br /&gt;2.718 &lt;br /&gt;MySQL 5.0.18 (nosync):    &lt;br /&gt;1.641 &lt;br /&gt;FirebirdSQL 1.5.2:    &lt;br /&gt;2.976 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you want to see some more information on the above and 10 more tests, you can go &lt;a href="http://www.sqlite.org/cvstrac/wiki?p=SpeedComparison"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114240250892950397?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114240250892950397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114240250892950397' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114240250892950397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114240250892950397'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/10-database-speed-tests.html' title='10 database speed tests'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114223008033128073</id><published>2006-03-12T22:06:00.000-08:00</published><updated>2006-04-27T14:15:42.900-07:00</updated><title type='text'>Flash 8 and Security</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I recently came across the following message when I tried to run a flash program on a client's machine:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/flash8.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/flash8.jpg" border="0" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The security dialog comes up because when you fire getURL() with Local Playback Security set to&lt;br /&gt;"Access Local Files only" it sees the getURL call as a request for network resource (and pops up the&lt;br /&gt;security dialog).&lt;br /&gt;&lt;br /&gt;If you then set Local Playback Security set to "Access Network".... Normally that would allow the&lt;br /&gt;call access to the network. But the requested communication is actually between a local SWF and a&lt;br /&gt;local HTML file, so it sees that as a local file accessing a local file, which is outside of what's&lt;br /&gt;allowed when LPS is set to "Access Network". Which results in a Flash Player 8 Security Sandbox dialog .&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For Developers, there are three ways to solve the above issue:&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;1.&lt;/strong&gt; The end user has to use the Settings Manager to set local file security to "Always Allow" AND&lt;br /&gt;they have to add the path to the file as a trusted path.&lt;br /&gt;The direct path to this section of the online Settings Manager is&lt;br /&gt;(&lt;a href="http://www.macromedia.com/support/documentation/"&gt;http://www.macromedia.com/support/documentation/&lt;/a&gt;&lt;br /&gt;en/flashplayer/help/s...).&lt;br /&gt;The default is 'always ask'. Change that to 'Always Allow'.&lt;br /&gt;Then add the path to your local content to the trusted locations. For example, if your content&lt;br /&gt;is on a CD-ROM then you'd add the path to the CD (for example, "F:/").&lt;br /&gt;&lt;br /&gt;Doing these two things is essentially enabling a local Trust File. Settings manager then&lt;br /&gt;writes the trust file settings for you, to the #SharedObjects (which is obfuscated so nobody can&lt;br /&gt;crack it)&lt;br /&gt;So that's how you can do it if your users are internet-connected and you feel they're savvy&lt;br /&gt;enough to handle the steps.&lt;br /&gt;&lt;br /&gt;What if your users are not internet connected? In that case you have to manually add the trust file&lt;br /&gt;to one of two locations:&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;2.&lt;/strong&gt; You can create a trust file in C:\Documents and Settings\&lt;username&gt;\Application&lt;br /&gt;Data\Macromedia\Flash Player\#Security\FlashPlayerTrust.&lt;br /&gt;The name of the file can be whatever you want.&lt;br /&gt;The only minimum thing in the file is one line of text that's the path you want to trust.&lt;br /&gt;Additional paths can be one per line.&lt;br /&gt;Do this if you just want to set up trust for one unique user account on that machine.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;3.&lt;/strong&gt; You can create a trust file in C:\WINDOWS\system32\Macromed\Flash\FlashPlayerTrust.&lt;br /&gt;This is the same trust file as step #2, but sets it for all the users on this machine.&lt;br /&gt;The catch here is that you have to be an admin on the machine to create this trust file.&lt;br /&gt;&lt;br /&gt;Options #2 and #3 are obviously also available to end users who do have internet connections but&lt;br /&gt;whom you might not want to direct to the Flash Player Settings Manager.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114223008033128073?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114223008033128073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114223008033128073' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114223008033128073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114223008033128073'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/flash-8-and-security.html' title='Flash 8 and Security'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114211722160295646</id><published>2006-03-11T14:41:00.000-08:00</published><updated>2006-06-14T16:38:41.086-07:00</updated><title type='text'>optimizing mysql tables</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Many times, slow access to a mysql database can be the result of Badly defined or non-existent indexes and fixing these can often lead to better performance. Here is an&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;example table&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;CREATE TABLE address_book (&lt;br /&gt;&lt;br /&gt;contact_number char(10) NOT NULL,&lt;br /&gt;firstname varchar(40),&lt;br /&gt;surname varchar(40),&lt;br /&gt;address text,&lt;br /&gt;telephone varchar(25)&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;example query&lt;/strong&gt;: SELECT firstname FROM address_book WHERE contact_number = '12312';&lt;br /&gt;&lt;br /&gt;This will retrieve the firstname of a person added to the address_book table, based on the contact number.&lt;br /&gt;&lt;br /&gt;Without any kind of indexes added to this table, mysql will have to search through each row to find the item that you would like to find, which is very inefficient.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Optimizing your table&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;There is a built-in command called explain, that can show you what, if any, indexes that are being used to retrieve results.&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;example:&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;EXPLAIN SELECT firstname FROM address_book WHERE contact_number = '12312';&lt;br /&gt;&lt;br /&gt;This will return a set of results that will tell you how myql is processing the results&lt;br /&gt;&lt;br /&gt;&lt;em&gt;table: &lt;/em&gt;The&lt;em&gt; &lt;/em&gt;table the output is about (will show multiple if you have joins)&lt;br /&gt;&lt;em&gt;type:&lt;/em&gt; The type of join is being used.best to worst the &lt;em&gt;types are&lt;/em&gt;: system, const, eq_ref, ref, range, index, all&lt;br /&gt;&lt;em&gt;possible_keys:&lt;/em&gt; Shows which possible indexes apply to this table&lt;br /&gt;key: And which one is actually used&lt;br /&gt;&lt;em&gt;key_len: T&lt;/em&gt;he length of the key used. The shorter that better.&lt;br /&gt;&lt;em&gt;ref: The &lt;/em&gt;column, or a constant, is used&lt;br /&gt;&lt;em&gt;rows:&lt;/em&gt; The number&lt;em&gt; &lt;/em&gt;of rows mysql believes it must examine to get the data&lt;br /&gt;&lt;em&gt;extra:&lt;/em&gt; You don't want to see "using temporary" or "using filesort"&lt;br /&gt;&lt;br /&gt;and index can be added to the above example table using the following command:&lt;br /&gt;&lt;br /&gt;ALTER TABLE address_book ADD INDEX(contact_number);&lt;br /&gt;&lt;br /&gt;you can also add an index on only part of a varchar. In the following, I will add an index on only 8 of the 10 characters.&lt;br /&gt;&lt;br /&gt;ALTER TABLE address_book ADD INDEX(contact_number(8));&lt;br /&gt;&lt;br /&gt;Why would you want to do this?&lt;br /&gt;&lt;br /&gt;Indexes do increase performance in the right situations, but they are also a tradeoff between speed and space. The bigger an index is, the more space it will consume on your harddrive.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Using the query optimizer/analyzer&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;the following command can analyze your table key distribution to find out the best indexes to use:&lt;/p&gt;&lt;p&gt;analyze table *tablename*&lt;/p&gt;&lt;p&gt;also, another thing to keep in mind is the fact that over time, update and delete operations leave gaps in the table, which will cause un-needed overhead when reading data from your tables&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;from time to time, it is a good idea to run the following (which will fix the above issue):&lt;/p&gt;&lt;p&gt;optimize table *tablename*&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114211722160295646?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114211722160295646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114211722160295646' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114211722160295646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114211722160295646'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/optimizing-mysql-tables.html' title='optimizing mysql tables'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114196573134778106</id><published>2006-03-09T20:36:00.000-08:00</published><updated>2006-03-14T07:49:57.706-08:00</updated><title type='text'>What would you like to see in PHP 6?</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/afup2005.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/afup2005.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;In November of 2005, the major developers working on the core of PHP met up in Paris and discussed various additions that would possibly make version 6.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The attendees&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Marcus Börger (SOMABO)&lt;br /&gt;Wez Furlong (OmniTI)&lt;br /&gt;Rasmus Lerdorf (Yahoo!)&lt;br /&gt;Derick Rethans (eZ systems)&lt;br /&gt;Dmitry Stogov (Zend)&lt;br /&gt;Zeev Suraski (Zend)&lt;br /&gt;Jani Taskinen&lt;br /&gt;Andrei Zmievski (Yahoo!) &lt;/p&gt;&lt;p&gt;The following are a list of the top 5 additions I think should be made (in no particular order):&lt;/p&gt;&lt;p&gt;1) Filename Encoding&lt;/p&gt;&lt;p&gt;&lt;strong&gt;issue&lt;/strong&gt;: Files on a file system can have names encoded in different character sets. For example Windows can make use of it's UTF16 based filename API, while on Linux it simply depends on the application&lt;/p&gt;&lt;p&gt;2) optimizing []&lt;/p&gt;&lt;p&gt;&lt;strong&gt;issue: &lt;/strong&gt;Currently using the [] operator to select an arbitrary character is very slow as PHP needs to start scanning the string from the start. &lt;/p&gt;&lt;p&gt;3) register_globals&lt;/p&gt;&lt;p&gt;&lt;strong&gt;issue&lt;/strong&gt;: This causes many security issues and should be removed completly. I still encouter PHP scripts that make use of the this feature.&lt;/p&gt;&lt;p&gt;4) 64-bit integer&lt;/p&gt;&lt;p&gt;&lt;strong&gt;issue&lt;/strong&gt;: With 64-bit processing in the horizen, this will come in handy for future (and some present) apps.&lt;/p&gt;&lt;p&gt;5) built-in opcode cache&lt;/p&gt;&lt;p&gt;&lt;strong&gt;issue&lt;/strong&gt;: When an opcode caching system is installed (such as zend or ion cube), script execution time is much better. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;A list of everything discussed can be found &lt;a href="http://www.php.net/~derick/meeting-notes.html"&gt;Here&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114196573134778106?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114196573134778106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114196573134778106' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114196573134778106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114196573134778106'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/what-would-you-like-to-see-in-php-6.html' title='What would you like to see in PHP 6?'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114186347118925266</id><published>2006-03-08T16:09:00.000-08:00</published><updated>2006-05-12T01:36:52.336-07:00</updated><title type='text'>patTemplate and php</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;by Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;What is patTemplate?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;patTemplate is a set of classes that allow you to separate your php code from design/output, making your code easier to maintain&lt;span style="FONT-WEIGHT: bold"&gt;.&lt;/span&gt;&lt;span class="nm"&gt; To identify a certain part of the page as a template, patTemplate uses &lt;acronym title="eXtensible Markup Language"&gt;XML&lt;/acronym&gt; tags to assign a template a unique name and a various attributes (see &lt;a class="link" href="http://www.php-tools.de/site.php?&amp;PHPSESSID=244c8bc387ce4eb40b74d52dc6c87215&amp;amp;file=/patTemplate/doc/tags.xml"&gt;patTemplate Tags and attributes&lt;/a&gt; for a list of all tags and attributes). When parsing a template, the parser divides the page in several chunks and treats them as separate templates. By using patTemplate's API you can hide, display or repeat a certain template.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Template Types&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;OddEven&lt;/strong&gt;&lt;br /&gt;you can assign to subtemplates () to this type: Odd and Even, which will be alternated, when the template is repeated &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Condition&lt;/strong&gt;&lt;br /&gt;you can assign as many subtemplate as you like and you have to assign one variable which will be used to compare it with the specified conditions of the subtemplates. This allows you to define different HTML code for each value your condition variable may have. There are two special conditions you can use: default, which is similar to the default in a switch/case statement and empty which will be displayed, when there is no value assigned to the condition variable.  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SimpleCondition&lt;/strong&gt;&lt;br /&gt;A situation that often arises is that an error message has to be displayed if an error occured. Normally you would set the error message if it exists or hide the template using setAttribute() if there is none. By using a template of type SimpleCondition you can assign a list of variables (using the requiredvars) that have to be set if the template has to be displayed. If one of these variables is not set, the template will not be visible.  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Variables&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;patTemplate supports variables similar to programming languages. There can be local variables (assigned by addVar) and global variables (assigned by addGlobalVar).&lt;br /&gt;&lt;br /&gt;Global variables can only be scalar variables (strings, integers,...) and local variables can also be arrays. If you assign an array to a variable, the template where you assigned the variable will be repeated.&lt;br /&gt;&lt;br /&gt;If a condition template uses the useglobals="yes" attribute global variables will be used if no local variables are set.&lt;br /&gt;&lt;br /&gt;Variables have to be written in uppercase and may only contain chars, numbers or the underscore (_). Variables are always enclosed in {}.&lt;br /&gt;&lt;br /&gt;Variables will be replaced with their values when parsing a template.&lt;br /&gt;&lt;br /&gt;There is one predefined variable you can use when you want to enumerate a template that is automatically repeated: just place the variable PAT_ROW_VAR in your template, where you'd like to enumeration to appear (can also be used for javascript mouseovers).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How to install&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;There are two ways to install phptemplate&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;1) through pear&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Download the pear package and execute: " pear install patTemplate-3.0.1.tgz"&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2) Manually&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;A) Download the .zip or .tgz manual package from the patTemplate website&lt;br /&gt;B) Download the patError class&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Example of usage&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Example of usage&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;error_reporting( E_ALL ); &lt;br /&gt;&lt;br /&gt;//require the error reporting class&lt;br /&gt;require_once( 'pat/patErrorManager.php' );&lt;br /&gt;//require the main template class &lt;br /&gt;require_once '../patTemplate.php'; &lt;br /&gt;//create a new instance&lt;br /&gt;$tmpl = &amp;new patTemplate();&lt;br /&gt;//set the directory of where to find the templates &lt;br /&gt;$tmpl-&amp;gtsetRoot( 'templates' ); &lt;br /&gt;//use this file for your template&lt;br /&gt;$tmpl-&amp;gtreadTemplatesFromInput( 'example_api_addvar.tmpl' ); &lt;br /&gt;//add a variable for displaying&lt;br /&gt;$tmpl-&amp;gtaddVar( 'template1', 'argh', array( 'one', 'two', 'repeat it.' ) ); &lt;br /&gt;//actually display it&lt;br /&gt;$tmpl-&amp;gtdisplayParsedTemplate();&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why use this template system?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;There are many template systems available for PHP.  I have recently started using this one over the others because it is simple, has less overhead, and is much easier for a person designing your pages to read and understand.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;patTemplate can be downloaded &lt;a href="http://www.php-tools.de/site.php"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114186347118925266?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114186347118925266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114186347118925266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114186347118925266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114186347118925266'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/pattemplate-and-php.html' title='patTemplate and php'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114169556025332312</id><published>2006-03-06T17:37:00.000-08:00</published><updated>2006-06-06T14:16:54.793-07:00</updated><title type='text'>5 reasons not to use oscommerce</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/oscommerce.0.gif"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/oscommerce.0.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/oscommerce.gif"&gt;&lt;/a&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What is Open Commerce?&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;From oscommerce.com:&lt;/strong&gt; &lt;em&gt;"osCommerce is the leading Open Source online shop e-commerce solution that is available for free under the GNU General Public License. It features a rich set of out-of-the-box online shopping cart functionality that allows store owners to setup, run, and maintain their online stores with minimum effort and with no costs, license fees, or limitations involved. &lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;The goal of the osCommerce project is to continually evolve by attracting a community that supports the ongoing development of the project at its core level and extensively through contributions to provide additional functionality to the already existing rich feature set."&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Why Shouldn't I use it?&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;1) no separation of logic and presentation&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Smaller applications can be created without separating logic and presentation, but when an application gets as large as oscommerce, there needs to be some kind of templating system in place.&lt;br /&gt;A templating system can also be used to cache dynamic pages and improve the overall performance.&lt;br /&gt;&lt;br /&gt;A good, scalable system needs to be engineered from the ground up. It looks to me like it was hacked together with pieces of code here and there&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2) difficult to integrate into an existing design&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;out of the box, the cart works fairly well. If you want to make any drastic design changes, you will run into major issues.&lt;br /&gt;&lt;br /&gt;Although it is free, and this may be intising to many companies, the time and labor cost of updating the cart to suit your needs ends up being more than many of the commerical carts available.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3) security&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;although it is updated, #1 makes it very difficult to make updates without having to manually open up each .php file and make the changes yourself.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4) cannot have multiple sizes of image previews (thumbnail, medium, large)&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;5) admin navigation issues&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;a) hard to do shipping cost per item (with different items having different costs) per country&lt;br /&gt;b) editing product descriptions seems a little awkward. overall, it looks like it was developed for a programmer, rather than a store owner.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;commercial&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;cubecart - &lt;a href="http://www.cubecart.com/"&gt;http://www.cubecart.com/&lt;/a&gt;&lt;br /&gt;sunshop - &lt;a href="http://www.turnkeywebtools.com/"&gt;http://www.turnkeywebtools.com/&lt;/a&gt;&lt;br /&gt;miva mercant - &lt;a href="http://www.miva.com"&gt;http://www.miva.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;open source&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;interchange - &lt;a href="http://www.icdevgroup.com/"&gt;http://www.icdevgroup.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114169556025332312?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114169556025332312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114169556025332312' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114169556025332312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114169556025332312'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/5-reasons-not-to-use-oscommerce.html' title='5 reasons not to use oscommerce'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114163016326748850</id><published>2006-03-05T23:17:00.000-08:00</published><updated>2006-09-19T09:59:18.543-07:00</updated><title type='text'>using sqlite and php</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/sqlite.gif"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/sqlite.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;by Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;What is SQLite?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;SQLite is a small library that implements a self-contained, embeddable, zero-configuration SQL database engine. Features include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Transactions are atomic, consistent, isolated, and durable (ACID) even after system crashes and power failures. &lt;/li&gt;&lt;li&gt;Zero-configuration - no setup or administration needed.&lt;/li&gt;&lt;li&gt;Implements most of SQL92. (&lt;a href="http://www.sqlite.org/omitted.html"&gt;Features not supported&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;A complete database is stored in a single disk file.&lt;/li&gt;&lt;li&gt;Database files can be freely shared between machines with different byte orders.&lt;/li&gt;&lt;li&gt;Supports databases up to 2 terabytes (2&lt;sup&gt;&lt;small&gt;41&lt;/small&gt;&lt;/sup&gt; bytes) in size.&lt;/li&gt;&lt;li&gt;Sizes of strings and BLOBs limited only by available memory.&lt;/li&gt;&lt;li&gt;Small code footprint: less than 250KiB fully configured or less than 150KiB with optional features omitted.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sqlite.org/speed.html"&gt;Faster&lt;/a&gt; than popular client/server database engines for most common operations.&lt;/li&gt;&lt;li&gt;Simple, easy to use &lt;a href="http://www.sqlite.org/capi3.html"&gt;API&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sqlite.org/tclsqlite.html"&gt;TCL bindings&lt;/a&gt; included. Bindings for many other languages &lt;a href="http://www.sqlite.org/cvstrac/wiki?p=SqliteWrappers"&gt;available separately.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Well-commented source code with over 95% test coverage.&lt;/li&gt;&lt;li&gt;Self-contained: no external dependencies.&lt;/li&gt;&lt;li&gt;Sources are in the &lt;a href="http://www.sqlite.org/copyright.html"&gt;public domain&lt;/a&gt;. Use for any purpose.&lt;/li&gt;&lt;/ul&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Why would I need this?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;If you want to have the advantages of a SQL database, without having to install a separate system such as mysql or postgres. It has also been demonstrated to work on websites getting more than 1,000,000 hits per day.&lt;br /&gt;&lt;br /&gt;lots of good performance info can be found &lt;a href="http://www.sqlite.org/cvstrac/wiki"&gt;here&lt;/a&gt;&lt;br /&gt;project page can be found &lt;a href="http://www.sqlite.org/"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Installing&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Read the INSTALL file, which comes with the package. Or just use the PEAR installer with &lt;b class="command"&gt;pear install sqlite&lt;/b&gt;. SQLite itself is already included, You do not need to install any additional software.&lt;br /&gt;&lt;p&gt;Windows users may download the DLL version of the SQLite extension here: (&lt;a href="http://snaps.php.net/win32/PECL_STABLE/php_sqlite.dll" target="_top"&gt;php_sqlite.dll&lt;/a&gt;). &lt;/p&gt;&lt;p&gt;In PHP 5, the SQLite extension and the engine itself are bundled and compiled by default. However, since PHP 5.1.0 you need to manually activate the extension in &lt;tt class="filename"&gt;php.ini&lt;/tt&gt; (because it is now bundled as shared). Moreover, since PHP 5.1.0 SQLite depends on &lt;a href="http://jp.php.net/manual/en/ref.pdo.php"&gt;PDO&lt;/a&gt; it must be enabled too, by adding the following lines to &lt;tt class="filename"&gt;php.ini&lt;/tt&gt; (in order): &lt;/p&gt;&lt;div class="informalexample"&gt;&lt;a name="AEN170081"&gt;extension=php_pdo.dll&lt;br /&gt;extension=php_sqlite.dll&lt;/a&gt;&lt;br&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="informalexample"&gt;&lt;/div&gt;&lt;div class="informalexample"&gt;&lt;/div&gt;&lt;div class="informalexample"&gt;&lt;/div&gt;On Linux or Unix operating systems, if you build PDO as a shared extension, you must build SQLite as a shared extension using the &lt;b class="command"&gt;--with-sqlite=shared&lt;/b&gt; configure option.&lt;br /&gt;&lt;p&gt;SQLite 3 is supported through &lt;a href="http://jp.php.net/manual/en/ref.pdo-sqlite.php"&gt;PDO SQLite&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Windows installation for unprivileged accounts&lt;/strong&gt;: On Windows operating systems, unprivileged accounts don't have the TMP environment variable set by default. This will make sqlite create temporary files in the windows directory, which is not desirable. So, you should set the TMP environment variable for the web server or the user account the web server is running under. If Apache is your web server, you can accomplish this via a SetEnv directive in your httpd.conf file. For example:&lt;br /&gt;&lt;a name="AEN170093"&gt;&lt;/a&gt;&lt;br /&gt;SetEnv TMP c:/temp&lt;br /&gt;If you are unable to establish this setting at the server level, you can implement the setting in your script:&lt;br /&gt;&lt;a name="AEN170095"&gt;&lt;/a&gt;&lt;br /&gt;putenv('TMP=C:/temp');&lt;br /&gt;The setting must refer to a directory that the web server has permission to create files in and subsequently write to and delete the files it created. Otherwise, you may receive the following error message: malformed database schema - unable to open a temporary database file for storing temporary tables&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Using SQlite&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The following is a simple example that can get you started with SQLite:&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &amp;lt?php&lt;br /&gt;// create new database &lt;br /&gt;$db = sqlite_open("db.sqlite");&lt;br /&gt;&lt;br /&gt;//create a table named test&lt;br /&gt;// sqlite_query($db , "CREATE TABLE test (id INTEGER PRIMARY KEY, name CHAR(128))");&lt;br /&gt;&lt;br /&gt;// insert sample data&lt;br /&gt;sqlite_query($db, "INSERT INTO test (name) VALUES ('Imuvalue')");&lt;br /&gt;&lt;br /&gt;// execute query&lt;br /&gt;$result = sqlite_query($db, "SELECT * FROM test");&lt;br /&gt;// iterate through the retrieved rows&lt;br /&gt;while ($row = sqlite_fetch_array($result)) &lt;br /&gt;    print_r($row);&lt;br /&gt;// close database connection&lt;br /&gt;sqlite_close($db);&lt;br /&gt;?&amp;gt&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114163016326748850?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114163016326748850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114163016326748850' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114163016326748850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114163016326748850'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/using-sqlite-and-php.html' title='using sqlite and php'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114141530723831522</id><published>2006-03-03T11:47:00.000-08:00</published><updated>2006-05-18T09:59:55.730-07:00</updated><title type='text'>using php and postgres</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;This is a simple guide on how to start connecting to a postgres database with php. I also assume that you already have a database setup with a table/tables.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Making a connection to the database&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;First, make sure the postgres module is enabled in php. This can done by looking through your php.ini file and ucommenting it in the modules section.&lt;/p&gt;in windows, the line is: "extension=php_pgsql.dll"&lt;br /&gt;in *nix, it is: extension="php_pgsql.so"&lt;br /&gt;&lt;br /&gt;next, a statement needs to setup for the actual connect.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;$my_connection = pg_connect("user=postgres dbname=phphh");&lt;/p&gt;pg_connect() takes a single argument, a connection string, which consists of name=value pairs.&lt;br /&gt;&lt;br /&gt;Other valid connection string names include:&lt;br /&gt;&lt;br /&gt;host - an optional host name for the database&lt;br /&gt;port - an optional port number for the database&lt;br /&gt;password - a password for the user you are connecting as&lt;br /&gt;options - options to pass to the backendtty - a UNIX terminal path to send debugging information to&lt;br /&gt;&lt;br /&gt;Unless you have customised your PostgreSQL installation, you should not need to use these.&lt;br /&gt;&lt;br /&gt;The pg_connect() function returns a database connection handle which should be used with the PostgreSQL utility functions. On error, it returns FALSE.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Queries&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;$query_resource = pg_exec($my_connection,"INSERT INTO mytable VALUES('value1','value2','value3');");&lt;br /&gt;&lt;br /&gt;if(!$query_resource)&lt;br /&gt;exit("could not insert into database");&lt;br /&gt;&lt;br /&gt;$query_resource = pg_exec($my_connection,"SELECT * FROM mytable;");&lt;br /&gt;&lt;br /&gt;if(!$query_resource)&lt;br /&gt;exit("could not selectfrom database");&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Other Helpful functions&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This is a list of other helpful functions that can be used to get data.&lt;br /&gt;&lt;br /&gt;pg_fetch_row() - retrieve a single row&lt;br /&gt;setpg_fetch_array() - retrieve a single row as an array&lt;br /&gt;pg_fetch_object() - retrieve a single row as an object&lt;br /&gt;pg_result() - retrieve a single field&lt;br /&gt;pg_numrows() - number of rows returned by the query&lt;br /&gt;pg_numfields() - number of fields per row returned by query&lt;br /&gt;pg_fieldnum() - the numeric number of a given field&lt;br /&gt;pg_fieldname() - the name of a given field&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114141530723831522?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114141530723831522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114141530723831522' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114141530723831522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114141530723831522'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/using-php-and-postgres.html' title='using php and postgres'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114134221155319572</id><published>2006-03-02T15:29:00.000-08:00</published><updated>2006-03-03T23:23:33.756-08:00</updated><title type='text'>5 postgres tips</title><content type='html'>&lt;span style="font-weight: bold;"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here are 5 postgres tips to follow my "5 mysql tips" post. These are known issues with versions 7.3 and below.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1) Object names that aren't in quotes are assumed to be lower-case&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;example: Select column1 FROM table1 and SELECT COLUMN1 FROM table1 both will return results from column1. SELECT "COLUMN1" FROM table1 will be viewed as a diffrent column by postgres.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2) count(*) is very slow with large tables&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is because rather than an indexed scan, postgres scans the entire table to determine the count.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3) Min and Max are both slow with large tables&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is fixed in version 8.0, but there is a work-around that I have used in previous versions:&lt;br /&gt;&lt;br /&gt;min equivalent: SELECT column1 FROM table1 ORDER BY column1 DESC LIMIT 1&lt;br /&gt;max equivalent: SELECT column1 FROM table1 ORDER BY column1 ASC LIMIT 1&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4) unicode values&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;unicode defaults to UTF-8&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5) integers used in calculations that result in a value that is greater that 32-bits will end up as 0.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;to fix the issue, either get postgres version 8.0 or cast one of your values as a 64 bit value (select integer::INT8)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114134221155319572?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114134221155319572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114134221155319572' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114134221155319572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114134221155319572'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/5-postgres-tips_02.html' title='5 postgres tips'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114126893147530406</id><published>2006-03-01T19:07:00.000-08:00</published><updated>2006-06-14T16:40:32.833-07:00</updated><title type='text'>5 mysql tips</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;These are some tips that may help you out when dealing with mysql tables (known in 4.1 and below).&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;1) char and varchar are case sensitive&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;example:&lt;br /&gt;&lt;br /&gt;if you have a table that contains the following:&lt;br /&gt;&lt;br /&gt;table newtable (&lt;br /&gt;name varchar(32)&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;name contains the name "John Smith".&lt;br /&gt;&lt;br /&gt;the following statement: "SELECT * from newtable where name='john smith' will return our record.&lt;br /&gt;&lt;br /&gt;to stop this from happening, use the following when you create your table:&lt;br /&gt;&lt;br /&gt;CREATE TABLE newtable (&lt;br /&gt;name VARCHAR(32) BINARY&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;2) Varchar type is limited to 255 characters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;3) Varchar trailing spaces are stripped&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;example: insert into newtable values('Test with no spaces ');&lt;br /&gt;&lt;br /&gt;select concat(name, 'no spaces') FROM newtable;&lt;br /&gt;&lt;br /&gt;output will be: Test with no spacesnospaces&lt;br /&gt;&lt;br /&gt;Varchar works this way, because it saves space by stripping the spaces.&lt;br /&gt;&lt;br /&gt;if you need to keep the trailing spaces in the data you are adding to a varchar type,&lt;br /&gt;you need to use the text or blob types.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;4)  operator&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The  (or) operater is a logical operator&lt;br /&gt;&lt;br /&gt;example: select 'string1'  'string2' will not return 'string1string2'&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;5) function parameters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This issue has caused me many headaches in the past, and I am not sure why this issue was never fixed. If there is a space&lt;br /&gt;between the paramater list and an internal function that you want to execute, it will return an error.&lt;br /&gt;&lt;br /&gt;example: select min (my_field) from mytable wil return an error, while select min(my_field) from my_table will not&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114126893147530406?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114126893147530406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114126893147530406' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114126893147530406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114126893147530406'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/5-mysql-tips_01.html' title='5 mysql tips'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114125501808051864</id><published>2006-03-01T15:12:00.000-08:00</published><updated>2006-04-19T20:37:16.380-07:00</updated><title type='text'>How to manually remove a program in windows XP</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The following can help in those situations on windows, when you try and un-install a program and it either doesn't remove itself from the main add/remove programs menu or an error message comes up because the un-installer is corrupted.&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(255,0,0)"&gt;Warning: &lt;span style="font-size:0;"&gt;&lt;/span&gt;editing your registry impropery can cause damage to windows. Use the following at your own risk:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Click Start, and then click Run.&lt;br /&gt;2. In the Open box, type regedt32, and then click OK.&lt;br /&gt;3. In Registry Editor, find the following key:&lt;br /&gt;&lt;br /&gt;HKEY_LOCAL_MACHINESOFTWARE&lt;br /&gt;MicrosoftWindowsCurrentVersion\Uninstall&lt;br /&gt;&lt;br /&gt;4. In the left pane, click the Uninstall registry key, and then click Export on the File menu.&lt;br /&gt;5. In the Export Registry File dialog box that appears, click Desktop in the Save in list, type uninstall in the File name box, and then click Save.&lt;br /&gt;6. Each key listed under Uninstall in the left pane of Registry Editor represents a program that is displayed in the Currently installed programs list of the Add or Remove Programs tool. To determine which program that each key represents, click the key, and then view the following values in the details pane on the right:&lt;br /&gt;DisplayName: The value data for the DisplayName key is the name that is listed in Add or Remove Programs.&lt;br /&gt;&lt;br /&gt;-and-&lt;br /&gt;&lt;br /&gt;UninstallString: The value data for the UninstallString key is the program that is used to uninstall the program.&lt;br /&gt;&lt;br /&gt;7. After you identify the registry key that represents the program that you removed but which is still displayed in the Currently installed programs list of Add or Remove Programs, right-click the key in the left pane of the Registry Editor window, and then click Delete.&lt;br /&gt;&lt;br /&gt;Click Yes in response to the "Are you sure you want to delete this key and all of its subkeys?" message.&lt;br /&gt;&lt;br /&gt;8. On the File menu, click Exit to quit Registry Editor.&lt;br /&gt;&lt;br /&gt;9. Click Start, click Control Panel, and then click Add or Remove Programs.&lt;br /&gt;&lt;br /&gt;In the Currently installed programs list, verify that the program whose registry key you deleted is no longer listed.&lt;br /&gt;&lt;br /&gt;10. Do one of the following:• If the program list is not correct in Add or Remove Programs, double-click the Uninstall.reg file that you saved to your desktop in step 5 to restore the original list of programs in the registry.&lt;br /&gt;&lt;br /&gt;-or-&lt;br /&gt;&lt;br /&gt;If the program list is correct in Add or Remove Programs, right-click the Uninstall.reg file on your desktop, and then click Delete.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;an anonymous poster has an addition to my post:&lt;br /&gt;&lt;br /&gt;It's worth mentioning that this doesn't actually remove any of the files or reg keys the program created when it was installed, it just removes the 'record' Windows has which tells it the program has been installed.An alternate way to do this is to use msizap :&lt;a href="http://msdn.microsoft.com/library/default.asp"&gt;http://msdn.microsoft.com/library/default.asp&lt;/a&gt;?url=/library/en us/msi/setup/msizap_exe.asp&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114125501808051864?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114125501808051864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114125501808051864' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114125501808051864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114125501808051864'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/03/how-to-manually-remove-program-in.html' title='How to manually remove a program in windows XP'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114119628992317139</id><published>2006-02-28T22:54:00.000-08:00</published><updated>2006-11-12T15:27:41.716-08:00</updated><title type='text'>using pear cache_lite for high performance</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/pearsmall.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/6545/2077/320/pearsmall.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span name="intelliTxt" id="intelliTxt"&gt;&lt;span style="font-weight: bold;"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span name="intelliTxt" id="intelliTxt"&gt;&lt;span style="font-weight: bold;"&gt;What is cache lite?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Cache_lite is a php/pear caching module that is designed for high traffic sites.  It is different than most caching systems because it has a built-in locking mechanism that will prevent cache corruption that can sometimes occur when there are a large amount of concurrent users trying to read and write to your cached data.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How to use it&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here is a simple example on how to cache your data:&lt;br /&gt;&lt;br /&gt;//assign an id to the cache object&lt;br /&gt;$cacheid = '589';&lt;br /&gt;&lt;br /&gt;$cache_options = array(&lt;br /&gt;'cacheDir' =&amp;gt '/cachetmp',      //this is the temp directory of the cache files &lt;br /&gt;'lifeTime =&amp;gt 5000               //time, in seconds, of how long the cache will be valid&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span name="intelliTxt" id="intelliTxt"&gt;&lt;br /&gt;// Create a Cache_Lite object&lt;br /&gt;$Cache_object = new Cache_Lite($cache_options);&lt;br /&gt;&lt;br /&gt;// Test if thereis a valide cache for this id&lt;br /&gt;if ($data = $Cache_object-&amp;gtget($cacheid)) {&lt;br /&gt;&lt;br /&gt;// data is in our cache, access it through $data&lt;br /&gt;&lt;br /&gt;} else { // Not found in cache, it needs to be added&lt;br /&gt;&lt;br /&gt;$Cache_Lite-&amp;amp;gtsave($data);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Performance tip&lt;/span&gt;: Don't include every package your page needs.  Only &lt;/span&gt;&lt;span class="emphasis"&gt;&lt;/span&gt;load the modules     you need when the page is not in the cache.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;&amp;lt?php&lt;br /&gt;   require_once("Cache/Lite.php");&lt;br /&gt;     // (...)&lt;br /&gt;   $cache_object = new Cache_Lite();&lt;br /&gt;   if ($data = $cache_object-&amp;gtget($cache_id)) { // cache hit !&lt;br /&gt;       echo($data);&lt;br /&gt;   } else { // page has to be constructed&lt;br /&gt;       require_once("...")&lt;br /&gt;       require_once("...")&lt;br /&gt;       // (...)&lt;br /&gt;       $Cache_object-&amp;gtsave($data);&lt;br /&gt;   }&lt;br /&gt;?&amp;gt&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Downloading&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Cache_lite is part of the free pear package, which is a large repository of modules available &lt;a href="http://pear.php.net"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114119628992317139?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114119628992317139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114119628992317139' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114119628992317139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114119628992317139'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-pear-cachelite-for-high.html' title='using pear cache_lite for high performance'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114100450514720751</id><published>2006-02-26T17:40:00.000-08:00</published><updated>2006-05-12T00:56:07.976-07:00</updated><title type='text'>using paypal mass payment</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/paypal.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/paypal.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;br /&gt;&lt;br /&gt;Introduction&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;&lt;/strong&gt;Mass Payment allows anyone with a Premier or Business account to send multiple payments instantly—saving time, money and the hassle of having to individually send funds to every payment recipient.&lt;br /&gt;&lt;br /&gt;Click the links on the left of this page to learn more about Mass Payment.&lt;br /&gt;&lt;br /&gt;Mass Payment can be used for such things as:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Affiliate commissions&lt;/li&gt;&lt;li&gt;Customer rebates&lt;/li&gt;&lt;li&gt;Pay-to-surf rewards&lt;/li&gt;&lt;li&gt;Employee benefits&lt;/li&gt;&lt;li&gt;Lottery prizes&lt;/li&gt;&lt;li&gt;Survey incentives&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;File Format&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;You must create a tab-delimited file containing your recipients’ information to send a Mass Payment file. A tab-delimited file can be generated from most spreadsheet applications, such as Excel.&lt;br /&gt;&lt;br /&gt;Column 1: recipients’ email addresses.&lt;br /&gt;Column 2: the payment amounts for each recipient.&lt;br /&gt;Column 3: the three-letter currency code for the currency of the payment (only one currency type is allowed for each Mass Payment file):&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;EUR for Euro&lt;/li&gt;&lt;li&gt;USD for U.S. Dollar&lt;/li&gt;&lt;li&gt;GBP for Pound Sterling&lt;/li&gt;&lt;li&gt;CAD for Canadian Dollar&lt;/li&gt;&lt;li&gt;JPY for Yen&lt;/li&gt;&lt;li&gt;AUD for Australian Dollar&lt;/li&gt;&lt;/ul&gt;Column 4 (optional): a unique identifier for each customer for easier overall record-keeping. The unique identifier must be equal to or less than 30 characters, and must not contain any spaces. Examples of name format: Pitel, John; John_Pitel; JohnPitel.&lt;br /&gt;&lt;br /&gt;Column 5 (optional): customized notes about each customer.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How to export a table in comma delimited text format (using mysql):&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Here is an example on how to export your mysql tables in the above format:&lt;br /&gt;&lt;br /&gt;select field1,field2,'USD' from paypal_payments into outfile '$export_long_name' fields terminated by '\t' lines terminated by '\r\n'";&lt;br /&gt;&lt;br /&gt;in mysql, when you are selecting data from a table, if you add a string in quotes 'string', it will add on that string in a separate column for each record returned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114100450514720751?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114100450514720751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114100450514720751' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114100450514720751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114100450514720751'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-paypal-mass-payment.html' title='using paypal mass payment'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114100341596990727</id><published>2006-02-26T17:07:00.000-08:00</published><updated>2006-05-12T17:52:45.163-07:00</updated><title type='text'>File downloads in PHP</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This is a simple code snippet. It will allow you to force the web-browser that is currently viewing your script to come up with a file-download box (and the a file on your system can be downloaded).&lt;br /&gt;&lt;br /&gt;Here is the code:&lt;br /&gt;&lt;br /&gt; //so only the data from the headers is sent  &lt;br /&gt;ob_start(); &lt;br /&gt;//dispable caching&lt;br /&gt;header ("Cache-Control: must-revalidate, pre-check=0, post-check=0");  &lt;br /&gt;header ("Content-Type: application/binary");  &lt;br /&gt;header ("Content-Length: " . filesize($export_long_name));  &lt;br /&gt;header ("Content-Disposition: attachment; filename=yourfile.ext");  &lt;br /&gt;readfile($export_long_name);&lt;br /&gt;&lt;br /&gt;A list of of mime types can be found &lt;a href="http://www.ltsw.se/knbase/internet/mime.htp"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114100341596990727?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114100341596990727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114100341596990727' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114100341596990727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114100341596990727'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/file-downloads-in-php.html' title='File downloads in PHP'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114094500630623716</id><published>2006-02-26T01:06:00.000-08:00</published><updated>2006-02-26T01:10:06.320-08:00</updated><title type='text'>The history of Apple</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/mac128k320.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/mac128k320.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Here is an interesting article I found on the history of apple.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Before Apple&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;John Sculley's childhood was the antithesis of Steve Jobs'. His father was strict and had impossibly high standards for his son.&lt;br /&gt;&lt;br /&gt;Sculley attended St. Marks, an exclusive private boarding school made up of blue blooded Northeasterners. While there, he succeeded socially and academically, becoming the captain of the soccer team and earning impeccable grades at the same time.&lt;br /&gt;Being sociable was not easy for Sculley, however, and he feared it. He had to train himself to be sociable. He says in his autobiography, Odyssey, that he decided that he would overcome his stutter and become an inspiring speaker, and he did.&lt;br /&gt;&lt;br /&gt;To learn appropriate body language during speaking, he went to movie after movie, studying the actors' poses, committing them all to memory.&lt;br /&gt;&lt;br /&gt;It worked. Throughout his career, his speaking skill would be commended, though it was not perfect. He was nervous in crowds and recoiled at being touched. He often sat by himself in the Apple cafeteria eating his peanut butter sandwich until some merciful employee joined him.&lt;br /&gt;After St. Marks, Sculley studied at Wharton, and he eventually married the daughter of the chairman of PepsiCo, Don Kendall. The two soon divorced, though Sculley maintained a close relationship with his former father-in-law, who gave him a job managing PepsiCo's struggling Brazilian snack division, which soon became the most profitable division in the southern hemisphere...&lt;br /&gt;&lt;br /&gt;The rest can be found &lt;a href="http://lowendmac.com/orchard/06/0222.html"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114094500630623716?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114094500630623716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114094500630623716' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114094500630623716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114094500630623716'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/history-of-apple.html' title='The history of Apple'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114074617621604946</id><published>2006-02-23T17:51:00.000-08:00</published><updated>2006-04-06T22:03:51.060-07:00</updated><title type='text'>Bart's preinstalled Environment (PE)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/pebuilder.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/pebuilder.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;What is Bart's PE?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;PE Builder is not a Microsoft product and does not create Microsoft Windows Preinstallation Environment ("Windows PE"). Using PE Builder does not grant you a license to Microsoft Windows PE or to use the Windows XP or Server 2003 binaries in a manner other than stated in the End-User License Agreement included in your version of Microsoft Windows XP or Windows Server 2003. Microsoft has not reviewed or tested PE Builder and does not endorse its use.Please do not contact Microsoft for support on the preinstallation environment that has been created by PE Builder!Microsoft does not provide support for PE Builder or for the preinstallation environment created by PE Builder.The PE Builder program (pebuilder.exe) runs on Windows 2000/XP/2003/BartPE. It does not run on Windows NT4/ME/9x.To avoid any confusion, the bootable CD generated by PE Builder should be called by its nickname "BartPE"! &lt;h3&gt;Differences between BartPE and Windows PE&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Target - Microsoft sees Windows PE as an installation platform. Bart sees Windows PE as the next generation rescue platform. &lt;/li&gt;&lt;li&gt;Start-menu - Bart's builder gives you a simple, dynamic and powerful start-menu (Nu2Menu, see &lt;a title="/pebuilder/screenshots" href="/pebuilder/screenshots"&gt;screenshots&lt;/a&gt;). Microsoft's builder does not give you a start-menu, it uses a command prompt. &lt;/li&gt;&lt;li&gt;Build from - Bart's builder can also build from Windows XP Home Edition or from a preinstalled Windows XP version (without CD). &lt;/li&gt;&lt;li&gt;Plugins - With PE Builder you can easily add applications, drivers or tools using plugins. This makes PE Builder extremely powerful. The end user can even combine plugins from different software vendors into one CD image.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Network support - PE Builder includes its own network support tools (bartpe/penetcfg) to start TCP/IP and Microsoft Client. The TCP/IP settings like: dynamic/static ip-address, subnet-mask, default gateway, dns-servers computer-name, workgroup can be changed on-the-fly. You can create pre-defined profiles, that you can select. Microsoft Windows PE only supports DHCP or fixed settings using winbom.ini.&lt;br /&gt;Also there is a plugin (NwDskPe) created by Erwin Veermans that loads the Netware Client on BartPE (IP/IPX). &lt;/li&gt;&lt;li&gt;Fileshare - BartPE can start File Sharing support so you can connect to the system through a share. &lt;/li&gt;&lt;li&gt;VNC - Because of the File Sharing support you can also run UltraVNC. &lt;/li&gt;&lt;li&gt;Dos support - Bart's builder has a plugin called "dospe". &lt;/li&gt;&lt;li&gt;License - Microsoft Windows PE is only for Enterprise/OEM customers (see previous), BartPE is for everybody! &lt;/li&gt;&lt;li&gt;64-Bit - Bart's builder does not support Windows 64-bit editions. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The files from your Windows Installation CD-Rom.Supported Windows versions are:&lt;br /&gt;Windows XP Home Edition (must be slip streamed with Service Pack 1 or higher)&lt;br /&gt;Windows XP Professional (must be slip streamed with Service Pack 1 or higher)&lt;br /&gt;Windows Server 2003, Web Edition&lt;br /&gt;Windows Server 2003, Standard Edition&lt;br /&gt;Windows Server 2003, Enterprise Edition&lt;br /&gt;PE Builder runs on Windows 2000/XP/2003/BartPE systems.&lt;br /&gt;CD/DVD writer if you want to creat a bootable CD/DVD.&lt;br /&gt;&lt;br /&gt;The Download is available &lt;a href="http://www.nu2.nu/pebuilder/"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another great project based on barts PE called the Ultimate Boot CD can be found &lt;a href="http://www.ubcd4win.com"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114074617621604946?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114074617621604946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114074617621604946' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114074617621604946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114074617621604946'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/barts-preinstalled-environment-pe.html' title='Bart&apos;s preinstalled Environment (PE)'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114072794927288452</id><published>2006-02-23T12:51:00.000-08:00</published><updated>2006-02-23T16:11:44.720-08:00</updated><title type='text'>using vmware for development</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/vmware.0.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; CURSOR: pointer" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/vmware.0.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As a programmer, I often times need to develop or test my work on multiple operating systems such as linux, freebsd, and various versions of windows. Rather than keep separate boxes around for each operating system, I run windows 2003 standard edition as my base OS and a vmware session for each separate OS.&lt;br /&gt;&lt;br /&gt;My current hardware is : amd64 with an 80 gig harddrive/1 gig of Ram. Any OS that I have tried runs very fast, with almost no noticable difference from a regular installation.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;One quick tip&lt;/strong&gt;: install the Vmware tools. This will improve performance significantly.&lt;br /&gt;&lt;br /&gt;One of the most interesting features of Vmware is the fact that it has bridged networking. This allows your sessions to each have their own separate IP addresses on your network. This can really come in handy if you want to test out a new server on linux or an apache installation.&lt;br /&gt;&lt;br /&gt;Beyond development, vmware can also be used to surf the Internet without having to worry about your computer getting infected with spyware. This may be overkill, but it just might save you from having to re-install your entire OS because of an insecure browser.&lt;br /&gt;&lt;br /&gt;Vmware has a free verson available for both windows and linux. It is in beta, but it still works very well for most people's needs.&lt;br /&gt;&lt;br /&gt;Both can be downloaded &lt;a href="http://www.vmware.com/products/gsx/"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114072794927288452?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114072794927288452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114072794927288452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114072794927288452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114072794927288452'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-vmware-for-development.html' title='using vmware for development'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114067259932990732</id><published>2006-02-22T21:29:00.000-08:00</published><updated>2006-06-14T15:47:29.133-07:00</updated><title type='text'>using sql relay</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/sqlrelay.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/6545/2077/320/sqlrelay.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;By Justin Silverton    &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What is SQL relay?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; SQL Relay is a persistent database connection pooling, proxying and load  balancing system for Unix and Linux supporting ODBC, Oracle, MySQL, mSQL,  PostgreSQL, Sybase, MS SQL Server, IBM DB2, Interbase, SQLite and MS Access (minimally) with APIs for C, C++, Perl, Perl-DBD, Python, Python-DB, Zope, PHP, Ruby, Ruby-DBD, Java and TCL, drop-in replacement libraries for MySQL and PostgreSQL clients, command line clients, a GUI configuration tool and extensive documentation.  The APIs support advanced database operations such as bind variables, multi-row fetches, client-side result set caching and suspended transactions.  It is ideal for speeding up database-driven web-based applications, accessing databases from unsupported platforms, migrating between databases, distributing access to replicated databases and throttling database access.&lt;br /&gt;&lt;p&gt;SQL Relay is ideal for:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;speeding up database-driven web-based applications &lt;/li&gt;&lt;li&gt;enhancing the scalability of database-driven web-based applications &lt;/li&gt;&lt;li&gt;distributing access to replicated databases &lt;/li&gt;&lt;li&gt;throttling database access &lt;/li&gt;&lt;li&gt;accessing databases from unsupported platforms &lt;/li&gt;&lt;li&gt;migrating applications from one database to another &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;SQL Relay supports the following database backends:&lt;/p&gt; &lt;table&gt; &lt;tbody&gt;&lt;tr&gt; &lt;td valign="top"&gt; &lt;ul&gt;&lt;li&gt;Oracle&lt;/li&gt;&lt;li&gt;MySQL&lt;/li&gt;&lt;li&gt;mSQL&lt;/li&gt;&lt;li&gt;PostgreSQL&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;td valign="top"&gt; &lt;ul&gt;&lt;li&gt;Sybase&lt;/li&gt;&lt;li&gt;MS SQL Server&lt;/li&gt;&lt;li&gt;IBM DB2&lt;/li&gt;&lt;li&gt;Interbase&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;td valign="top"&gt; &lt;ul&gt;&lt;li&gt;Sybase&lt;/li&gt;&lt;li&gt;SQLite&lt;/li&gt;&lt;li&gt;ODBC&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;td valign="top"&gt; &lt;ul&gt;&lt;li&gt;MS Access&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;The SQL Relay client API's support advanced database operations such as bind variables, multi-row fetches, client-side result set caching and suspended transactions.  SQL Relay has native client API's for the following languages: &lt;/p&gt;   &lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt; &lt;ul&gt;&lt;li&gt;C&lt;/li&gt;&lt;li&gt;C++&lt;/li&gt;&lt;li&gt;Perl&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;td&gt; &lt;ul&gt;&lt;li&gt;Python&lt;/li&gt;&lt;li&gt;PHP&lt;/li&gt;&lt;li&gt;Ruby&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;td&gt; &lt;ul&gt;&lt;li&gt;Java&lt;/li&gt;&lt;li&gt;TCL&lt;/li&gt;&lt;li&gt;Zope&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;span style="font-weight: bold;" class="heading3"&gt;How does SQL Relay work?&lt;/span&gt;  &lt;p&gt;SQL Relay's connection daemons log into and maintain sessions with  databases.  These connection daemons advertise themselves with a listener  daemon which listens on an inet and/or unix port for client connections. When a client connects to the listener, if a connection daemon is available,  the listener hands off the client to that connection.  If no connection daemon is available, the client must wait in queue until one is.  Once a client is handed off to a connection daemon, the client communicates to the database  through the session maintained by that daemon.&lt;/p&gt;&lt;span style="font-weight: bold;" class="heading3"&gt;How can SQL Relay improve the efficiency of my  website?&lt;/span&gt;&lt;p style="font-weight: bold;"&gt;  &lt;/p&gt;&lt;p&gt;Here are some examples of how SQL Relay can improve the efficiency  of your web site.&lt;/p&gt;  &lt;p&gt;Let's say you're running CGI's againt a transactional database such as  PostgreSQL, MS SQL Server or Oracle.  CGI's have to log into and out of the  database each time they run.  If you use SQL Relay to maintain  persistent connections to the database and just log into and out of  SQL Relay, you can reduce the amount of time wasted establishing  database connections and handle more CGI requests per-second.  This is both because the time-cost of connecting to SQL Relay is smaller than the time-cost of connecting to a transactional database, and because the  SQL Relay client library is smaller than most database client  libraries, resulting in a more lightweight CGI.&lt;/p&gt;  &lt;p&gt;Let's say you're using Apache, PHP and Oracle and you determine by doing all sorts of analysis that you need to keep 30 Apache processes running to provide adequate response.  Since most of your site isn't database-driven, on average, no more than 5 PHP's actually access the database simultaneously. Currently, you're using persistent connections to defeat the time-cost of  logging into Oracle, but you have to maintain 30 connections (1 per web server process) which takes up a lot of memory on both the web server and database  server and you really only need 5 connections. By using SQL Relay you can  reduce the number of Oracle connections to the 5 that you need, continue to  run 30 Apache processes and reclaim the wasted memory on both machines.&lt;/p&gt;  &lt;p&gt;Many websites run a combination of PHP's and Perl modules.  Perl modules can use Apache::DBI and PHP's have a persistent database connection system, but a  PHP cannot use an Apache::DBI connection and a Perl module cannot use a PHP  persistent connection.  Thus in order to make sure that there are enough  database connections for each platform, many more web-server processes have to be run, perhaps twice as many.  If the PHP's and Perl modules used SQL Relay instead, they could share databse connections and reduce the number of web-server processes and database connections.&lt;/p&gt;  &lt;p&gt;SQL Relay makes it easy to distribute load over replicated servers.  A  common scaling solution when using MySQL or PostgreSQL in a read-only web  environment is to run several web servers with a dedicated database server for each web server or group of web servers and update all the databases  simultaneously at scheduled intervals.  This usually works pretty well, but sometimes database or web servers get runs of heavy load while others are idle.  In other cases, an uneven number of machines is required.  For  example, your application may need 3 web servers but only 2 database servers  or vice-versa.  People usually just by 3 of each, wasting money.  Moreover, in  most cases, the servers have to be equivalently powerful machines.  You can't usually just add another cheap machine that you have lying around into the  pool.   SQL Relay can connect to multiple, replicated or clustered database servers, providing web-based applications access to whichever server isn't  busy.  SQL Relay can also be configured to maintain more connections to more powerful machines and fewer connections to less powerful machines, enabling unevenly matched machines to be used in the same database pool.  Collectively, these features allow you to save money by using only the exact number of servers that you need and by enabling you to use spare hardware in your  database pools.&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Where can I get it?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;SQL relay can be downloaded &lt;A HREF="http://sqlrelay.sourceforge.net"&gt; Here&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114067259932990732?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114067259932990732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114067259932990732' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114067259932990732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114067259932990732'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-sql-relay.html' title='using sql relay'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114059770495815645</id><published>2006-02-22T00:33:00.000-08:00</published><updated>2006-02-22T10:37:14.880-08:00</updated><title type='text'>why use php5?</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;New Object-orientated features&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="bodycopy"&gt;In the previous versions of PHP, objects and classes were supported, but only on a limited basis. Missing was the ability to de-reference objects that are returned from a method and implicit object cloning resulted in unexpected behavior.&lt;br /&gt;&lt;br /&gt;The following are new features within php5&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="bodycopy"&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="boldbodycopy2"&gt;A) Public, private, protected class modifiers&lt;/span&gt;&lt;span class="bodycopy"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="bodycopy"&gt;These modifiers may be used on both properties and methods, and restrict access.&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span class="boldbodycopy2"&gt;B) Interfaces and abstract classes and methods.&lt;/span&gt;&lt;span class="bodycopy"&gt; &lt;/span&gt;&lt;span class="boldbodycopy2" style="FONT-STYLE: italic"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="boldbodycopy2"&gt;C) Object cloning&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;span class="bodycopy"&gt;&lt;/span&gt;&lt;p&gt;&lt;span class="bodycopy"&gt;The scripting engine never automatically clones objects in PHP 5, whether they are assigned, passed by-value, or returned by-value. If you do need to clone an object, then you can use the following syntax: "clone $newobject" or a method called __clone() can be implemented, which will be called after an object's properties has been cloned.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span class="boldbodycopy2"&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;span class="boldbodycopy2"&gt;&lt;br /&gt;D) Design Patterns&lt;/span&gt;&lt;span class="bodycopy"&gt;&lt;br /&gt;&lt;br /&gt;Supported in PHP 4, but now has new and improved features such as static properties and methods, private/public/protected modifiers, and interfaces.&lt;br /&gt;&lt;br /&gt;E) XML and Soap&lt;br /&gt;&lt;br /&gt;The soap protocol is becoming increasingly popular for communicating with web services. Many companies are implementing it to allow for easy access to data.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Improved mysql functionality&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;A new library, called mysqli, offers the following improvements over the old library:&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;A) SSL connectivity&lt;br /&gt;B) prepared statements&lt;br /&gt;C) Bound Input and Out parameters&lt;br /&gt;D) Object orientated interface&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="bodycopy"&gt;&lt;a href="http://www.zend.com/manual/migration5.functions.php"&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="bodycopy"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Exception Handling&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&lt;span class="bodycopy"&gt;Exceptions allow you to have a greater degree of control over error handling, by separating the program logic. You no longer have to check the return value from a function.&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="bodycopy"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="bodycopy"&gt;Complete function list can be found &lt;a href="http://www.zend.com/manual/migration5.functions.php"&gt;here&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114059770495815645?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114059770495815645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114059770495815645' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114059770495815645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114059770495815645'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/why-use-php5.html' title='why use php5?'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114046705931389657</id><published>2006-02-20T12:22:00.000-08:00</published><updated>2006-06-14T17:14:19.026-07:00</updated><title type='text'>another article on oracle/mysql</title><content type='html'>&lt;em&gt;"In November, I looked at &lt;/em&gt;&lt;a href="http://www.databasejournal.com/features/mysql/article.php/3561731"&gt;&lt;em&gt;Oracle's purchase of InnoDB&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, as well as their release of Oracle Express, and the effect on MySQL. In short, I concluded that the positives for Oracle were clear, but that MySQL must be feeling outmaneuvered. Since InnoDB, with its full transactional capability, has become an integral part of their product offering, I suggested that both BerkleyDB (their first transactional storage engine, but which has never got beyond so-called gamma status) and MaxDB (what was SAPDB, which is a fully-featured database but does not yet integrate well with MySQL's other products) had both become critically important.&lt;br /&gt;Shortly after Oracle purchased InnoDB, MySQL vice-president Richard Mason acknowledged that MySQL were "evaluating options to replace that functionality in some way," but that they were "not at the point yet where we can go public with what that plan is but we will be shortly."&lt;br /&gt;However, since then Oracle has upped the ante even more. On February 14th, Oracle purchased Sleepycat Software, who provides MySQL with the Berkeley DB transactional storage engine. Furthermore, in the last few days, rumors have been flying that Oracle also intends to purchase both Zend ('the PHP Company'), as well as JBoss. I believe this is another smart series of moves by Oracle that can only benefit them......"&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;The rest can be found &lt;a href="http://www.databasejournal.com/features/mysql/article.php/3585266"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;/em&gt;&lt;em&gt;&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114046705931389657?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114046705931389657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114046705931389657' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114046705931389657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114046705931389657'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/another-article-on-oraclemysql.html' title='another article on oracle/mysql'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-114042165225789859</id><published>2006-02-19T23:38:00.000-08:00</published><updated>2006-02-23T06:58:15.010-08:00</updated><title type='text'>Oracle and open source</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the past year or so, Oracle has recently started purchasing/bidding on open source companies/products:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.networkworld.com/news/2006/021406-oracle-sleepycat-open-source.html"&gt;Oracle buys sleepycat software&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-STYLE: italic"&gt;excerpt&lt;/span&gt;: "Sleepycat's Berkeley DB is embedded in several well-known open source products, including the Linux and BSD Unix operating systems, Apache Web server, OpenLDAP directory and OpenOffice productivity suite, Oracle said Tuesday"&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.oracle.com/corporate/press/2005_oct/inno.html"&gt;Oracle buys innobase&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-STYLE: italic"&gt;excerpt&lt;/span&gt;: "&lt;span class="bodycopy"&gt;Innobase is the developer of discrete transactional database technology, InnoDB, that is distributed under an open source license. "Oracle has long been a supporter of open source software such as Linux and Apache," said Charles Rozwat, Oracle's Executive Vice President in charge of Database and Middleware Technology. "Innobase is an innovative small company that develops open source database technology. Oracle intends to continue developing the InnoDB technology and expand our commitment to open source software. Oracle has already developed and contributed an open source clustered file system to Linux. We expect to make additional contributions in the future."&lt;/span&gt; &lt;p&gt;&lt;span class="bodycopy"&gt;InnoDB is not a standalone database product: it is distributed as a part of the MySQL database. InnoDB's contractual relationship with MySQL comes up for renewal next year. Oracle fully expects to negotiate an extension of that relationship."&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href="http://news.com.com/Oracle+tried+to+buy+open-source+MySQL/2100-7344_3-6040197.html?tag=nefd.lede"&gt;Oracle bids on mysql&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-STYLE: italic"&gt;excerpt&lt;/span&gt;: "MySQL, based in Sweden and Cupertino, Calif., announced in January that it's been profitable for two quarters. But it's not turning down outside money. &lt;a title="MySQL lands $18.5 million in third round -- Monday, Feb 13, 2006" href="http://news.com.com/MySQL+lands+18.5+million+in+third+round/2110-7344_3-6038761.html?tag=nl"&gt;MySQL announced Monday it raised $18.5 million&lt;/a&gt; in a third round of funding from Institutional Venture Partners, Intel Capital, Red Hat, SAP Ventures and Sumitomo's Presidio STX investment subsidiary. &lt;p&gt;Oracle's financial moves, however, are orders of magnitude grander. Its major buying spree resulted in the acquisitions of Siebel Systems for $5.8 billion and PeopleSoft for $10.3 billion."&lt;/p&gt;&lt;p&gt;&lt;span style="FONT-WEIGHT: bold"&gt;What does this mean for open source?&lt;/span&gt;&lt;/p&gt;Open source is starting to become a real threat to the commercial application companies of the world. Applications such as apache, mysql, postgres, and linux are gaining momentum and are becoming better and than than their commerical counterparts.&lt;br /&gt;&lt;br /&gt;How can a company defend against the power of the community? The greatest strength of open source is the fact that it can't be bought or sold as a whole. Even if a new, closed source and proprietary version comes out of a project, the community can still continue developing the open sourced version.&lt;br /&gt;&lt;br /&gt;a representitive from Oracle stated the following in a press release :&lt;br /&gt;&lt;br /&gt;"i&lt;span class="bodycopy"&gt;nnoDB is not a standalone database product: it is distributed as a part of the MySQL database. InnoDB's contractual relationship with MySQL comes up for renewal next year. Oracle fully expects to negotiate an extension of that relationship."&lt;br /&gt;&lt;br /&gt;Oracle is a business with their stock holders as their main objective. Purchasing innobase, which is an integral part of the mysql database system, is the first step in taking it over. It seems okay right now, but if they start losing martketshare, there is no telling what they might do.&lt;br /&gt;&lt;br /&gt;Another weapon large companies have against OSS is money and resources. This means they have the ability to hire the top developers of a project and basically take it off the map for awhile as a competitor.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;recently, Microsoft did something like this and it &lt;a href="http://news.zdnet.co.uk/software/linuxunix/0,39020390,39252292,00.htm"&gt;backfired&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-114042165225789859?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/114042165225789859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=114042165225789859' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114042165225789859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/114042165225789859'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/oracle-and-open-source.html' title='Oracle and open source'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113924171936132965</id><published>2006-02-19T14:26:00.000-08:00</published><updated>2006-02-19T11:31:05.386-08:00</updated><title type='text'>using PHP in large websites - redone</title><content type='html'>&lt;strong&gt;by Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This was originally an article by Aaron Crane, but because of overwhelming amount of inaacurate and outdated information, I have decided to write a new and up-to-date article.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The following methods can help improve scalability with php applications.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1) object code caching&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Each time a request comes to your server for a php script, it has to go through the compiler and then execute the object code. If this is cached, the 1st step is skipped and you end up with a faster and more responsive script.&lt;br /&gt;&lt;br /&gt;There are many object code caching packages available on the Internet (some free, some commercial):&lt;br /&gt;&lt;br /&gt;&lt;table border="1" spacing="2"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;A) Ioncube&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.ioncube.com/"&gt;http://www.ioncube.com/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;B) Zend Encoder&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.zend.com/products/zend_safeguard"&gt;http://www.zend.com/products/zend_safeguard&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;C) Turckl MMCache&lt;/td&gt;&lt;td&gt;&lt;a href="http://freshmeat.net/projects/turck-mmcache/"&gt;http://freshmeat.net/projects/turck-mmcache/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2) Template systems&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Template systems provide a different type of caching. Content caching. Template systems work well in a situation where there is static data on one or many of your pages that doesn't have to be reloaded. Caching systems also provide a separation of code and html, which will not only improve completion time of the overall project, but make it easier for future improvments. Most template systems for php are available for free:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;table border="1" spacing="2"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;A) Smarty Templates&lt;/td&gt;&lt;td&gt;&lt;a href="http://smarty.php.net/"&gt;http://smarty.php.net/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;B) Pear Templates&lt;/td&gt;&lt;td&gt;&lt;a href="http://pear.php.net/package/html_template_it/redirected"&gt;http://pear.php.net/package/html_template_it/redirected&lt;/a&gt;&lt;a href="http://www.zend.com/products/zend_safeguard"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;C) PHP savant&lt;/td&gt;&lt;td&gt;&lt;a href="http://phpsavant.com/yawiki/"&gt;http://phpsavant.com/yawiki/&lt;/a&gt;&lt;a href="http://freshmeat.net/projects/turck-mmcache/"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3) Distributed object caching systems&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The most widely used system of this type is memcached (&lt;a href="http://www.danga.com/memcached/"&gt;http://www.danga.com/memcached/&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;This type of system makes your overall site faster by caching the majority of your database data into a large memory pool.&lt;/p&gt;&lt;p&gt;an interesting excerpt from their site: &lt;/p&gt;&lt;p&gt;"&lt;a href="http://www.danga.com/"&gt;Danga Interactive&lt;/a&gt; developed memcached to enhance the speed of &lt;a href="http://www.livejournal.com/"&gt;LiveJournal.com&lt;/a&gt;, a site which was already doing 20 million+ dynamic page views per day for 1 million users with a bunch of webservers and a bunch of database servers. memcached dropped the database load to almost nothing, yielding faster page load times for users, better resource utilization, and faster access to the databases on a memcache miss."&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4) PHP variables that can be set&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;variables_order = 'GPC'&lt;br /&gt;register_argc_argv = 'Off'&lt;br /&gt;register_globals = 'Off' (this is a good idea to keep off for security purposes as well)&lt;br /&gt;always_populate_raw_post_data = 'Off'&lt;br /&gt;magic_quotes_gpc = 'Off'&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Disable Error Logging&lt;/em&gt;. This is a good idea to keep on when you are developing your scripts, but it has been known to decrease overall performance.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Use IP address to access your database. &lt;/em&gt;Although this is sometimes not possible, you will get a slight boost in lookup speed if the IP address is used to access your database rather than its hostname.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5) Output Compression&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Almost all browsers these days support something called gzip compression. Gzip compression can decrease the overall size of your output by up to 80%, but with a tradeoff: cpu usage will go up by around 10%. The benefit of using this compression type is the fact that not only will your bandwidth be decreased, but your pages will load faster.&lt;/p&gt;&lt;p&gt;&lt;em&gt;enabling it in php (add the following lines to php.ini):&lt;/em&gt;&lt;/p&gt;&lt;p&gt;zlib.output_compression = On&lt;br /&gt;zlib.output_compression_level = (level) (where level is 1-9. Youy may want to try different values to see what is best for your system).&lt;/p&gt;&lt;p&gt;if you are using apache, you can also enable the mod_gzip module. It is highly configurable, with the ability to modify output based on MIME types, files, or browser settings.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;6) Other things that may help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;when using a database, only retrieve the data that you are actually going to use&lt;/em&gt;. This may sound like a no-brainer, but I have often times worked on projects where the original programmer used (select * from mytable) when they could have used (select fieldIneed from mytable).&lt;/p&gt;&lt;p&gt;&lt;em&gt;index database tables whenever possible&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Learn more about this &lt;a href="http://www.websitedatabases.com/database-index.html"&gt;Here&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;specific language tricks&lt;/em&gt;&lt;/p&gt;&lt;p&gt;An interesting blog article I found mentions many interesting tricks that can be used: &lt;a href="http://ilia.ws/archives/12-PHP-Optimization-Tricks.html"&gt;http://ilia.ws/archives/12-PHP-Optimization-Tricks.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;an article on zend.com about measuring performance: &lt;a href="http://www.zend.com/zend/trick/trick-optimizing-php.php"&gt;http://www.zend.com/zend/trick/trick-optimizing-php.php&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113924171936132965?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113924171936132965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113924171936132965' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113924171936132965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113924171936132965'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-php-in-large-websites-redone.html' title='using PHP in large websites - redone'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113990252687818049</id><published>2006-02-13T23:32:00.000-08:00</published><updated>2006-05-07T01:15:26.016-07:00</updated><title type='text'>Using the iis 6 ftp service</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/ftp-server.gif"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/ftp-server.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Install Internet Information Services and the FTP Service&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Because FTP depends on Microsoft Internet Information Services (IIS), IIS and the FTP Service must be installed on the computer. To install IIS and the FTP Service, follow these steps.&lt;br /&gt;&lt;br /&gt;NOTE: In Windows Server 2003, the FTP Service is not installed by default when you install IIS. If you already installed IIS on the computer, you must use the Add or Remove Programs tool in Control Panel to install the FTP Service.&lt;br /&gt;&lt;br /&gt;1. Click Start, point to Control Panel, and then click Add or Remove Programs.&lt;br /&gt;2. Click Add/Remove Windows Components.&lt;br /&gt;3. In the Components list, click Application Server, click Internet Information Services (IIS) (but do not select or clear the check box), and then click Details.&lt;br /&gt;4. Click to select the following check boxes (if they are not already selected):&lt;br /&gt;Common Files&lt;br /&gt;File Transfer Protocol (FTP) Service&lt;br /&gt;Internet Information Services Manager&lt;br /&gt;5. Click to select the check boxes next to any other IIS-related service or subcomponent that you want to install, and then click OK.&lt;br /&gt;6. Click Next.&lt;br /&gt;7. When you are prompted, insert the Windows Server 2003 CD-ROM into the computer's CD-ROM or DVD-ROM drive or provide a path to the location of the files, and then click OK.&lt;br /&gt;8. Click Finish.&lt;br /&gt;IIS and the FTP service are now installed. You must configure the FTP Service before you can use it.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Configure The FTP Service&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;To configure the FTP Service to allow only anonymous connections, follow these steps: 1. Start Internet Information Services Manager or open the IIS snap-in.&lt;br /&gt;2. Expand Server_name, where Server_name is the name of the server.&lt;br /&gt;3. Expand FTP Sites&lt;br /&gt;4. Right-click Default FTP Site, and then click Properties.&lt;br /&gt;5. Click the Security Accounts tab.&lt;br /&gt;6. Click to select the Allow Anonymous Connections check box (if it is not already selected), and then click to select the Allow only anonymous connections check box.&lt;br /&gt;&lt;br /&gt;When you click to select the Allow only anonymous connections check box, you configure the FTP Service to allow only anonymous connections. Users cannot log on by using user names and passwords.&lt;br /&gt;7. Click the Home Directory tab.&lt;br /&gt;8. Click to select the Read and Log visits check boxes (if they are not already selected), and then click to clear the Write check box (if it is not already cleared).&lt;br /&gt;9. Click OK.&lt;br /&gt;10. Quit Internet Information Services Manager or close the IIS snap-in.&lt;br /&gt;The FTP server is now configured to accept incoming FTP requests. Copy or move the files that you want to make available to the FTP publishing folder for access. The default folder is drive:\Inetpub\Ftproot, where drive is the drive on which IIS is installed.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;adding a virtual directory&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;This is probably one of the most confusing issues with the IIS ftp service. To create a virtual directory, do the following:&lt;br /&gt;&lt;br /&gt;1) right click your new ftp server that you created from above (in iis manager) and go to new-&gt;virtual directory.&lt;br /&gt;2) it will ask you for the alias (how people will access this directory and the location (which is the actual physical directory on your harddrive).&lt;br /&gt;3) after this is created, you may try to login to your ftp server and see if your directories are listed. They won't be there.&lt;br /&gt;4) Most FTP server use the actual file structure of your system to determine what directories to display to the user.&lt;br /&gt;&lt;br /&gt;To allow your virtual directories to be seen, go into the home directory of your ftp site and create an empty directory with same name as your virtual one (the alias).&lt;br /&gt;&lt;br /&gt;This works virtual directories take precidence over file-system directories.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113990252687818049?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113990252687818049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113990252687818049' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113990252687818049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113990252687818049'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-iis-6-ftp-service.html' title='Using the iis 6 ftp service'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113989690344450962</id><published>2006-02-13T21:52:00.000-08:00</published><updated>2006-02-14T08:57:22.966-08:00</updated><title type='text'>using php and smarty templates</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;By Justin Silverton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Why use smarty templates?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;One of Smartys primary design goals is to facilitate the separation of application code from presentation. Typically, the application code contains the business logic of your application, written and maintained in PHP code. This code is maintained by programmers. The presentation is the way your content is presented to the end user, which is written and maintained in template files. The templates are maintained by template designers. &lt;/p&gt;&lt;p&gt;At its most basic function, the application code collects content, assigns it to the template engine and displays it. The content might be something like the headline, tagline, author and body of a newspaper article. The application code has no concern how this content will be presented in the template. The template designer is responsible for the presentation. They edit the template files, adding markup and bringing it to completion. This typically involves things like HTML tags, cascading style sheets and other tools provided by the template engine. &lt;/p&gt;&lt;p&gt;This paradigm serves several purposes: &lt;/p&gt;&lt;p&gt;*) Designers can't break application code. They can mess with the templates all they want, but the code stays intact. The code will be tighter, more secure and easier to maintain. &lt;/p&gt;&lt;p&gt;*) Errors in the templates are confined to the Smartys error handling routines, making them as simple and intuitive as possible for the designer. &lt;/p&gt;&lt;p&gt;*) With presentation on its own layer, designers can modify or completely redesign it from scratch, all without intervention from the programmer. &lt;/p&gt;&lt;p&gt;*) Programmers aren't messing with templates. They can go about maintaining the application code, changing the way content is acquired, making new business rules, etc. without disturbing the presentation layer. &lt;/p&gt;&lt;p&gt;*) Templates are a close representation of what the final output will be, which is an intuitive approach. Designers don't care &lt;i&gt;how&lt;/i&gt; the content got to the template. If you have extraneous data in the template such as an SQL statement, this opens the risk of breaking application code by accidental deletion or alteration by the designer. &lt;/p&gt;&lt;p&gt;*) You are not opening your server to the execution of arbitrary PHP code. Smarty has many security features built in so designers won't breach security, whether intentional or accidental. They can only do what they are confined to in the templates. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Although application code is separated from presentation, this does not necessarily mean that &lt;i&gt;logic&lt;/i&gt; is separated. The application code obviously has logic, but the templates may have logic based on the condition that it is for presentation &lt;i&gt;only&lt;/i&gt;. For example, if the designer wants to alternate table row colors or upper-case some assigned content, they can. This is presentation logic, something the programmer should not be concerned with. How often have you had some presentation displayed in a single column and then you wanted it in two or three columns, so the application code needs adjusting to accomodate this? A better approach is to assign the content in one single array and let the template handle the presentation. This will simplify your application and keep your templates flexible. Smarty supplies the tools to handle this kind of situation.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Getting Started&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold"&gt;with smarty&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;The first step is to download the smarty template engine &lt;a href="http://smarty.php.net/download.php"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;1. copy the following to a new file named "smartywrapper.php&lt;br /&gt;&lt;br /&gt;// require the Smarty class&lt;br /&gt;require_once('Smarty.class.php');&lt;br /&gt;&lt;br /&gt;// extend the Smarty class&lt;br /&gt;class smartywrapper extends Smarty {&lt;br /&gt;&lt;br /&gt;//this will only work with php 5.X&lt;br /&gt;function &lt;span class="keyword"&gt;function &lt;/span&gt;&lt;span class="default"&gt;__construct&lt;/span&gt;&lt;span class="keyword"&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// create the Smarty object&lt;br /&gt;$this-&gt;Smarty();&lt;br /&gt;&lt;br /&gt;// make sure these folders exist and the permissions are set accordingly&lt;br /&gt;$this-&gt;template_dir = '/www/example.com/webapp/template/';&lt;br /&gt;$this-&gt;compile_dir = '/www/example.com/webapp/compile/';&lt;br /&gt;$this-&gt;config_dir = '/www/example.com/webapp/config/';&lt;br /&gt;$this-&gt;cache_dir = '/www/example.com/webapp/cache/';&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;2. copy the following to a file named "smartytest.php"&lt;br /&gt;&lt;br /&gt;// require the new wrapper class we just created from above&lt;br /&gt;require_once('smartywrapper.php');&lt;br /&gt;&lt;br /&gt;// create the Smarty_WebApp object&lt;br /&gt;$smarty = new smartywrapper();&lt;br /&gt;&lt;br /&gt;// assign a variable, first parameter is the var name, second is the value&lt;br /&gt;$smarty-&gt;assign('test_var_1','this is a test');&lt;br /&gt;&lt;br /&gt;//display the template file (all html can now be placed here instead of in your php files)&lt;br /&gt;$smarty-&gt;display('my_template.tpl');&lt;br /&gt;&lt;br /&gt;create a file called my_template.tpl and place it in the directory in $this-&gt;template_dir = '/www/example.com/webapp/template/'; from above:&lt;br /&gt;&lt;br /&gt;This is a test page from smarty, my variable is: {$test_var_1}&lt;br /&gt;&lt;br /&gt;launch smartytest.php from you webbrowser and if it is successful, you should see the following&lt;br /&gt;&lt;br /&gt;output:&lt;br /&gt;&lt;br /&gt;This is a test page from smarty, my variable is: this is a test&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Smarty templates can not only be used to increase the overall speed of your php scripts through caching (more about caching can be found &lt;a href="http://smarty.php.net/manual/en/caching.php"&gt;Here&lt;/a&gt;), but make it easier to develop large-scale applications through the separation of HTML code and php script.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113989690344450962?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113989690344450962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113989690344450962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113989690344450962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113989690344450962'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-php-and-smarty-templates.html' title='using php and smarty templates'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113989320673036449</id><published>2006-02-13T20:51:00.000-08:00</published><updated>2006-02-13T21:36:47.610-08:00</updated><title type='text'>php 5.0 and iis -  authentication issues</title><content type='html'>&lt;strong&gt;by Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I installed php 5.0/iis 6 (the isapi dll manually) today on one of my new development servers, following the directions from the install.txt (and using the steps that I wrote about in a previous article).  After I created a test php file and attempted to launch it from a web-browser, I was shown a username and password box.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;img src="http://home.blazesupport.com/phpauth.jpg" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;if you are getting the message box above, it is most likely a permission problem.&lt;br /&gt;&lt;br /&gt;The following can be done to fix it:&lt;br /&gt;&lt;br /&gt;1) make sure the path has c:\php (where your php is installed)&lt;br /&gt; -this can be done by going to start-&gt;settings-&gt;control panel-&gt;system, then clicking on the advanced tab, and finally clicking on "environment variables".  The path variable is located within the second box on the page.&lt;br /&gt;&lt;br /&gt;2) the following files need to have their permissions set to read by the user account  IIS uses to launch files (typically IUSR_(your server name):&lt;br /&gt;&lt;br /&gt;php.ini&lt;br /&gt;php5ts.dll&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113989320673036449?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113989320673036449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113989320673036449' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113989320673036449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113989320673036449'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/php-50-and-iis-authentication-issues.html' title='php 5.0 and iis -  authentication issues'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113971086615276837</id><published>2006-02-11T18:07:00.000-08:00</published><updated>2006-02-16T17:43:35.426-08:00</updated><title type='text'>Is the End of Microsoft Near?</title><content type='html'>&lt;strong&gt;By Justin Silverton&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Microft has had a pretty good run. They have gone from a small development shop in the late 1970s and early 80s to the largest software company in the world.&lt;br /&gt;&lt;br /&gt;One of the reasons the windows operating system can now be seen on 80% of the world's computers is because of developer support. Any programmer from novice to expert has the ability to write an application and release it on the windows platform.&lt;br /&gt;&lt;br /&gt;Recently, an article appeared over at boing boing: (&lt;a href="http://www.boingboing.net/2006/01/30/msft_our_drm_licensi.html"&gt;http://www.boingboing.net/2006/01/30/msft_our_drm_licensi.html&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Here is an excerpt:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;"Microsoft's DRM requires that device makers pay Microsoft a license fee for each device that plays back video encoded with its system. it also requires every such vendor to submit to a standardized, non-negotiable license agreement that spells out how the player must be implemented. This contract contains numerous items that limit the sort of business you're allowed to pursue, notably that you may not implement a Microsoft player in open source software. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;The bombshell was Amir's explanation of the reason that his employer charges fees to license its DRM. According to Amir, the fee is not intended to recoup the expenses Microsoft incurred in developing their DRM, or to turn a profit. The intention is to reduce the number of licensors to a manageable level, to lock out "hobbyists" and other entities that Microsoft doesn't want to have to trouble itself with."&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;This is a step in the wrong direction and it really makes me wonder why in their right mind they would even consider doing this.&lt;br /&gt;&lt;br /&gt;I guess it shouldn't come as a surprise. With Microsoft's track record as a convicted monopolist and their blatent strongarm tactics in the hardware and software industry, another step towards world domination of total domination is only inevitable.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;what alternatives do we have?&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;1) &lt;em&gt;Linux &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;I started using linux back in 96, when there was no such thing as kde (I believe KDE was just starting out as a project) or gnome and most people you ask would have no idea what linux even is. It has come a long way in 10 years, but I don't think it is ready to take the place of windows yet.&lt;br /&gt;&lt;br /&gt;Don't get me wrong. Linux is a great operating system. I wish I could throw away all of my insecure and buggy windows machines tomorrow and never look back, but it's just not possible at this point. I think one of the main reasons I'm still using microsoft products, is driver support.&lt;br /&gt;This isn't the fault of the developing force behind linux, but of the sheer force of windows. Most manufacturers don't want to put research and development into writing a driver for linux. The end result is a constant battle to keep up with the many pieces of hardware that need to be supported. Many drivers are created by reverse-engineering an existing driver.&lt;br /&gt;&lt;br /&gt;If more manufacurers started supporting linux (at least 90%) It could be a Microsoft killer.&lt;br /&gt;&lt;br /&gt;interested in linux? find a distro &lt;a href="http://www.distrowatch.com"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2) &lt;em&gt;OS X&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;OS X could very well be the next windows killer. In the past year or so, apple announced their compatibility with OS X and the intel platform. Although in its current state, os x cannot run on an out of the box PC, what's to stop it from doing so in the future? This could all be in apple's plan.&lt;br /&gt;&lt;br /&gt;1) release intel version of os x&lt;br /&gt;2) get driver support from manufacturers and fix compatiblity issues&lt;br /&gt;3) profit&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;an interesting link about&lt;a href="http://www.apcmag.com/apc/v3.nsf/0/64E7EA353646669ECA2570F50012430B"&gt; macs booting windows XP&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;more info on &lt;a href="http://www.apple.com/macosx/"&gt;intel mac os x&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113971086615276837?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113971086615276837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113971086615276837' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113971086615276837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113971086615276837'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/is-end-of-microsoft-near.html' title='Is the End of Microsoft Near?'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113968178183848382</id><published>2006-02-11T09:22:00.000-08:00</published><updated>2006-02-11T10:44:01.376-08:00</updated><title type='text'>using php and imagemagick</title><content type='html'>&lt;strong&gt;by justin silverton&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;What is imagemagick and why do i need it?&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;image magick is a free and useful tool that can do the following:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;1) Convert an image from one format to another (e.g. PNG to JPEG&lt;br /&gt;2) Resize, rotate, sharpen, color reduce, or add special effects to an image&lt;br /&gt;3) Create a montage of image thumbnails&lt;br /&gt;4) Create a transparent image suitable for use on the Web&lt;br /&gt;5) Turn a group of images into a GIF animation sequence&lt;br /&gt;6) Create a composite image by combining several separate image&lt;br /&gt;7) Draw shapes or text on an image&lt;br /&gt;8) Decorate an image with a border or frame&lt;br /&gt;9) Describe the format and characteristics of an image&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Accessing it from PHP&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;In my experience, image magick is most likely installed here (on *nix systems) (it also may be in a different area on your system) : /usr/bin/convert&lt;/p&gt;&lt;p&gt;as an example of how I used it, I needed to automatically create thumbnails of images that were being uploaded through and administrative interface for a photo gallery.&lt;/p&gt;&lt;p&gt;&lt;?php&lt;/p&gt;&lt;p&gt;exec ("/usr/local/bin/convert -geometry 480X -quality 70 $sourcepath $destpath");&lt;/p&gt;&lt;p&gt;?&gt;&lt;/p&gt;&lt;p&gt;notes: change /usr/local/bin to the directory on your system where it is installed.&lt;/p&gt;&lt;p&gt;$sourcepath: source image we want to convert (including image name)&lt;/p&gt;&lt;p&gt;$destpath: destination image name (including image name)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;command line options&lt;/strong&gt; &lt;/p&gt;&lt;p&gt;-adjoin join images into a single multi-image file &lt;/p&gt;&lt;p&gt;-affine matrix drawing transform matrix &lt;/p&gt;&lt;p&gt;-antialias remove pixel-aliasing &lt;/p&gt;&lt;p&gt;-append append an image sequence &lt;/p&gt;&lt;p&gt;-average average an image sequence &lt;/p&gt;&lt;p&gt;-background color background color &lt;/p&gt;&lt;p&gt;-blur geometry blur the image &lt;/p&gt;&lt;p&gt;-border geometry surround image with a border of color &lt;/p&gt;&lt;p&gt;-bordercolor color border color &lt;/p&gt;&lt;p&gt;-box color color for annotation bounding box &lt;/p&gt;&lt;p&gt;-cache threshold megabytes of memory available to the pixel cache &lt;/p&gt;&lt;p&gt;-gaussian geometry gaussian blur an image &lt;/p&gt;&lt;p&gt;-geometry geometry perferred size or location of the image &lt;/p&gt;&lt;p&gt;a full list can be found by executing convert --?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Don't have imagemagick on your system? download it for free &lt;a href="http://www.imagemagick.com/www/download.html"&gt;Here&lt;/a&gt;&lt;br /&gt;It's free and licensed under the GNU&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113968178183848382?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113968178183848382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113968178183848382' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113968178183848382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113968178183848382'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-php-and-imagemagick.html' title='using php and imagemagick'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113962360184167530</id><published>2006-02-10T18:02:00.000-08:00</published><updated>2006-02-11T08:32:39.556-08:00</updated><title type='text'>life advice from steve jobs</title><content type='html'>This is a little bit old, but I still find it interesting.&lt;br /&gt;&lt;br /&gt;This is the text of the Commencement address by Steve Jobs, CEO of Apple Computer and of Pixar Animation Studios, delivered on June 12, 2005.&lt;br /&gt;&lt;br /&gt;I am honored to be with you today at your commencement from one of the finest universities in the world. I never graduated from college. Truth be told, this is the closest I've ever gotten to a college graduation. Today I want to tell you three stories from my life. That's it. No big deal. Just three stories.&lt;br /&gt;&lt;br /&gt;The first story is about connecting the dots.&lt;br /&gt;&lt;br /&gt;I dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why did I drop out?&lt;br /&gt;&lt;br /&gt;It started before I was born. My biological mother was a young, unwed college graduate student, and she decided to put me up for adoption. She felt very strongly that I should be adopted by college graduates, so everything was all set for me to be adopted at birth by a lawyer and his wife. Except that when I popped out they decided at the last minute that they really wanted a girl. So my parents, who were on a waiting list, got a call in the middle of the night asking: "We have an unexpected baby boy; do you want him?" They said: "Of course." My biological mother later found out that my mother had never graduated from college and that my father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents promised that I would someday go to college.&lt;br /&gt;&lt;br /&gt;And 17 years later I did go to college. But I naively chose a college that was almost as expensive as Stanford, and all of my working-class parents' savings were being spent on my college tuition. After six months, I couldn't see the value in it. I had no idea what I wanted to do with my life and no idea how college was going to help me figure it out. And here I was spending all of the money my parents had saved their entire life. So I decided to drop out and trust that it would all work out OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the required classes that didn't interest me, and begin dropping in on the ones that looked interesting.&lt;br /&gt;&lt;br /&gt;It wasn't all romantic. I didn't have a dorm room, so I slept on the floor in friends' rooms, I returned coke bottles for the 5¢ deposits to buy food with, and I would walk the 7 miles across town every Sunday night to get one good meal a week at the Hare Krishna temple. I loved it. And much of what I stumbled into by following my curiosity and intuition turned out to be priceless later on. Let me give you one example:&lt;br /&gt;&lt;br /&gt;Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every drawer, was beautifully hand calligraphed. Because I had dropped out and didn't have to take the normal classes, I decided to take a calligraphy class to learn how to do this. I learned about serif and san serif typefaces, about varying the amount of space between different letter combinations, about what makes great typography great. It was beautiful, historical, artistically subtle in a way that science can't capture, and I found it fascinating.&lt;br /&gt;&lt;br /&gt;None of this had even a hope of any practical application in my life. But ten years later, when we were designing the first Macintosh computer, it all came back to me. And we designed it all into the Mac. It was the first computer with beautiful typography. If I had never dropped in on that single course in college, the Mac would have never had multiple typefaces or proportionally spaced fonts. And since Windows just copied the Mac, its likely that no personal computer would have them. If I had never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they do. Of course it was impossible to connect the dots looking forward when I was in college. But it was very, very clear looking backwards ten years later.&lt;br /&gt;&lt;br /&gt;Again, you can't connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something - your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;My second story is about love and loss. &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I was lucky - I found what I loved to do early in life. Woz and I started Apple in my parents garage when I was 20. We worked hard, and in 10 years Apple had grown from just the two of us in a garage into a $2 billion company with over 4000 employees. We had just released our finest creation - the Macintosh - a year earlier, and I had just turned 30. And then I got fired. How can you get fired from a company you started? Well, as Apple grew we hired someone who I thought was very talented to run the company with me, and for the first year or so things went well. But then our visions of the future began to diverge and eventually we had a falling out. When we did, our Board of Directors sided with him. So at 30 I was out. And very publicly out. What had been the focus of my entire adult life was gone, and it was devastating.&lt;br /&gt;&lt;br /&gt;I really didn't know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down - that I had dropped the baton as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and I even thought about running away from the valley. But something slowly began to dawn on me - I still loved what I did. The turn of events at Apple had not changed that one bit. I had been rejected, but I was still in love. And so I decided to start over.&lt;br /&gt;&lt;br /&gt;I didn't see it then, but it turned out that getting fired from Apple was the best thing that could have ever happened to me. The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter one of the most creative periods of my life.&lt;br /&gt;&lt;br /&gt;During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.&lt;br /&gt;&lt;br /&gt;I'm pretty sure none of this would have happened if I hadn't been fired from Apple. It was awful tasting medicine, but I guess the patient needed it. Sometimes life hits you in the head with a brick. Don't lose faith. I'm convinced that the only thing that kept me going was that I loved what I did. You've got to find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven't found it yet, keep looking. Don't settle. As with all matters of the heart, you'll know when you find it. And, like any great relationship, it just gets better and better as the years roll on. So keep looking until you find it. Don't settle.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;My third story is about death. &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;When I was 17, I read a quote that went something like: "If you live each day as if it was your last, someday you'll most certainly be right." It made an impression on me, and since then, for the past 33 years, I have looked in the mirror every morning and asked myself: "If today were the last day of my life, would I want to do what I am about to do today?" And whenever the answer has been "No" for too many days in a row, I know I need to change something.&lt;br /&gt;&lt;br /&gt;Remembering that I'll be dead soon is the most important tool I've ever encountered to help me make the big choices in life. Because almost everything - all external expectations, all pride, all fear of embarrassment or failure - these things just fall away in the face of death, leaving only what is truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.&lt;br /&gt;&lt;br /&gt;About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly showed a tumor on my pancreas. I didn't even know what a pancreas was. The doctors told me this was almost certainly a type of cancer that is incurable, and that I should expect to live no longer than three to six months. My doctor advised me to go home and get my affairs in order, which is doctor's code for prepare to die. It means to try to tell your kids everything you thought you'd have the next 10 years to tell them in just a few months. It means to make sure everything is buttoned up so that it will be as easy as possible for your family. It means to say your goodbyes.&lt;br /&gt;&lt;br /&gt;I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope down my throat, through my stomach and into my intestines, put a needle into my pancreas and got a few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed the cells under a microscope the doctors started crying because it turned out to be a very rare form of pancreatic cancer that is curable with surgery. I had the surgery and I'm fine now.&lt;br /&gt;&lt;br /&gt;This was the closest I've been to facing death, and I hope its the closest I get for a few more decades. Having lived through it, I can now say this to you with a bit more certainty than when death was a useful but purely intellectual concept:&lt;br /&gt;&lt;br /&gt;No one wants to die. Even people who want to go to heaven don't want to die to get there. And yet death is the destination we all share. No one has ever escaped it. And that is as it should be, because Death is very likely the single best invention of Life. It is Life's change agent. It clears out the old to make way for the new. Right now the new is you, but someday not too long from now, you will gradually become the old and be cleared away. Sorry to be so dramatic, but it is quite true.&lt;br /&gt;&lt;br /&gt;Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma - which is living with the results of other people's thinking. Don't let the noise of others' opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.&lt;br /&gt;&lt;br /&gt;When I was young, there was an amazing publication called The Whole Earth Catalog, which was one of the bibles of my generation. It was created by a fellow named Stewart Brand not far from here in Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960's, before personal computers and desktop publishing, so it was all made with typewriters, scissors, and polaroid cameras. It was sort of like Google in paperback form, 35 years before Google came along: it was idealistic, and overflowing with neat tools and great notions.&lt;br /&gt;&lt;br /&gt;Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find yourself hitchhiking on if you were so adventurous. Beneath it were the words: "Stay Hungry. Stay Foolish." It was their farewell message as they signed off. Stay Hungry. Stay Foolish. And I have always wished that for myself. And now, as you graduate to begin anew, I wish that for you.&lt;br /&gt;&lt;br /&gt;Stay Hungry. Stay Foolish.&lt;br /&gt;&lt;br /&gt;Thank you all very much.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113962360184167530?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113962360184167530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113962360184167530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113962360184167530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113962360184167530'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/life-advice-from-steve-jobs.html' title='life advice from steve jobs'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113960548046236597</id><published>2006-02-10T13:04:00.000-08:00</published><updated>2006-06-14T16:38:29.116-07:00</updated><title type='text'>using java and mysql</title><content type='html'>&lt;strong&gt;by Paul DuBois&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You can write MySQL applications in a variety of languages. The languages that most people use with MySQL are PHP and Perl, but a sometimes overlooked option is the MySQL Connector/J driver, which allows you to develop Java applications that interact with your MySQL server.&lt;br /&gt;MySQL Connector/J works within the framework of the Java JDBC interface, an API that allows Java programs to use database servers in a portable way. JDBC is based on an approach similar to that used in the design of Perl and Ruby DBI modules, Python's DB-API module, and&lt;br /&gt;&lt;br /&gt;PHP's PEAR::DB class. This approach uses a two-tier architecture:&lt;br /&gt;The top level is visible to application programs and presents an abstract interface for connecting to and using database engines. The application interface does not depend on details specific to particular engines.&lt;br /&gt;&lt;br /&gt;The lower level consists of drivers for individual database engines. Each driver handles the details necessary to map the abstract application interface onto operations that a specific engine will understand.The JDBC interface allows developers to write applications that can be used with different databases with a minimum of porting effort. Once a driver for a given server engine is installed, JDBC applications can communicate with any server of that type. By using MySQL Connector/J, your Java programs can access MySQL databases.&lt;br /&gt;&lt;br /&gt;Note: MySQL Connector/J is the successor to the MM.MySQL driver. If you have JDBC programs written for MM.MySQL, they should work with MySQL Connector/J as well, although you may want to update the driver class name used in your programs. Just replace instances of org.gjt.mm.mysql in your Java source files with com.mysql.jdbc and recompile.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Preliminary Requirements&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;To use Java applications with MySQL, you may need to install some additional software:&lt;br /&gt;If you want to compile and run Java programs, you'll need a Java compiler (such as javac or jikes) and a runtime environment. If these are not already installed on your system, you can get them by obtaining a Java Software Development Kit (SDK) from &lt;a href="http://java.sun.com/"&gt;java.sun.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you want only to run precompiled applications, no compiler is necessary, but you'll still need a Java Runtime Environment (JRE). This too may be obtained from &lt;a href="http://java.sun.com/"&gt;java.sun.com&lt;/a&gt;.This article assumes that you'll write and compile your own programs, and thus that you have a Java SDK installed. Once you compile a Java program, however, you can deploy it to other machines, even ones that have only a runtime environment. This works even in heterogenous installations, because Java is platform-independent. Applications compiled on one platform can be expected to work on other platforms. For example, you can develop on a Linux box and deploy on Windows&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Connecting to the MySQL Server&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;To connect to the MySQL server, register the JDBC driver you plan to use, then invoke its getConnection() method. The following short program, Connect.java, shows how to connect to and disconnect from a server running on the local host. It accesses a database named test, using a MySQL account with a user name and password of testuser and testpass: import java.sql.*;&lt;br /&gt;&lt;br /&gt;public class Connect&lt;br /&gt;{&lt;br /&gt;public static void main (String[] args)&lt;br /&gt;{&lt;br /&gt;Connection conn = null;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;String userName = "testuser";&lt;br /&gt;String password = "testpass";&lt;br /&gt;String url = "jdbc:mysql://localhost/test";&lt;br /&gt;Class.forName ("com.mysql.jdbc.Driver").newInstance ();&lt;br /&gt;conn = DriverManager.getConnection (url, userName, password);&lt;br /&gt;System.out.println ("Database connection established");&lt;br /&gt;}&lt;br /&gt;catch (Exception e)&lt;br /&gt;{&lt;br /&gt;System.err.println ("Cannot connect to database server");&lt;br /&gt;}&lt;br /&gt;finally&lt;br /&gt;{&lt;br /&gt;if (conn != null)&lt;br /&gt;{&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;conn.close ();&lt;br /&gt;System.out.println ("Database connection terminated");&lt;br /&gt;}&lt;br /&gt;catch (Exception e) { /* ignore close errors */ }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Compile Connect.java to produce a class file Connect.class that contains executable Java code: % javac Connect.java&lt;br /&gt;Then invoke the class file as follows and it should connect to and disconnect from your MySQL server: % java Connect&lt;br /&gt;Database connection established&lt;br /&gt;Database connection terminated&lt;br /&gt;If you have trouble compiling Connect.java, double check that you have a Java Software Development Kit installed and make sure that the MySQL Connector/J driver is listed in your CLASSPATH environment variable.&lt;br /&gt;&lt;br /&gt;The arguments to getConnection() are the connection URL and the user name and password of&lt;br /&gt;a MySQL account. As illustrated by Connect.java, JDBC URLs for MySQL consist of jdbc:mysql:// followed by the name of the MySQL server host and the database name. An alternate syntax for specifying the user and password is to add them as parameters to the end of the connection URL: jdbc:mysql://localhost/test?user=testuser&amp;password=testpass&lt;br /&gt;When you specify a URL using this second format, getConnection() requires only one argument.&lt;br /&gt;&lt;br /&gt;For example, the code for connecting to the MySQL server in Connect.java could have been written like this: String userName = "testuser";&lt;br /&gt;String password = "testpass";&lt;br /&gt;String url = "jdbc:mysql://localhost/test?user="&lt;br /&gt;+ userName&lt;br /&gt;+ "&amp;password="&lt;br /&gt;+ password;&lt;br /&gt;Class.forName ("com.mysql.jdbc.Driver").newInstance ();&lt;br /&gt;conn = DriverManager.getConnection (url);&lt;br /&gt;&lt;br /&gt;getConnect() returns a Connection object that may be used to interact with MySQL by issuing queries and retrieving their results. (The next section describes how to do this.) When you're done with the connection, invoke its close() method to disconnect from the MySQL server.&lt;br /&gt;&lt;br /&gt;To increase the portability of your applications, you can store the connection parameters (host, database, user name, and password) in a Java properties file and read the properties at runtime. Then they need not be listed in the program itself. This allows you to change the server to which the program connects by editing the properties file, rather than by having to recompile the program.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Issuing Queries&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;To process SQL statements in a JDBC-based application, create a Statement object from your Connection object. Statement objects support an executeUpdate() method for issuing queries that modify the database and return no result set, and an executeQuery() method for queries that do return a result set. The query-processing examples in this article use the following table, animal, which contains an integer id column and two string columns, name and category: CREATE TABLE animal&lt;br /&gt;(&lt;br /&gt;id INT UNSIGNED NOT NULL AUTO_INCREMENT,&lt;br /&gt;PRIMARY KEY (id),&lt;br /&gt;name CHAR(40),&lt;br /&gt;category CHAR(40)&lt;br /&gt;)&lt;br /&gt;id is an AUTO_INCREMENT column, so MySQL automatically assigns successive values 1, 2, 3, ... as records are added to the table.&lt;br /&gt;Issuing Queries That Return No Result Set&lt;br /&gt;The following example obtains a Statement object from the Connection object, then uses it to create and populate the animal table. DROP TABLE, CREATE TABLE, and INSERT all are statements that modify the database, so executeUpdate() is the appropriate method for issuing them: &lt;br /&gt;&lt;br /&gt;Statement s = conn.createStatement ();&lt;br /&gt;int count;&lt;br /&gt;s.executeUpdate ("DROP TABLE IF EXISTS animal");&lt;br /&gt;s.executeUpdate (&lt;br /&gt;"CREATE TABLE animal ("&lt;br /&gt;+ "id INT UNSIGNED NOT NULL AUTO_INCREMENT,"&lt;br /&gt;+ "PRIMARY KEY (id),"&lt;br /&gt;+ "name CHAR(40), category CHAR(40))");&lt;br /&gt;count = s.executeUpdate (&lt;br /&gt;"INSERT INTO animal (name, category)"&lt;br /&gt;+ " VALUES"&lt;br /&gt;+ "('snake', 'reptile'),"&lt;br /&gt;+ "('frog', 'amphibian'),"&lt;br /&gt;+ "('tuna', 'fish'),"&lt;br /&gt;+ "('racoon', 'mammal')");&lt;br /&gt;s.close ();&lt;br /&gt;System.out.println (count + " rows were inserted");&lt;br /&gt;The executeUpdate() method returns the number of rows affected by a query. As shown above, the count is used to report how many rows the INSERT statement added to the animal table.&lt;br /&gt;&lt;br /&gt;A Statement object may be used to issue several queries. When you're done with it, invoke its close() method to dispose of the object and free any resources associated with it&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Issuing Queries That Return a Result Set&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;For statements such as SELECT queries that retrieve information from the database, use executeQuery(). After calling this method, create a ResultSet object and use it to iterate through the rows returned by your query. The following example shows one way to retrieve the contents of the animal table: &lt;br /&gt;&lt;br /&gt;Statement s = conn.createStatement ();&lt;br /&gt;s.executeQuery ("SELECT id, name, category FROM animal");&lt;br /&gt;ResultSet rs = s.getResultSet ();&lt;br /&gt;&lt;br /&gt;int count = 0;&lt;br /&gt;while (rs.next ())&lt;br /&gt;{&lt;br /&gt;int idVal = rs.getInt ("id");&lt;br /&gt;String nameVal = rs.getString ("name");&lt;br /&gt;String catVal = rs.getString ("category");&lt;br /&gt;System.out.println (&lt;br /&gt;"id = " + idVal&lt;br /&gt;+ ", name = " + nameVal&lt;br /&gt;+ ", category = " + catVal);&lt;br /&gt;++count;&lt;br /&gt;}&lt;br /&gt;rs.close ();&lt;br /&gt;s.close ();&lt;br /&gt;&lt;br /&gt;System.out.println (count + " rows were retrieved");&lt;br /&gt;&lt;br /&gt;executeQuery() does not return a row count, so if you want to know how many rows a result set contains, you should count them yourself as you fetch them.&lt;br /&gt;To obtain the column values from each row, invoke getXXX() methods that match the column data types. The getInt() and getString() methods used in the preceding example return integer and string values. As the example shows, these methods may be called using the name of a result set column. You can also fetch values by position. For the result set retrieved by the SELECT query in the example, id, name, and category are at column positions 1, 2 and 3 and thus could have been obtained like this: &lt;br /&gt;&lt;br /&gt;int idVal = rs.getInt (1);&lt;br /&gt;String nameVal = rs.getString (2);&lt;br /&gt;String catVal = rs.getString (3);&lt;br /&gt;&lt;br /&gt;ResultSet objects, like Statement objects, should be closed when you're done with them.&lt;br /&gt;&lt;br /&gt;To check whether or not a column value is NULL, invoke the result set object's wasNull() method after fetching the value. For example, you could check for a NULL value in the name column like this: String nameVal = rs.getString ("name");&lt;br /&gt;&lt;br /&gt;if (rs.wasNull ())&lt;br /&gt;nameVal = "(no name available)";&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Using Placeholders&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Sometimes it's necessary to construct queries from values containing characters that require special treatment. For example, in queries, string values are written enclosed within quotes, but any quote characters in the string itself should be doubled or escaped with a backslash to avoid creating malformed SQL. In this case, it's much easier to let JDBC handle the escaping for you, rather than fooling around trying to do so yourself. To use this approach, create a different kind of statement (a PreparedStatement), and refer to the data values in the query string by means of placeholder characters. Then tell JDBC to bind the data values to the placeholders and it will handle any special characters automatically.&lt;br /&gt;&lt;br /&gt;Suppose you have two variables nameVal and catVal from which you want to create a new record in the animal table. To do so without regard to whether or not the values contain special characters, issue the query like this: &lt;br /&gt;&lt;br /&gt;PreparedStatement s;&lt;br /&gt;s = conn.prepareStatement (&lt;br /&gt;"INSERT INTO animal (name, category) VALUES(?,?)");&lt;br /&gt;s.setString (1, nameVal);&lt;br /&gt;s.setString (2, catVal);&lt;br /&gt;int count = s.executeUpdate ();&lt;br /&gt;s.close ();&lt;br /&gt;&lt;br /&gt;System.out.println (count + " rows were inserted");&lt;br /&gt;The '?' characters in the query string act as placeholders--special markers indicating where data values should be placed. The setString() method takes a placeholder position and a string value and binds the value to the appropriate placeholder, performing any special-character escaping that may be necessary. The method you use to bind a value depends on the data type. For example, setString() binds string values and setInt() binds integer values.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If you want to trap errors, execute your JDBC operations within a try block and use an exception handler to display information about the cause of any problems that occur. JDBC provides getMessage() and getErrorCode() methods that may be invoked when an exception occurs to obtain the error message and the numeric error code. The following example deliberately issues a malformed query. When it runs, the executeQuery() method fails and raises an exception that is handled in the catch block: try&lt;br /&gt;{&lt;br /&gt;Statement s = conn.createStatement ();&lt;br /&gt;s.executeQuery ("XYZ"); // issue invalid query&lt;br /&gt;s.close ();&lt;br /&gt;}&lt;br /&gt;catch (SQLException e)&lt;br /&gt;{&lt;br /&gt;System.err.println ("Error message: " + e.getMessage ());&lt;br /&gt;System.err.println ("Error number: " + e.getErrorCode ());&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113960548046236597?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113960548046236597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113960548046236597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113960548046236597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113960548046236597'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/using-java-and-mysql.html' title='using java and mysql'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113959503281993572</id><published>2006-02-10T10:08:00.000-08:00</published><updated>2006-07-18T00:56:53.630-07:00</updated><title type='text'>smiletag 2.3 released</title><content type='html'>&lt;strong&gt;what is smiletag?&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;smiletag is a free (GPL License) shoutbox written in PHP.Available as general purpose version, WordPress plugin, Joomla / Mambo module and Drupal module version, smiletag is an interactive, easy to use, mini-message board with powerful template system.&lt;br /&gt;Powerful template system, easy-to-modify templates using only simple tags, no programming skills required. &lt;a href="http://www.smiletag.com/themes.php"&gt;Lot of themes&lt;/a&gt; available.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;features&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Smart auto-refresh, automagically refreshes whenever a new message is posted, this is done using &lt;a href="http://en.wikipedia.org/wiki/Ajax_(programming)"&gt;Ajax&lt;/a&gt; technology.&lt;br /&gt;&lt;br /&gt;Message Moderation, if enabled you can take control for every submitted message before they appear in the shoutbox.&lt;br /&gt;&lt;br /&gt;Admin Panel, easily edit/delete messages, moderate, ban, add smilies, configure and more. &lt;a href="http://www.smiletag.com/demo/admin/"&gt;Try the admin panel demo&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;No database is needed, uses flat file (XML) for storage.&lt;br /&gt;&lt;br /&gt;Profanity filters, easily add your own custom words to filter as well.&lt;br /&gt;&lt;br /&gt;Flood guard, stop spammer from flooding your board.&lt;br /&gt;&lt;br /&gt;Valid XHTML, outputs Valid XHTML 1.0 Transitional code.&lt;br /&gt;&lt;br /&gt;IP Address/Nick banning, support for both manual and automatic banning.&lt;br /&gt;&lt;br /&gt;Customizable smilies, you can add your own images as many as you want.&lt;br /&gt;&lt;br /&gt;Time Zone Control, sets the time zone to any GMT offset.&lt;br /&gt;&lt;br /&gt;Multi-language support.&lt;br /&gt;&lt;br /&gt;Email/URL recognition, automatically convert any email or url into link.&lt;br /&gt;&lt;br /&gt;Custom CSS File, you have complete control for your board look and feel.&lt;br /&gt;&lt;br /&gt;Alternate custom text, more than just alternating background color, you can alternate any text to switch for each row.&lt;br /&gt;&lt;br /&gt;Filters HTML tags and blank messages.&lt;br /&gt;&lt;br /&gt;Message formatting, allow bold, italic and underline.&lt;br /&gt;&lt;br /&gt;Custom Header and Footer, put any text at the top and bottom of your board.&lt;br /&gt;&lt;br /&gt;Timestamp, easily change the format using simple rule.&lt;br /&gt;&lt;br /&gt;Logs visitor IP Address.&lt;br /&gt;&lt;br /&gt;Auto rotate each message, in order to avoid a large file from staying on your server.&lt;br /&gt;&lt;br /&gt;Configurable number of messages to display.&lt;br /&gt;&lt;br /&gt;Configurable message length.&lt;br /&gt;&lt;br /&gt;It's free and comes with complete source code.&lt;br /&gt;&lt;br /&gt;smiletag can be downloaded &lt;a href="http://www.smiletag.com"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113959503281993572?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113959503281993572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113959503281993572' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113959503281993572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113959503281993572'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/smiletag-23-released.html' title='smiletag 2.3 released'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113952073661197895</id><published>2006-02-09T13:24:00.000-08:00</published><updated>2006-02-09T13:32:16.620-08:00</updated><title type='text'>ezsql 2.0 released</title><content type='html'>&lt;strong&gt;Overview&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;ezSQL is a class that makes it ridiculously easy to use mySQL, Oracle8, SQLite (PHP), within your PHP script. Includes lots of examples making it very easy to understand how to work with databases. ezSQL has excellent debug functions making it lightning-fast to see what’s going on in your SQL code. ezSQL can dramatically decrease development time and in most cases will streamline your code and make things run faster.&lt;br /&gt;Features&lt;br /&gt;&lt;br /&gt;ezSQL is a widget that makes it ridiculously easy for you to use mySQL, Oracle8, InterBase/FireBird, PostgreSQL, SQLite (PHP), SQLite (C++) or MS-SQL database(s) within your PHP/C++ scripts (more db's coming soon)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It is one php file that you include at the top of your script. Then, instead of using standard php database functions listed in the php manual, you use a much smaller (and easier) set of ezSQL functions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It automatically caches query results and allows you to use easy to understand functions to manipulate and extract them without causing extra server overhead&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It has excellent debug functions making it lightning-fast to see what's going on in your SQL code&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Most ezSQL functions can return results as Objects, Associative Arrays, or Numerical Arrays&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It can dramatically decrease development time and in most cases will streamline your code and make things run faster as well as making it very easy to debug and optimise your database queries.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Works with Smarty templating language&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It is a small class and will not add very much overhead to your website.&lt;br /&gt;&lt;br /&gt;Download ezSQL completely Free &lt;a href="http://php.justinvincent.com/download.php?ezsql"&gt;from here&lt;/a&gt; , also check out &lt;a href="http://www.jvmultimedia.com/portal/node/7"&gt;EZ Results Paging Class&lt;/a&gt; ezSQL's sister class that makes result paging a snip.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113952073661197895?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113952073661197895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113952073661197895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113952073661197895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113952073661197895'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/ezsql-20-released.html' title='ezsql 2.0 released'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113943082562857948</id><published>2006-02-08T12:29:00.000-08:00</published><updated>2006-05-12T03:24:18.266-07:00</updated><title type='text'>Debugging Php</title><content type='html'>&lt;strong&gt;by David Sklar&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Whether you're a PHP newbie or a wizard, your programs are going to have bugs in them. Nobody's perfect.&lt;br /&gt;&lt;br /&gt;This article gives you some techniques for finding and fixing the problems in your programs. It covers three topics:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1) How to get the PHP interpreter to report the errors that interest you.&lt;br /&gt;2) How to locate basic syntax errors in your program.&lt;br /&gt;3) How to check the values of variables as your program is running.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Configuring Error Reporting&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;First of all, you need to configure the PHP interpreter so that when an error happens, you can see information about it. The error info can be sent along with program output to the web browser. It can also be included in the web server error log. A common way to set things up is to have error output go to the web browser when you're debugging your program, and then to the web server error log once the program is finished and (supposedly) working properly. That way, web site users can't see any potentially sensitive data included with error output.&lt;br /&gt;&lt;br /&gt;To make error messages display in the browser, set the display_errors configuration directive to On. To send errors to the web server error log, set log_errors to On. You can set them both to On if you want error messages in both places.&lt;br /&gt;An error message that the PHP interpreter generates falls into one of five different categories:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Parse error&lt;/strong&gt;: A problem with the syntax of your program, such as leaving a semicolon off of the end of a statement. The interpreter stops running your program when it encounters a parse error.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Fatal error&lt;/strong&gt;: A severe problem with the content of your program, such as calling a function that hasn't been defined. The interpreter stops running your program when it encounters a fatal error.&lt;br /&gt;Warning: An advisory from the interpreter that something is fishy in your program, but the interpreter can keep going. Using the wrong number of arguments when you call a function causes a warning.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Notice&lt;/strong&gt;: A tip from the PHP interpreter, playing the role of Miss Manners. For example, printing a variable without first initializing it to some value generates a notice.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Strict notice&lt;/strong&gt;: An admonishment from the PHP interpreter about your coding style. Most of these have to do with esoteric features that changed between PHP 4 and PHP 5, so you're not likely to run into them too much.&lt;br /&gt;&lt;br /&gt;You don't have to be notified about all of the different error categories. The error_reporting configuration directive controls which kinds of errors the PHP interpreter reports. The default value for error_reporting is E_ALL &amp; ~E_NOTICE &amp;amp; ~E_STRICT, which tells the interpreter to report all errors except notices and strict notices.&lt;br /&gt;&lt;br /&gt;PHP defines some constants you can use to set the value of error_reporting so that only errors of certain types get reported: E_ALL (for all errors except strict notices), E_PARSE (parse errors), E_ERROR (fatal errors), E_WARNING (warnings), E_NOTICE (notices), and E_STRICT (strict notices).&lt;br /&gt;&lt;br /&gt;Because strict notices are rare (and new to PHP 5), they are not included in E_ALL. To tell the PHP interpreter that you want to hear about everything that could possibly be an error, set error_reporting to E_ALL E_STRICT.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Fixing Parse Errors&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The first time you write a PHP program, you discover that the PHP interpreter is extremely picky. If you leave out a necessary semicolon or start a string with a single quote but end it with a double quote, the interpreter doesn't run your program. It throws up its (virtual) hands, complains about a parse error, and leaves you stuck in the debugging wilderness.&lt;br /&gt;&lt;br /&gt;This can be one of the most frustrating things about programming when you're getting started. Everything has to be phrased and punctuated just so in order for the PHP interpreter to accept it. One thing that helps this process along is writing your programs in an editor that is PHP-aware, such as BBEdit, Emacs, XEmacs, Komodo, Dreamweaver, PHPEd, PHPEdit, or Zend Studio.&lt;br /&gt;&lt;br /&gt;These editors do syntax highlighting. This is a feature that changes the color of different parts of your program based on what those parts are. For example, strings are pink, keywords such as if and while are blue, comments are grey, and variables are black. Syntax highlighting makes it easier to detect things like a string that's missing its closing quote: the pink text continues past the line that the string is on, all the way to the end of the file (or to the next quote that appears later in the program).&lt;br /&gt;&lt;br /&gt;Another feature of these editors is quote and bracket matching. This helps to make sure that your quotes and brackets are balanced. When you type a closing delimiter such as }, the editor highlights the opening { that it matches. Different editors do this in different ways, but typical methods are to flash the cursor at the location of the opening {, or bold the { } pair for a short time. This behavior is helpful for pairs of punctuation marks that go together: single and double quotes that delimit strings, parentheses, square brackets, and curly braces.&lt;br /&gt;&lt;br /&gt;These editors also show the line numbers of your program files. When you get an error message from the PHP interpreter complaining about a parse error in line 35 in your program, you can focus on the right place to look for your error.&lt;br /&gt;Parse errors happen when the PHP interpreter comes upon something unexpected in your program.&lt;br /&gt;&lt;br /&gt;Consider this broken program:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Inspecting Program Data&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Once you clear the parse error hurdle, you still may have some work to do before you reach the finish line. A program can be syntactically correct but logically flawed. Just as the sentence "The tugboat chewed apoplectically with six subtle buffaloes" is grammatically correct but meaningless nonsense, you can write a program that the PHP interpreter doesn't find any problems with, but doesn't do what you expect.&lt;br /&gt;If your program is acting funny, add some checkpoints that display the values of variables. That way, you can see where the program's behavior diverges from your expectations. The following program incorrectly attempts to calculate the total cost of a few items:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Going Further&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Once you've got error reporting set up as you like it, and you know how to find parse errors, and you can inspect program data, you're on your way to a fruitful debugging career. However, a fully fleshed-out PHP programmer's toolbox consists of much more than just the tips in this article. Chapter 12 of Learning PHP 5, "Debugging," includes some additional debugging techniques. For more advanced debugging possibilities, check out PHP extensions such as XDebug and apd. Some of the PHP-aware editors listed in this article also include integrated debugging capabilities.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113943082562857948?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113943082562857948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113943082562857948' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113943082562857948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113943082562857948'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/debugging-php.html' title='Debugging Php'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113934056913255503</id><published>2006-02-07T11:27:00.000-08:00</published><updated>2006-06-06T15:04:08.950-07:00</updated><title type='text'>php vs. java</title><content type='html'>by &lt;b&gt;Jack Herrington&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;PHP scales. There, I said it. The word on the street is that "Java scales and PHP doesn't." The word on the street is wrong, and PHP needs someone to stand up and tell the truth: that it does scale.&lt;br /&gt;&lt;br /&gt;Those with a closed mind can head straight to the inevitable flame war located at the end of this article. Those with an open mind who are interested in taking their web development skills and putting them to use building applications in the cross-platform, easy-to-write, easy-to-maintain, scalable, and robust PHP platform, but were hesitant because of the scalability myth, should read on. It starts by looking at the term scalability.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What is Scalability?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;There are a number of different aspects of scalability. It always starts with performance, which is what we will cover in this article. But it also covers issues such as code maintainability, fault tolerance, and the availability of programming staff.&lt;br /&gt;&lt;br /&gt;These are all reasonable issues, and should be covered whenever you are choosing the development platform for any large project. But in order to convey a convincing argument in this small space, I need to reduce the term scalability to its core concern: performance.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Language and Database Performance&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Both Java and PHP run in virtual machines, which means that neither perform as well as compiled C or C++. In the &lt;a href="http://dada.perl.it/shootout/craps.html"&gt;great language shootout&lt;/a&gt;, Java beat PHP on most of the performance benchmarks, even substantially on some. However, overall the two languages were not an order of magnitude different. In addition, an older version of PHP was used in the test, and substantial performance improvements have been made since and are continuing to be made.&lt;br /&gt;Another area of performance concern is in the connection to the database. This is a misnomer, however, as the majority of the time spent in a database query is on the database server end, processing the query, and the transmit time to marshal the data between the server and the client. PHP's connectivity to the database consists of either a thin layer on top of the C data access functions, or a database abstraction layer called PEAR::DB. There is nothing to suggest that there is any PHP-specific database access performance penalty.&lt;br /&gt;&lt;br /&gt;Yet another area of efficiency concern is in the connection between the language and the web server. In the CGI model, the program or interpreter is booted on each request. In the in-process model, the interpreter stays around after each request. One of the original Java-versus-scripting-languages (e.g. PHP) benchmarks pit in-process Java against CGI invocation on the server. In the CGI model, each page incurred the overhead of the startup and shutdown of the interpreter. Even at the time, the comparison was unfair, as production machines used server-scripting extensions (such as PHP), which run in-process and stay loaded between each page fetch. There is no performance penalty for loading the interpreter and compiled pages remain in memory.&lt;br /&gt;&lt;br /&gt;With these basic efficiency questions out of the way, it's time to look at the overall architecture of the web application&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Comparing Architectures&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;There are three basic web architectures in common use today: two-tier, logical three-tier, and physical three-tier. Engineers give them different names and slightly different mechanics, so to be clear about what I mean, I will illustrate the three architectures.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;J2EE Web Server Architecture&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Perhaps the second most contentious part of this article is my definition of a J2EE web server application architecture. Externally to the Java community, the application structure looks clear: JSPs talk to EJBs, which talk to the database. Within the Java community, the standard J2EE topology is anything but clear. A comparison is only valid between two things, so to decide whether "Java scales and PHP doesn't," I need to be clear about what a Java web application server is.&lt;br /&gt;I'll take the two most common interpretations of J2EE architecture. The first is Sun's EJB 1.0 architecture, and the second is the EJB 2.0 architecture. Shown below is Sun's EJB 1.0 architecture for web application servers:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/ejb1.gif"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/ejb1.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is classic physical three-tier architecture, and it pays the performance price. I've highlighted the portions of the architecture that involve network traffic, either via database connection, an overhead shared by PHP, or by Remote Method Invocation (RMI), an overhead not shared by PHP.&lt;br /&gt;&lt;br /&gt;To be fair, the connection between the web server and the servlet engine can be avoided with modern application servers and web servers, such as Tomcat and Apache 2.0. At the time when the first versions of the JSP and EJB standards were released, the prevalent web server was (and still is) Apache 1.x, which had a process model that was not compatible with Java's threading model. This meant that a small stub was required on the web server side to communicate with the servlet engine. The remains a non-trivial performance overhead for those that decide to pay it, and was a significant performance overhead when the first scalability comparisons were made.&lt;br /&gt;A much more significant source of overhead was in the RMI connection between the servlet engine and the EJB layer. A page showing ten fields from twenty objects would make two hundred RMI calls before it was completed. This overhead was removed with the EJB 2.0 standard, which introduced local interfaces. This topology is shown below:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/ejb2.gif"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/ejb2.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is logical three-tier architecture. The web server box has been removed because more recent web servers are not separated from the servlet code (e.g. Tomcat, Apache 2.0, etc.). As you will see when we compare this model to the PHP model, EJB 2.0 moved Java web application server development closer to the successful, and scalable, PHP model.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;PHP Web Server Architecture &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;PHP has always been capable of running the gamut between a two-tier architecture and a logical three-tier architecture. Early versions of PHP could abstract the business and database access logic into a functional second tier. More recent versions can abstract the business logic with objects, and with PHP 5, these objects can use public, protected, and private access control.&lt;br /&gt;&lt;br /&gt;A modern PHP architecture, strikingly similar to the EJB 2.0 model, is shown below:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/6545/2077/1600/php.gif"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/6545/2077/320/php.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is logical three-tier architecture, and this is how modern PHP applications are written. As with Java web servers, the PHP code is in-process with the web server, so there is no overhead in the server talking to the PHP code.&lt;br /&gt;&lt;br /&gt;The PHP page acts as a broker between second-tier business objects and Smarty templates, which format the page for presentation. As with the JSP "best practice," the Smarty templates are only capable of displaying the data presented, with rudimentary looping and conditional control structures.&lt;br /&gt;&lt;br /&gt;But this is all about the design of the server. What about the architecture of the application itself?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Stateful and Stateless Architecture&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The lack of an external, stateful object store, where the application can hold session state, is often voiced as a scalability concern. PHP can use the database as the back-end session store. There is little performance difference, because a network access is required in both cases. An argument can be made that the external object store allows for any arbitrary data to be stored conveniently; however, this is easily offset by the fact that the object store itself is a single point of failure. If the object store is replicated across multiple web servers, that becomes an issue of data replication and cache coherency, which is a very complex problem.&lt;br /&gt;&lt;br /&gt;Another familiar Java pattern is the use of a local persistent object store on each web server. The user is limited to a single server by use of sticky sessions on the router. The same could be done in PHP: a local, persistent data store. But this is an &lt;a href="http://www.wikipedia.org/wiki/Anti-pattern"&gt;anti-pattern&lt;/a&gt; anyway, because a sticky session-based server pool is prone to overloading of a single web server. Or should the server go down, the result is the denial of service to a group of customers.&lt;br /&gt;&lt;br /&gt;The ideal multi-server model is a pod architecture, where the router round-robins each of the machines and there is only a minimal session store in the database. Transient user interface information is stored in hidden variables on the web page. This allows for the user to run multiple web sessions against the server simultaneously, and alleviates the "back button issue" in web user interfaces.&lt;br /&gt;&lt;br /&gt;This section has covered some very complex issues in web application server design. Scalability is mainly about the architecture of the application layer, and there is no one true panacea architecture that will work for all application architectures. The key to success is not in any particular technology, but in simplifying your server model and understanding all of the components of the application layer, from the HTML and HTTP on the front end to the SQL in the back end. Both PHP and Java are flexible enough to create scalable applications for those who spend the time to optimize their application architecture.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Convergence of Web Application Architecture&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This article started by asserting that PHP scales. When the tag-line "Java scales and scripting languages don't" was born, it was based on EJB 1.0, an architecture that most Java architects would consider absurd, based on its high overhead. Based on EJB 1.0, Java's performance was much worse than that of scripting languages. It is only the addition of local interfaces in EJB 2.0 that makes the J2EE architecture perform well.&lt;br /&gt;&lt;br /&gt;The argument for PHP scalability is further simplified, however, by the fact that both PHP and J2EE architecture (as well as others) are converging on the same design. And if "J2EE scales" given this simpler, logical three-tier architecture, then it follows that PHP does as well.&lt;br /&gt;The performance principle for scalability is simple: if you want to scale, then you have to serve web pages quickly. To serve web pages quickly, you either have to do less, or do what you do faster. Faster is a non-starter, because Java is not so much faster than PHP that it makes much of a difference. Doing less is the key. By using a logical three-tier architecture and by reducing the number of queries and commands sent to the database, we can get web applications that scale, both in Java and in PHP.&lt;br /&gt;&lt;br /&gt;For the open-minded developer, there is a world of applications that can be built quickly, cheaply, robustly, and scalably with PHP. Services such as Amazon, Yahoo, Google, and Slashdot have known about scripting languages for years and used them effectively in production. Yahoo even adopted PHP as its language of choice for development. Don't believe the hype in the white papers that says that PHP isn't for real applications or doesn't scale.&lt;br /&gt;&lt;br /&gt;I'm sure that what I have said in this article will be picked to death and ridiculed by some. I stand by what I have said. The idea that PHP does not scale is clearly false at the performance level. In fact, we should have never even gotten to the point where this article was necessary, because as engineers, we should recognize that the argument that one language clearly "scales better" than another is, on its face, ridiculous. As engineers and architects, we need to look objectively at technologies and use a factual and rational basis to make technology decisions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113934056913255503?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113934056913255503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113934056913255503' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113934056913255503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113934056913255503'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/php-vs-java.html' title='php vs. java'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113898755038953147</id><published>2006-02-03T09:21:00.000-08:00</published><updated>2006-02-03T09:26:31.046-08:00</updated><title type='text'>New TinyMCE 2.0.2 released</title><content type='html'>&lt;strong&gt;What is TinyMCE?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under LGPL by &lt;a title="Moxiecode Systems" href="http://www.moxiecode.com/"&gt;Moxiecode Systems AB&lt;/a&gt;. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances. TinyMCE is very easy to integrate into other CMS systems.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;TinyMCE Features&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;p&gt;&lt;a href="http://tinymce.moxiecode.com/tinymce/docs/installing.html" target="documentation"&gt;Easy to integrate&lt;/a&gt;, takes only two lines of code. &lt;/p&gt;&lt;p&gt;Customizable through &lt;a href="http://tinymce.moxiecode.com/tinymce/docs/customization_themes.html" target="documentation"&gt;themes&lt;/a&gt; and &lt;a href="http://tinymce.moxiecode.com/tinymce/docs/customization_plugins.html" target="documentation"&gt;plugins&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://tinymce.moxiecode.com/tinymce/docs/option_valid_elements.html" target="documentation"&gt;Customizable XHTML 1.0 output&lt;/a&gt;. Block invalid elements and force attributes.&lt;br /&gt;&lt;a href="http://tinymce.moxiecode.com/tinymce/docs/customization_language_packs.html" target="documentation"&gt;International language support&lt;/a&gt; (Language packs)&lt;br /&gt;&lt;a href="http://tinymce.moxiecode.com/tinymce/docs/compatiblity_chart.html" target="documentation"&gt;Multiple browser support&lt;/a&gt;, Mozilla, MSIE, FireFox, Opera and Safari (experimental).&lt;br /&gt;&lt;a href="http://tinymce.moxiecode.com/download.php"&gt;PHP/.NET/JSP/Coldfusion GZip compressor&lt;/a&gt;, Makes TinyMCE 75% smaller and a lot faster to load. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;new to the release&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This release adds a new cleanup routine that out performs the previous one in both performance and flexibility. This new cleanup routine is currently available in a plugin since it could include bugs and issues so we suggest using the original cleanup if you have issues with the new one.&lt;br /&gt;New language packs and other contributions where also added to this release, I would like to send a big thanks to everyone contributing to this project and helping us develop one of the best WYSIWYG editor applications out there.&lt;br /&gt;We also added a few new interessting options to the save plugin that enables AJAX save calls to be made.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;On top of these new features we resolved lots of bugs and issues including the common one with getting xsrc/xhref attributes.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Download it &lt;a href="http://tinymce.moxiecode.com/download.php"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113898755038953147?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113898755038953147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113898755038953147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113898755038953147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113898755038953147'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/new-tinymce-202-released.html' title='New TinyMCE 2.0.2 released'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113889970918509786</id><published>2006-02-02T08:46:00.000-08:00</published><updated>2006-05-05T09:30:54.320-07:00</updated><title type='text'>improving php execution speed in windows with php.ini</title><content type='html'>adding the following two lines to php.ini  can make your php scripts run run faster and also save you in bandwidth.&lt;br /&gt;&lt;br /&gt;zlib.output_compression = On&lt;br /&gt;zlib.output_compression_level = &lt;strong&gt;level&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;level can be from 1-9. This is a tradeoff between speed and size. The higer compression levels create files that are smaller in size (which will save you in bandwidth), but they take more processing time to de-compress/compress. Most web-browsers support this standard. It is best to choose different numbers to find out which one will work best for your server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113889970918509786?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113889970918509786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113889970918509786' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113889970918509786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113889970918509786'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/02/improving-php-execution-speed-in.html' title='improving php execution speed in windows with php.ini'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113875403697207079</id><published>2006-01-31T16:30:00.000-08:00</published><updated>2006-06-06T14:06:17.160-07:00</updated><title type='text'>using memcached and php</title><content type='html'>&lt;strong&gt;What is memcached?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.&lt;br /&gt;&lt;br /&gt;Danga Interactive developed memcached to enhance the speed of LiveJournal.com, a site which was already doing 20 million+ dynamic page views per day for 1 million users with a bunch of webservers and a bunch of database servers. memcached dropped the database load to almost nothing, yielding faster page load times for users, better resource utilization, and faster access to the databases on a memcache miss.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How it Works&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;First, you start up the memcached daemon on as many spare machines as you have. The daemon has no configuration file, just a few command line options, only 3 or 4 of which you'll likely use: # ./memcached -d -m 2048 -l 10.0.0.40 -p 11211&lt;br /&gt;&lt;br /&gt;This starts memcached up as a daemon, using 2GB of memory, and listening on IP 10.0.0.40, port 11211. Because a 32-bit process can only address 4GB of virtual memory (usually significantly less, depending on your operating system), if you have a 32-bit server with 4-64GB of memory using PAE you can just run multiple processes on the machine, each using 2 or 3GB of memory.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Shouldn't the database do this?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Regardless of what database you use (MS-SQL, Oracle, Postgres, MysQL-InnoDB, etc..), there's a lot of overhead in implementing &lt;a href="http://www.wikipedia.org/wiki/ACID"&gt;ACID&lt;/a&gt; properties in a RDBMS, especially when disks are involved, which means queries are going to block. For databases that aren't ACID-compliant (like MySQL-MyISAM), that overhead doesn't exist, but reading threads block on the writing threads.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What about shared memory?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The first thing people generally do is cache things within their web processes. But this means your cache is duplicated multiple times, once for each mod_perl/PHP/etc thread. This is a waste of memory and you'll get low cache hit rates. If you're using a multi-threaded language or a shared memory API (IPC::Shareable, etc), you can have a global cache for all threads, but it's per-machine. It doesn't scale to multiple machines. Once you have 20 webservers, those 20 independent caches start to look just as silly as when you had 20 threads with their own caches on a single box. (plus, shared memory is typically laden with limitations)&lt;br /&gt;&lt;br /&gt;The memcached server and clients work together to implement one global cache across as many machines as you have. In fact, it's recommended you run both web nodes (which are typically memory-lite and CPU-hungry) and memcached processes (which are memory-hungry and CPU-lite) on the same machines. This way you'll save network ports.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What about MySQL 4.x query caching?&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;MySQL query caching is less than ideal, for a number of reasons:&lt;br /&gt;&lt;br /&gt;MySQL's query cache destroys the entire cache for a given table whenever that table is changed. On a high-traffic site with updates happening many times per second, this makes the the cache practically worthless. In fact, it's often harmful to have it on, since there's a overhead to maintain the cache.&lt;br /&gt;&lt;br /&gt;On 32-bit architectures, the entire server (including the query cache) is limited to a 4 GB virtual address space. memcached lets you run as many processes as you want, so you have no limit on memory cache size.&lt;br /&gt;&lt;br /&gt;MySQL has a query cache, not an object cache. If your objects require extra expensive construction after the data retrieval step, MySQL's query cache can't help you there.&lt;br /&gt;If the data you need to cache is small and you do infrequent updates, MySQL's query caching should work for you. If not, use memcached.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What about database replication?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You can spread your reads with replication, and that helps a lot, but you can't spread writes (they have to process on all machines) and they'll eventually consume all your resources. You'll find yourself adding replicated slaves at an ever-increasing rate to make up for the diminishing returns each addition slave provides.&lt;br /&gt;&lt;br /&gt;The next logical step is to horizontally partition your dataset onto different master/slave clusters so you can spread your writes, and then teach your application to connect to the correct cluster depending on the data it needs.&lt;br /&gt;&lt;br /&gt;While this strategy works, and is recommended, more databases (each with a bunch of disks) statistically leads to more frequent hardware failures, which are annoying.&lt;br /&gt;With memcached you can reduce your database reads to a mere fraction, leaving the databases to mainly do infrequent writes, and end up getting much more bang for your buck, since your databases won't be blocking themselves doing ACID bookkeeping or waiting on writing threads.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Is memcached fast?&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Very fast. It uses &lt;a href="http://www.monkey.org/~provos/libevent/"&gt;libevent&lt;/a&gt; to scale to any number of open connections (using &lt;a href="http://www.xmailserver.org/linux-patches/nio-improve.html"&gt;epoll&lt;/a&gt; on Linux, if available at runtime), uses non-blocking network I/O, refcounts internal objects (so objects can be in multiple states to multiple clients), and uses its own slab allocator and hash table so virtual memory never gets externally fragmented and allocations are guaranteed O(1).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What about race conditions?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You might wonder: "What if the get_foo() function adds a stale version of the Foo object to the cache right as/after the user updates their Foo object via update_foo()?"&lt;br /&gt;While the server and API only have one way to get data from the cache, there exists 3 ways to put data in:&lt;br /&gt;&lt;br /&gt;set -- unconditionally sets a given key with a given value (update_foo() should use this)&lt;br /&gt;add -- adds to the cache, only if it doesn't already exist (get_foo() should use this)&lt;br /&gt;replace -- sets in the cache only if the key already exists (not as useful, only for completeness)Additionally, all three support an expiration time.&lt;br /&gt;&lt;br /&gt;server can be downloaded here: &lt;a href="http://www.danga.com/memcached/dist/memcached-1.1.12.tar.gz"&gt;http://www.danga.com/memcached/dist/memcached-1.1.12.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;php module can be downloaded here: &lt;a href="http://pecl.php.net/package/memcache"&gt;http://pecl.php.net/package/memcache&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113875403697207079?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113875403697207079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113875403697207079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113875403697207079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113875403697207079'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/using-memcached-and-php.html' title='using memcached and php'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113871544735033386</id><published>2006-01-31T05:48:00.000-08:00</published><updated>2006-05-05T21:56:50.020-07:00</updated><title type='text'>php optimization myths</title><content type='html'>Some optimizations are useful. Others are a waste of time - sometimes the improvement is neglible, and sometimes the PHP internals change, rendering the tweak obsolete.&lt;br /&gt;Here are some common PHP legends:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;a. echo is faster than print&lt;/strong&gt;&lt;br /&gt;Echo is supposed to be faster because it doesn't return a value while print does. From my benchmarks with PHP 4.3, the difference is neglible. And under some situations, print is faster than echo (when ob_start is enabled).&lt;br /&gt;&lt;strong&gt;b. strip off comments to speed up code&lt;br /&gt;&lt;/strong&gt;If you use an opcode cache, comments are already ignored. This is a myth from PHP3 days, when each line of PHP was interpreted in run-time.&lt;br /&gt;&lt;strong&gt;c. 'var='.$var is faster than "var=$var"&lt;br /&gt;&lt;/strong&gt;This used to be true in PHP 4.2 and earlier. This was fixed in PHP 4.3. Note (22 June 2004): apparently the 4.3 fix reduced the overhead, but not completely. However I find the performance difference to be negligible.&lt;br /&gt;&lt;strong&gt;Do References Speed Your Code?&lt;/strong&gt;&lt;br /&gt;References do not provide any performance benefits for strings, integers and other basic data types. For example, consider the following code:&lt;br /&gt;&lt;br /&gt;function TestRef(&amp;$a)&lt;br /&gt;{&lt;br /&gt;$b = $a;&lt;br /&gt;$c = $a;&lt;br /&gt;}&lt;br /&gt;$one = 1;&lt;br /&gt;&lt;br /&gt;ProcessArrayRef($one);&lt;br /&gt;And the same code without references:&lt;br /&gt;function TestNoRef($a)&lt;br /&gt;{&lt;br /&gt;$b = $a;&lt;br /&gt;$c = $a;&lt;br /&gt;}&lt;br /&gt;$one = 1;&lt;br /&gt;&lt;br /&gt;ProcessArrayNoRef($one);&lt;br /&gt;&lt;br /&gt;PHP does not actually create duplicate variables when "pass by value" is used, but uses high&lt;br /&gt;speed reference counting internally. So in TestRef(), $b and $c take longer to set because the references have to be tracked, while in TestNoRef(), $b and $c just point to the original value of $a, and the reference counter is incremented. So TestNoRef() will execute faster than TestRef().&lt;br /&gt;In contrast, functions that accept array and object parameters have a performance advantage when references are used. This is because arrays and objects do not use reference counting, so multiple copies of an array or object are created if "pass by value" is used. So the following code:&lt;br /&gt;&lt;br /&gt;function ObjRef(&amp;$o)&lt;br /&gt;{&lt;br /&gt;$a =$o-&amp;amp;gtname;&lt;br /&gt;}&lt;br /&gt;is faster than:&lt;br /&gt;$function ObjRef($o)&lt;br /&gt;{&lt;br /&gt;$a = $o-&amp;gtname;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Note: In PHP 5, all objects are passed by reference automatically, without the need of an explicit &amp;amp; in the parameter list. PHP 5 object performance should be significantly faster.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113871544735033386?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113871544735033386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113871544735033386' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113871544735033386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113871544735033386'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/php-optimization-myths.html' title='php optimization myths'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113867367429946587</id><published>2006-01-30T18:09:00.000-08:00</published><updated>2006-01-30T18:14:34.313-08:00</updated><title type='text'>Optimizing Object-oriented PHP</title><content type='html'>1. Initialise all variables before use.&lt;br /&gt;&lt;br /&gt;2. Dereference all global/property variables that are frequently used in a method and put the values in local variables if you plan to access the value more than twice.&lt;br /&gt;&lt;br /&gt;3. Try placing frequently used methods in the derived classes.&lt;br /&gt;&lt;br /&gt;Warning: as PHP is going through a continuous improvement process, things might change in the future.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;More Details&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I have found that calling object methods (functions defined in a class) are about twice as slow as a normal function calls. To me that's quite acceptable and comparable to other OOP languages.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Inside a method (the following ratios are approximate only):&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;1. Incrementing a local variable in a method is the fastest. Nearly the same as calling a local variable in a function.&lt;br /&gt;2. Incrementing a global variable is 2 times slow than a local var.&lt;br /&gt;3. Incrementing a object property (eg. $this-&gt;prop++) is 3 times slower than a local variable.&lt;br /&gt;4. Incrementing an undefined local variable is 9-10 times slower than a pre-initialized one.&lt;br /&gt;5. Just declaring a global variable without using it in a function also slows things down (by about the same amount as incrementing a local var). PHP probably does a check to see if the global exists.&lt;br /&gt;6. Method invocation appears to be independent of the number of methods defined in the class because I added 10 more methods to the test class (before and after the test method) with no change in performance.&lt;br /&gt;7. Methods in derived classes run faster than ones defined in the base class.&lt;br /&gt;8. A function call with one parameter and an empty function body takes about the same time as doing 7-8 $localvar++ operations. A similar method call is of course about 15 $localvar++ operations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113867367429946587?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113867367429946587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113867367429946587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113867367429946587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113867367429946587'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/optimizing-object-oriented-php.html' title='Optimizing Object-oriented PHP'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113864626592741173</id><published>2006-01-30T10:33:00.000-08:00</published><updated>2006-01-30T10:37:45.930-08:00</updated><title type='text'>Using PEAR cache</title><content type='html'>The PEAR Cache is a set of caching classes that allows you to cache multiple types of data, including HTML and images.&lt;br /&gt;&lt;br /&gt;The most common use of the PEAR Cache is to cache HTML text. To do this, we use the Output buffering class which caches all text printed or echoed between the start() and end() functions:&lt;br /&gt;&lt;br /&gt;require_once("Cache/Output.php");&lt;br /&gt;&lt;br /&gt;$cache = new Cache_Output("file", array("cache_dir" =&amp;GT "cache/") );&lt;br /&gt;&lt;br /&gt;if ($contents = $cache-&amp;GTstart(md5("this is a unique key!"))) {&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# aha, cached data returned&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;  print $contents;&lt;br /&gt;  print "&amp;LTp&amp;GTCache Hit&amp;LT/p&amp;GT";&lt;br /&gt;&lt;br /&gt;} else {&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# no cached data, or cache expired&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;  print "&amp;LTp&amp;GTDon't leave home without it…&amp;LT/p&amp;GT"; # place in cache&lt;br /&gt;  print "&amp;LTp&amp;GTStand and deliver&amp;LT/p&amp;GT"; # place in cache&lt;br /&gt;  print $cache-&amp;GTend(10);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;The Cache constructor takes the storage driver to use as the first parameter. File, database and shared memory storage drivers are available; see the pear/Cache/Container directory. Benchmarks by Ulf Wendel suggest that the "file" storage driver offers the best performance. The second parameter is the storage driver options. The options are "cache_dir", the location of the caching directory, and "filename_prefix", which is the prefix to use for all cached files. Strangely enough, cache expiry times are not set in the options parameter.&lt;br /&gt;&lt;br /&gt;To cache some data, you generate a unique id for the cached data using a key. In the above example, we used md5("this is a unique key!").&lt;br /&gt;&lt;br /&gt;The start() function uses the key to find a cached copy of the contents. If the contents are not cached, an empty string is returned by start(), and all future echo() and print() statements will be buffered in the output cache, until end() is called.&lt;br /&gt;&lt;br /&gt;The end() function returns the contents of the buffer, and ends output buffering. The end() function takes as its first parameter the expiry time of the cache. This parameter can be the seconds to cache the data, or a Unix integer timestamp giving the date and time to expire the data, or zero to default to 24 hours.&lt;br /&gt;&lt;br /&gt;Another way to use the PEAR cache is to store variables or other data. To do so, you can use the base Cache class:&lt;br /&gt;&lt;br /&gt;&amp;LT?php&lt;br /&gt;&lt;br /&gt;require_once("Cache.php");&lt;br /&gt;&lt;br /&gt;$cache = new Cache("file", array("cache_dir" =&amp;GT "cache/") );&lt;br /&gt;$id = $cache-&amp;GTgenerateID("this is a unique key");&lt;br /&gt;&lt;br /&gt;if ($data = $cache-&amp;GTget($id)) {&lt;br /&gt;&lt;br /&gt;  print "Cache hit.&amp;LTbr&amp;GTData: $data";&lt;br /&gt;&lt;br /&gt;} else {&lt;br /&gt;&lt;br /&gt;  $data = "The quality of mercy is not strained...";&lt;br /&gt;  $cache-&amp;GTsave($id, $data, $expires = 60);&lt;br /&gt;  print "Cache miss.&amp;LTbr&amp;GT";&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&amp;GT&lt;br /&gt;&lt;br /&gt;To save the data we use save(). If your unique key is already a legal file name, you can bypass the generateID() step. Objects and arrays can be saved because save() will serialize the data for you. The last parameter controls when the data expires; this can be the seconds to cache the data, or a Unix integer timestamp giving the date and time to expire the data, or zero to use the default of 24 hours. To retrieve the cached data we use get().&lt;br /&gt;&lt;br /&gt;You can delete a cached data item using $cache-&amp;GTdelete($id) and remove all cached items using $cache-&amp;GTflush().&lt;br /&gt;&lt;br /&gt;New: A faster Caching class is Cache-Lite. Highly recommended.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113864626592741173?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113864626592741173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113864626592741173' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113864626592741173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113864626592741173'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/using-pear-cache_30.html' title='Using PEAR cache'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113858705613412853</id><published>2006-01-29T18:06:00.000-08:00</published><updated>2006-01-29T21:00:29.066-08:00</updated><title type='text'>How to install php 4.4.1 on iis 6.0 - updated</title><content type='html'>Earlier this month, I wrote a howto on how to install php 4.4.1 on iis 6.0. I have a small change in those instructions.&lt;br /&gt;&lt;br /&gt;As I have recently discovered (I'm not sure why I never saw this before), if you set the doc_root=your web directory, IIS will not be able to see a php file in any of your subdirectories.&lt;br /&gt;&lt;br /&gt;This value doesn't even need to be set at all.&lt;br /&gt;&lt;br /&gt;so, rather than setting the doc_root to your web root directory, don't even bother settting it, unless you know what you are doing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113858705613412853?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113858705613412853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113858705613412853' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113858705613412853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113858705613412853'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/how-to-install-php-441-on-iis-60_29.html' title='How to install php 4.4.1 on iis 6.0 - updated'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113857472308599017</id><published>2006-01-29T14:36:00.000-08:00</published><updated>2006-01-29T14:45:56.533-08:00</updated><title type='text'>The php zend engine</title><content type='html'>The Zend Engine is the internal compiler and runtime engine used by PHP4. Developed by Zeev Suraski and Andi Gutmans, the Zend Engine is an abbreviation of their names. In the early days of PHP4, it worked as follows:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/Image2.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/6545/2077/320/Image2.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The PHP script was loaded by the Zend Engine and compiled into Zend opcode. Opcodes, short for operation codes, are low level binary instructions. Then the opcode was executed and the HTML generated sent to the client. The opcode was flushed from memory after execution.&lt;br /&gt;&lt;br /&gt;Today, there are a multitude of products and techniques to help you speed up this process. In the following diagram, we show the how modern PHP scripts work; all the shaded boxes are optional.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6545/2077/1600/php-zend.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/6545/2077/400/php-zend.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PHP Scripts are loaded into memory and compiled into Zend opcodes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113857472308599017?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113857472308599017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113857472308599017' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113857472308599017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113857472308599017'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/php-zend-engine.html' title='The php zend engine'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113838814558970193</id><published>2006-01-27T10:45:00.000-08:00</published><updated>2006-03-01T08:22:48.363-08:00</updated><title type='text'>How to play a movie on your website</title><content type='html'>The following html code will allow you to play flash,quicktime,real meadia, or microsoft media files from your webpage.&lt;br /&gt;&lt;br /&gt;Flash:&lt;br /&gt;&lt;br /&gt;&lt;!-- begin embedded Flash file... --&gt;&lt;br /&gt;&lt;table border="'0'" cellpadding="'0'" align="center"&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;OBJECT classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'&lt;br /&gt;codebase=&lt;br /&gt;'http://download.macromedia.com/pub/shockwave/cabs&lt;br /&gt;/flash/swflash.cab#version=6,0,0,0'&lt;br /&gt;width="320" height="240"&gt;&lt;br /&gt;&lt;param name="'movie'" value="http://yourpage/yourmovie"&gt;&lt;br /&gt;&lt;param name="'quality'" value="high"&gt;&lt;br /&gt;&lt;param name="'bgcolor'" value="'#FFFFFF'"&gt;&lt;br /&gt;&lt;param name="'loop'" value="true"&gt;&lt;br /&gt;&lt;EMBED src="http://yourpage/yourmovie" quality='high' bgcolor='#FFFFFF' width="320"&lt;br /&gt;height="240" loop="true" type='application/x-shockwave-flash'&lt;br /&gt;pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'&gt;&lt;br /&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;!-- ...end embedded Flash file --&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Quicktime:&lt;br /&gt;&lt;!-- begin embedded QuickTime file... --&gt;&lt;br /&gt;&lt;table border="'0'" cellpadding="'0'" align="center"&gt;&lt;br /&gt;&lt;!-- begin video window... --&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;OBJECT classid='clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B' width="320"&lt;br /&gt;height="255" codebase='http://www.apple.com/qtactivex/qtplugin.cab'&gt;&lt;br /&gt;&lt;param name="'src'" value="http://yourpage/yourmovie"&gt;&lt;br /&gt;&lt;param name="'autoplay'" value="true"&gt;&lt;br /&gt;&lt;param name="'controller'" value="true"&gt;&lt;br /&gt;&lt;param name="'loop'" value="true"&gt;&lt;br /&gt;&lt;EMBED src="http://yourpage/yourmovie" width="320" height="255" autoplay="true"&lt;br /&gt;controller="true" loop="true" pluginspage='http://www.apple.com/quicktime/download/'&gt;&lt;br /&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;!-- ...end embedded QuickTime file --&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;REAL:&lt;br /&gt;&lt;br /&gt;&lt;!-- begin embedded RealMedia file... --&gt;&lt;br /&gt;&lt;table border="'0'" cellpadding="'0'" align="center"&gt;&lt;br /&gt;&lt;!-- begin video window... --&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;OBJECT id='rvocx' classid='clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA'&lt;br /&gt;width="320" height="240"&gt;&lt;br /&gt;&lt;param name="'src'" value="http://yourpage/yourmovie"&gt;&lt;br /&gt;&lt;param name="'autostart'" value="true"&gt;&lt;br /&gt;&lt;param name="'controls'" value="'imagewindow'"&gt;&lt;br /&gt;&lt;param name="'console'" value="'video'"&gt;&lt;br /&gt;&lt;param name="'loop'" value="true"&gt;&lt;br /&gt;&lt;EMBED src="http://yourpage/yourmovie" width="320" height="240"&lt;br /&gt;loop="true" type='audio/x-pn-realaudio-plugin' controls='imagewindow' console='video' autostart="true"&gt;&lt;br /&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;!-- ...end video window --&gt;&lt;br /&gt;&lt;!-- begin control panel... --&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;OBJECT id='rvocx' classid='clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA'&lt;br /&gt;width="320" height='30'&gt;&lt;br /&gt;&lt;param name="'src'" value="http://yourpage/yourmovie"&gt;&lt;br /&gt;&lt;param name="'autostart'" value="true"&gt;&lt;br /&gt;&lt;param name="'controls'" value="'ControlPanel'"&gt;&lt;br /&gt;&lt;param name="'console'" value="'video'"&gt;&lt;br /&gt;&lt;EMBED src="http://yourpage/yourmovie" width="320" height='30'&lt;br /&gt;controls='ControlPanel' type='audio/x-pn-realaudio-plugin' console='video' autostart="true"&gt;&lt;br /&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;!-- ...end control panel --&gt;&lt;br /&gt;&lt;!-- ...end embedded RealMedia file --&gt;&lt;br /&gt;&lt;!-- begin link to launch external media player... --&gt;&lt;br /&gt;&lt;tr&gt;&lt;td align="'center'"&gt;&lt;br /&gt;&lt;a href="http://yourpage/yourmovie" style="'font-size:" target="'_blank'"&gt;Launch in external player&lt;/a&gt;&lt;br /&gt;&lt;!-- ...end link to launch external media player... --&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Microsoft media:&lt;br /&gt;&lt;br /&gt;&lt;!-- begin embedded WindowsMedia file... --&gt;&lt;br /&gt;&lt;table border="'0'" cellpadding="'0'" align="center"&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;OBJECT id='mediaPlayer' width="320" height="285"&lt;br /&gt;classid='CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95'&lt;br /&gt;codebase='&lt;br /&gt;http://activex.microsoft.com/activex/controls&lt;br /&gt;/mplayer/en/nsmp2inf.cab#Version=5,1,52,701'&lt;br /&gt;standby='Loading Microsoft Windows Media Player components...' type='application/x-oleobject'&gt;&lt;br /&gt;&lt;param name="'fileName'" value="http://yourpage/yourmovie"&gt;&lt;br /&gt;&lt;param name="'animationatStart'" value="'true'"&gt;&lt;br /&gt;&lt;param name="'transparentatStart'" value="'true'"&gt;&lt;br /&gt;&lt;param name="'autoStart'" value="true"&gt;&lt;br /&gt;&lt;param name="'showControls'" value="true"&gt;&lt;br /&gt;&lt;param name="'loop'" value="false"&gt;&lt;br /&gt;&lt;EMBED type='application/x-mplayer2'&lt;br /&gt;pluginspage='http://microsoft.com/windows/mediaplayer/en/download/'&lt;br /&gt;id='mediaPlayer' name='mediaPlayer' displaysize='4' autosize='-1'&lt;br /&gt;bgcolor='darkblue' showcontrols="true" showtracker='-1'&lt;br /&gt;showdisplay='0' showstatusbar='-1' videoborder3d='-1' width="320" height="285"&lt;br /&gt;src="http://yourpage/yourmovie" autostart="true" designtimesp='5311' loop="false"&gt;&lt;br /&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;!-- ...end embedded WindowsMedia file --&gt;&lt;br /&gt;&lt;!-- begin link to launch external media player... --&gt;&lt;br /&gt;&lt;tr&gt;&lt;td align="'center'"&gt;&lt;br /&gt;&lt;a href="http://yourpage/yourmovie" style="'font-size:" target="'_blank'"&gt;Launch in external player&lt;/a&gt;&lt;br /&gt;&lt;!-- ...end link to launch external media player... --&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113838814558970193?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113838814558970193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113838814558970193' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113838814558970193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113838814558970193'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/how-to-play-movie-on-your-website.html' title='How to play a movie on your website'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113825541371903744</id><published>2006-01-25T22:00:00.000-08:00</published><updated>2006-01-26T09:12:03.610-08:00</updated><title type='text'>Launching a process from php</title><content type='html'>I have written a couple of simple functions that will allow you to launch a separate process from php.  This  comes in handy, because it can be called from the command line or through a web page.  The initial calling script will not halt and will come back immediately.&lt;br /&gt;&lt;br /&gt;code can be downloaded &lt;A HREF="http://home.blazesupport.com/jprocess.zip"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113825541371903744?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113825541371903744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113825541371903744' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113825541371903744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113825541371903744'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/launching-process-from-php.html' title='Launching a process from php'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113816766309215379</id><published>2006-01-24T21:39:00.000-08:00</published><updated>2006-01-25T11:04:30.313-08:00</updated><title type='text'>improving php performance on apache</title><content type='html'>Apache is available on both Unix and Windows. It is the most popular web server in the world. Apache 1.3 uses a pre-forking model for web serving. When Apache starts up, it creates multiple child processes that handle HTTP requests. The initial parent process acts like a guardian angel, making sure that all the child processes are working properly and coordinating everything. As more HTTP requests come in, more child processes are spawned to process them. As the HTTP requests slow down, the parent will kill the idle child processes, freeing up resources for other processes. The beauty of this scheme is that it makes Apache extremely robust. Even if a child process crashes, the parent and the other child processes are insulated from the crashing child.&lt;br /&gt;The pre-forking model is not as fast as some other possible designs, but to me that it is "much ado about nothing" on a server serving PHP scripts because other bottlenecks will kick in long before Apache performance issues become significant. The robustness and reliability of Apache is more important.&lt;br /&gt;&lt;br /&gt;Apache 2.0 offers operation in multi-threaded mode. My benchmarks indicate there is little performance advantage in this mode. Also be warned that many PHP extensions are not compatible (e.g. GD and IMAP). Tested with Apache 2.0.47.&lt;br /&gt;Apache is configured using the httpd.conf file. The following parameters are particularly important in configuring child processes:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;MaxClients : default: 256&lt;/strong&gt;&lt;br /&gt;The maximum number of child processes to create. The default means that up to 256 HTTP requests can be handled concurrently. Any further connection requests are queued.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;StartServers: default: 5&lt;/strong&gt;&lt;br /&gt;The number of child processes to create on startup.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;MinSpareServers: default:5&lt;br /&gt;&lt;/strong&gt;The number of idle child processes that should be created. If the number of idle child processes falls to less than this number, 1 child is created initially, then 2 after another second, then 4 after another second, and so forth till 32 children are created per second.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;MaxSpareServers: default:10&lt;/strong&gt;&lt;br /&gt;If more than this number of child processes are alive, then these extra processes will be terminated.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;MaxRequestsPerChild: default: 0&lt;br /&gt;&lt;/strong&gt;Sets the number of HTTP requests a child can handle before terminating. Setting to 0 means never terminate. Set this to a value to between 100 to 10000 if you suspect memory leaks are occurring, or to free under-utilized resources&lt;br /&gt;&lt;br /&gt;For large sites, values close to the following might be better:&lt;br /&gt;&lt;br /&gt;MinSpareServers 32&lt;br /&gt;MaxSpareServers 64&lt;br /&gt;&lt;br /&gt;Apache on Windows behaves differently. Instead of using child processes, Apache uses threads. The above parameters are not used. Instead we have one parameter: ThreadsPerChild which defaults to 50. This parameter sets the number of threads that can be spawned by Apache. As there is only one child process in the Windows version, the default setting of 50 means only 50 concurrent HTTP requests can be handled. For web servers experiencing higher traffic, increase this value to between 256 to 1024.&lt;br /&gt;&lt;br /&gt;Other useful performance parameters you can change include:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SendBufferSize: Set to OS default&lt;/strong&gt;&lt;br /&gt;Determines the size of the output buffer (in bytes) used in TCP/IP connections. This is primarily useful for congested or slow networks when packets need to be buffered; you then set this parameter close to the size of the largest file normally downloaded. One TCP/IP buffer will be created per client connection.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;KeepAlive [onoff] default:On&lt;/strong&gt;&lt;br /&gt;In the original HTTP specification, every HTTP request had to establish a separate connection to the server. To reduce the overhead of frequent connects, the keep-alive header was developed. Keep-alives tells the server to reuse the same socket connection for multiple HTTP requests.&lt;br /&gt;&lt;br /&gt;If a separate dedicated web server serves all images, you can disable this option. This technique can substantially improve resource utilization.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;KeepAliveTimeout:default:15&lt;br /&gt;&lt;/strong&gt;The number of seconds to keep the socket connection alive. This time includes the generation of content by the server and acknowledgements by the client. If the client does not respond in time, it must make a new connection.&lt;br /&gt;&lt;br /&gt;This value should be kept low as the socket will be idle for extended periods otherwise.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;MaxKeepAliveRequests: default:100&lt;/strong&gt;&lt;br /&gt;Socket connections will be terminated when the number of requests set by MaxKeepAliveRequests is reached. Keep this to a high value below MaxClients or ThreadsPerChild.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;TimeOut: default:300&lt;/strong&gt;&lt;br /&gt;Disconnect when idle time exceeds this value. You can set this value lower if your clients have low latencies.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;LimitRequestBody: default:0&lt;/strong&gt;&lt;br /&gt;Maximum size of a PUT or POST. O means there is no limit.&lt;br /&gt;&lt;br /&gt;If you do not require DNS lookups and you are not using the htaccess file to configure Apache settings for individual directories you can set:&lt;br /&gt;&lt;br /&gt;# disable DNS lookups: PHP scripts only get the IP address&lt;br /&gt;HostnameLookups off&lt;br /&gt;&lt;br /&gt;# disable htaccess checks&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;Directory /&amp;gt; &lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;AllowOverride &lt;b&gt;none &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;/Directory&amp;gt; &lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;If you are not worried about the directory security when accessing symbolic links, turn on FollowSymLinks and turn off SymLinksIfOwnerMatch to prevent additional lstat() system calls from being made:&lt;br /&gt;&lt;br /&gt;Options FollowSymLinks&lt;br /&gt;&lt;br /&gt;#Options SymLinksIfOwnerMatch&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113816766309215379?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113816766309215379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113816766309215379' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113816766309215379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113816766309215379'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/improving-php-performance-on-apache.html' title='improving php performance on apache'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113813927297407614</id><published>2006-01-24T13:43:00.000-08:00</published><updated>2006-04-07T00:19:30.356-07:00</updated><title type='text'>Tuning IIS for PHP</title><content type='html'>IIS is a multi-threaded web server available on Windows NT and 2000. From the Internet Services Manager, it is possible to tune the following parameters:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Performance Tuning based on the number of hits per day&lt;/strong&gt;: Determines how much memory to preallocate for IIS. (Performance Tab).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Bandwidth throttling&lt;/strong&gt;: Controls the bandwidth per second allocated per web site. (Performance Tab).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Process throttling&lt;/strong&gt;: Controls the CPU% available per Web site. (Performance Tab).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Timeout&lt;/strong&gt;: Default is 900 seconds. Set to a lower value on a Local Area Network. (Web Site Tab).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;HTTP Compression&lt;/strong&gt;: In IIS 6, you can compress dynamic pages, html and images. Can be configured to cache compressed static html and images. By default compression is off.&lt;br /&gt;&lt;br /&gt;HTTP compression has to be enabled for the entire physical server. To turn it on open the IIS console, right-click on the server (not any of the subsites, but the server in the left-hand pane), and get Properties. Click on the Service tab, and select "Compress application files" to compress dynamic content, and "Compress static files" to compress static content.&lt;br /&gt;&lt;br /&gt;You can also configure the default isolation level of your web site. In the Home Directory tab under Application Protection, you can define your level of isolation. A highly isolated web site will run slower because it is running as a separate process from IIS, while running web site in the IIS process is the fastest but will bring down the server if there are serious bugs in the web site code. Currently I recommend running PHP web sites using CGI, or using ISAPI with Application Protection set to high.&lt;br /&gt;&lt;br /&gt;You can also use regedit.exe to modify following IIS 5 registry settings stored at the following location:&lt;br /&gt;&lt;br /&gt;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Inetinfo\Parameters&lt;br /&gt;&lt;strong&gt;MemCacheSize&lt;/strong&gt;: Sets the amount of memory that IIS will use for its file cache. By default IIS will use 50% of available memory. Increase if IIS is the only application on the server. Value is in megabytes.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;MaxCachedFileSize&lt;/strong&gt;: Determines the maximum size of a file cached in the file cache in bytes. Default is 262,144 (256K).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;ObjectCacheTTL&lt;/strong&gt;: Sets the length of time (in milliseconds) that objects in the cache are held in memory. Default is 30,000 milliseconds (30 seconds).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;MaxPoolThreads&lt;/strong&gt;: Sets the number of pool threads to create per processor. Determines how many CGI applications can run concurrently. Default is 4. Increase this value if you are using PHP in CGI mode.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;ListenBackLog&lt;/strong&gt;: Specifies the maximum number of active Keep Alive connections that IIS maintains in the connection queue. Default is 15, and should be increased to the number of concurrent connections you want to support. Maximum is 250.&lt;br /&gt;&lt;br /&gt;If the settings are missing from this registry location, the defaults are being used.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;High Performance on Windows: IIS and FastCGI&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;After much testing, I find that the best PHP performance on Windows is offered by using IIS with FastCGI. CGI is a protocol for calling external programs from a web server. It is not very fast because CGI programs are terminated after every page request. FastCGI modifies this protocol for high performance, by making the CGI program persist after a page request, and reusing the same CGI program when a new page request comes in.&lt;br /&gt;&lt;br /&gt;As the installation of FastCGI with IIS is complicated, you should use the &lt;a href="http://phplens.com/phpeverywhere/easywindows"&gt;EasyWindows PHP Installer&lt;/a&gt;. This will install PHP, FastCGI and Turck MMCache for the best performance possible. This installer can also install PHP for Apache 1.3/2.0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20648899-113813927297407614?l=blinduser.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blinduser.blogspot.com/feeds/113813927297407614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20648899&amp;postID=113813927297407614' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113813927297407614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20648899/posts/default/113813927297407614'/><link rel='alternate' type='text/html' href='http://blinduser.blogspot.com/2006/01/tuning-iis-for-php.html' title='Tuning IIS for PHP'/><author><name>justin silverton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20648899.post-113800278606827579</id><published>2006-01-22T23:52:00.000-08:00</published><updated>2006-01-23T13:32:04.623-08:00</updated><title type='text'>Five Tips for Freelance PHP Coders</title><content type='html'>&lt;strong&gt;By Elizabeth Naramore&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Introduction &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If you've decided that working for yourself as a self-employed web developer or PHP coder sounds like your cup of tea, but you feel as if the task is a bit daunting, then listen up. We've put together a list of helpful tips that will enable you to go wherever it is you want your own business to go. You should know that these are in no particular order and we consider them all equally important. As well, please be advised that this is by no means a guarantee to your success, nor is it a comprehensive list of potential obstacles you may encounter.&lt;br /&gt;&lt;br /&gt;1. &lt;strong&gt;Guard Your Reputation With Your Life&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Your reputation is the most important asset you have, and you should treat it as such. You might be the most competent coder on the planet, but if you have a reputation for being difficult to work with, or unreliable, getting new clients will be more difficult, you will lose referrals from current clients and you will find you will have to prove yourself over and over again. Don't make promises you can't keep, and remember that your actions today may have a profound effect on the future success of your business. Maintaining a contract business is difficult enough without you inadvertently sabotaging your own efforts.&lt;br /&gt;&lt;br /&gt;2. &lt;strong&gt;Be Passionate About Your Work&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Clients want to see genuine enthusiasm and they will take comfort in the fact that you have a personal investment in their web site. A larger company may be able to offer the same coding services that you can, but you can use that "personal touch" to your advantage.&lt;br /&gt;&lt;br /&gt;3. &lt;strong&gt;Be Responsive And Communicate Often&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Even if things are crazy or if you are extremely behind schedule, taking five minutes to make a quick change for a client's site or sending a quick e-mail to update your client about the status of his project will really go a long way in diffusing a potentially damaging situation. Of course, this will only buy you a little time, but it is much better than ignoring a client altogether and aggravating the situation.You can also provide status reports for your clients weekly or bi-weekly, so they are kept in the loop as to how things are progressing. Knowing that you will have to be presenting these reports helps you maintain accountability for the project and keep you moving forward, as well as keeping your client informed.Along with this goes the advice of promptly returning phone calls and e-mails. Some of us are averse to using the phone, but by giving your client the courtesy of returning a phone call, you are in essence communicating that you v
