PHP Freaks Content

The latest tutorials and blog posts from PHP Freaks.

10 Signs of Crappy PHP Software

pLike it or not, as a professional developer, sooner or later you are going to do some customising (if you are lucky, quot;extendingquot;) of existing software./p pIf you are not familiar with the software, it is good advice to look into it before accepting the job. I had to learn that the hard way. But how do you recognize crappy applications without getting knee deep into the code? 10 pointers to identify crappy PHP software quickly.../p h31. The software tries to reinvent the object model, or quot;fixquot; language features./h3pSee if you can find a class called quot;Objectquot;. If you find it, it's a pretty clear indication that the author is in the business of trying to reinvent the object model (most commonly because of his own lacking understanding of OO). It is safe to assume that his quot;fixesquot; won't stop there. Unplug your phone and hide under your desk./p h32. The code includes user defined global variables /h3pA search in the code for quot;globalquot; or quot;$GLOBALSquot; may reveal something like this:/p ol class="code"liglobalnbsp;$database,nbsp;$my,nbsp;$mainframe;/li/olpThe infamous global variable. If you can tell me what those last two variables contain you are either intimate with the software I pulled it from, or you're psychic. Unlimited bonus points if you can say what code has had it's claws on it before execution flow got to this point. In short, steer bwell/b clear./p h33. Scattered HTML and SQL/h3pSearch for some common SQL and HTML strings. You should be able to determine very quickly whether these are appropriate places for HTML or SQL. If you find HTML and SQL in the same file, quot;crappynessquot; is most definitely confirmed./p h34. Classes do too much/h3pFind the 3 largest class files by bit size. Take a look at the class name. Does it indicate a distinct responsibility? Look at the methods. Are the tasks they perform closely related? If not, run away screaming./p h35. Lots of properties are public or lots of properties are static/h3pIf lots of properties are declared quot;public staticquot;, triple your quote. If I have to explain why, maybe there's an open position on the development team of the software for you./p h36. Multiple levels of inheritance/h3pMore than 2 levels inheritance should be avoided like the plague. I stake my life on the resulting objects having too much unrelated behaviour (ok, maybe not my life, but if you find a proper use of more than 2 levels of inheritance, I'll buy you a beer)./p h37. The authors span style="text-decoration:underline"try/span to use Design Patterns/h3pWhether or not the authors have a clue is easily determined by searching for some of the most common design patters. Search the code base and/or documentation for quot;factoryquot;, quot;decoratorquot;, quot;strategyquot; etc. If present, you can pretty quickly determine whether the authors know their stuff or are trying to look interesting. That is, if you know how the code should look. If not, refuse to take the project until you do./p h38. The software messes with the error level/h3pWell written applications run fine at any error level. Searching the files for /error_level\(.*\)/ should do the trick. In case of hits, try replacing the value with E_STRICT. That's little more than a formality though./p h39. In the code base, there is a directory called quot;corequot;/h3pThis is usually used as an excuse to have the whole application dependent on whatever is in there. Despite the appeal of the term (it span style="text-decoration:underline"does/span make the contents sound pretty cool and important), defining a quot;corequot; is a sign of bad design./p h310. The software uses it's own template language./h3pBe afraid. Very afraid. These guys are definitely in the business of reinventing the wheel. Ignore this warning and you will find yourself spending the better part of a day simulating a quot;forquot; loop./pdiv class="feedflare" a href="http://feeds.feedburner.com/~ff/phpfreaks?a=eIJ6VnDEJdw:OFHdvWl2xLk:yIl2AUoC8zA"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=yIl2AUoC8zA" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=eIJ6VnDEJdw:OFHdvWl2xLk:V_sGLiPBpWU"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=eIJ6VnDEJdw:OFHdvWl2xLk:V_sGLiPBpWU" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=eIJ6VnDEJdw:OFHdvWl2xLk:qj6IDK7rITs"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=qj6IDK7rITs" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=eIJ6VnDEJdw:OFHdvWl2xLk:gIN9vFwOqvQ"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=eIJ6VnDEJdw:OFHdvWl2xLk:gIN9vFwOqvQ" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=eIJ6VnDEJdw:OFHdvWl2xLk:F7zBnMyn0Lo"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=eIJ6VnDEJdw:OFHdvWl2xLk:F7zBnMyn0Lo" border="0"/img/a /divimg src="http://feeds.feedburner.com/~r/phpfreaks/~4/eIJ6VnDEJdw" height="1" width="1"/

Using MySQL Administrator with WampServer

pFor those readers who do not develop PHP on Windows platform a href="http://www.wampserver.com/en/"WampServer/a is probably the most popular Apache + MySQL + PHP package for Windows. MySQL Administrator on the other hand, is a part of a href="http://dev.mysql.com/downloads/gui-tools/5.0.html"MySQL GUI Tools/a package./p pThe problem with this pair, is that they don't want to work together. At least not right out of box. MySQL Administrator fails to find mysql service process as installed by WampServer. This leads to infamous 'Could not find settings' error message./p pimg src="http://img3.imageshack.us/img3/5092/couldnotfindsettings.png" alt="" //p pYou still will be able to use MySQL Administrator, but some of its features will be unavailable - among them quite important 'Startup variables' that lets you configure your server./p pThe reason is simple. WampServer keeps MySQL's config file in a directory, that is not checked by MySQL Administrator's searching algorithm./p pLuckily, the solution is also simple./p pOpen registry editorbr / Windows XP: Go to ttStart/tt gt; ttRun.../tt type in ttregedit/tt and press Enterbr / Vista: Go to ttStart/tt, type ttregedit/tt into search box and press Enter/p pA word of warning: be careful when using registry editor, as you might break your system if you change wrong variables./p pUsing tree on the left go to:br / ttHKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\wampmysqld/tt/p pIn the window on the right find ttImagePath/tt variable, double click it's name./p pIn the dialog that opens you should see something like this:br / ttc:\wamp\bin\mysql\mysql5.1.33\bin\mysqld.exe wampmysqld/ttbr / (MySQL's version may vary)/p pChange it like this:br / ttquot;c:\wamp\bin\mysql\mysql5.1.33\bin\mysqld.exequot; --defaults-file=quot;c:\wamp\bin\mysql\mysql5.1.33\my.iniquot; wampmysqld/ttbr / (be careful not to miss any double quotes!/p pClose registry editor, then restart you MySQL server from WampServer's tray menu./p pMySQL Administrator should work fine now./p pThat would be it ;)/p p----/p pa href="http://forums.mysql.com/read.php?34,128259,128297#msg-128297"MySQL Forums post, where I've found this solution/a/pdiv class="feedflare" a href="http://feeds.feedburner.com/~ff/phpfreaks?a=owFd9iY8PoA:klud5IERs3o:yIl2AUoC8zA"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=yIl2AUoC8zA" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=owFd9iY8PoA:klud5IERs3o:V_sGLiPBpWU"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=owFd9iY8PoA:klud5IERs3o:V_sGLiPBpWU" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=owFd9iY8PoA:klud5IERs3o:qj6IDK7rITs"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=qj6IDK7rITs" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=owFd9iY8PoA:klud5IERs3o:gIN9vFwOqvQ"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=owFd9iY8PoA:klud5IERs3o:gIN9vFwOqvQ" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=owFd9iY8PoA:klud5IERs3o:F7zBnMyn0Lo"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=owFd9iY8PoA:klud5IERs3o:F7zBnMyn0Lo" border="0"/img/a /divimg src="http://feeds.feedburner.com/~r/phpfreaks/~4/owFd9iY8PoA" height="1" width="1"/

SSH Auto-mount Network Share

p(bBeware/b - iThis blog/tutorial is directed towards linux based users/i)br / When doing any type of work, especially web work, one of the royal pains is FTPing to your server, or any type of file transfer. Well now you can make it quick and painless. Let me introduce SSHFS. There are 3 major components when creating the SSHFS, and I will guide you through creating and installing all of the necessary steps. Now you can mount and use your file system to automatically upload files and folders to your server with ease./p pspan style="text-decoration:underline"iThe 3 Major components:i/i/i/span/p ol liSSH Automatic Login/li liInstall SSHFS/li liMount your folder(s)/li/olh3SSH Automatic Login/h3pRun this command (with the obvious variable substitutions). It should create a public ssh key on your server./p pre class="bbcode"ssh-copy-id [-i [identity_file]] [user@]machine/preol lissh-keygen -t dsa/li lissh-copy-id user@machiner./li/olp Check to make sure it's there, the file should be called, quot;authorized_keysquot;.br / /p pre class="bbcode"ls -al ~/.ssh//prep If you're having trouble with this part, you can reference this tutorial which breaks this component into smaller steps: a href="http://wp.uberdose.com/2006/10/16/ssh-automatic-login/"SSH Automatic Login/a./p h3Install SSHFS/h3pre class="bbcode"sudo apt-get install sshfs/prep Or use whatever package manager your distribution provides./p h3Mount/h3p Create a shell script, we'll call it quot;mount.shquot;, and add the contents:br / /p pre class="bbcode"sshfs [user]@[your_server].com:/dir/on/server /dir/to/mount/prep Run the script:br / /p pre class="bbcode"./mount.sh/prep Go to the mounted directory and run the 'ls' command to make sure all of your files/folders from your server show up in your local directory./p pAfter you have this successfully working you should at it to your startup scripts.br / /p pre class="bbcode"System gt;gt; Preferences gt;gt; Sessions gt;gt; [add_a_new_entry]/prepYou should be all set. You should have an automatic SSH login (no prompt for a password) from your computer to your server and a mounted folder to your server that acts as an automatic FTP client. The files in your mounted directory should be synced with that of your server. Now all you have to do is move or copy your desired files/folders into the mounted directory, and voila, they're on your server./pdiv class="feedflare" a href="http://feeds.feedburner.com/~ff/phpfreaks?a=4w4Nakpxdh4:zqoO3UsDSOY:yIl2AUoC8zA"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=yIl2AUoC8zA" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=4w4Nakpxdh4:zqoO3UsDSOY:V_sGLiPBpWU"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=4w4Nakpxdh4:zqoO3UsDSOY:V_sGLiPBpWU" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=4w4Nakpxdh4:zqoO3UsDSOY:qj6IDK7rITs"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=qj6IDK7rITs" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=4w4Nakpxdh4:zqoO3UsDSOY:gIN9vFwOqvQ"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=4w4Nakpxdh4:zqoO3UsDSOY:gIN9vFwOqvQ" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=4w4Nakpxdh4:zqoO3UsDSOY:F7zBnMyn0Lo"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=4w4Nakpxdh4:zqoO3UsDSOY:F7zBnMyn0Lo" border="0"/img/a /divimg src="http://feeds.feedburner.com/~r/phpfreaks/~4/4w4Nakpxdh4" height="1" width="1"/

MySQL University: Boosting Performance With MySQL 5.1 Partitioning

pIt's been some time some time since we had a MySQL Uni session subject that could be interesting to an 'average' PHP developer. The one that's going to take place next Thursday will definitely be of this sort./p pIntroduced in MySQL 5.1, partitioning lets you divide your tables into smaller chunks of data... while still keeping them in one table. No more need for `invoices2006`, `invoices2007`, `invoices2008` tables to cope with archival data, no more wicked UNIONs. Now you can tell MySQL to keep invoices (or whatever you need to keep) from one year separate from all other years, thus improving queries that only deal with records from one year./p pThat's just a simple example, as there are much more to partitioning than that. I urge you therefore to attend MySQL Uni's Dimdim session this Thursday, June 4th at 13:00GMT./p pThe session will be presented by Giuseppe Maxia a.k.a. a href="http://datacharmer.blogspot.com/"The Data Charmer/a. I attended one of his sessions in the past, and he seems like a very interesting person to listen to./p pCheck the a href="http://forge.mysql.com/wiki/MySQL_University"MySQL University home page/a for details (and possible last minute schedule changes!)br / For more information about MySQL University, see a href="http://www.phpfreaks.com/blog/mysql-university"my introductory post/a/pdiv class="feedflare" a href="http://feeds.feedburner.com/~ff/phpfreaks?a=TWYCiLEnVE4:EOnLvrurW0s:yIl2AUoC8zA"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=yIl2AUoC8zA" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=TWYCiLEnVE4:EOnLvrurW0s:V_sGLiPBpWU"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=TWYCiLEnVE4:EOnLvrurW0s:V_sGLiPBpWU" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=TWYCiLEnVE4:EOnLvrurW0s:qj6IDK7rITs"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=qj6IDK7rITs" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=TWYCiLEnVE4:EOnLvrurW0s:gIN9vFwOqvQ"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=TWYCiLEnVE4:EOnLvrurW0s:gIN9vFwOqvQ" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=TWYCiLEnVE4:EOnLvrurW0s:F7zBnMyn0Lo"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=TWYCiLEnVE4:EOnLvrurW0s:F7zBnMyn0Lo" border="0"/img/a /divimg src="http://feeds.feedburner.com/~r/phpfreaks/~4/TWYCiLEnVE4" height="1" width="1"/

or die() must die

pThis is something I constantly see on the a href="http://www.phpfreaks.com/forums/"PHP Freaks forums/a, and I absolutely hate it. It's the infamous ttor die()/tt statement./p ol class="code"li$resultnbsp;=nbsp;mysql_query('SELECTnbsp;foonbsp;FROMnbsp;bar',nbsp;$db)nbsp;ornbsp;die('Querynbsp;failed:nbsp;'nbsp;.nbsp;mysql_error($db));/li/olpI see it all the time, and I see people telling other people to do that all the time. It's plain simply bad practice and it's time that people start to understand this. When I confront people with it they usually say something along the lines of quot;oh, but it's just for debugging purposesquot;. Okay, so I tend to put ttecho/tt and ttvar_dump()/tt statements in my code for debugging as well. However, this is not the same. It's quite obvious that you wouldn't want an array var_dump'ed to the screen in the final application, but you certainly do want some sort of error handling for when e.g. database queries fail./p pThe ttor die()/tt trick is a very poor choice for several reasons:/p ol liIt's not a very nice way to present the user with an error message./li liUsing for instance the mysql_error() call with it, as many people do, exposes information that should never get output in a production environment (see: a href="http://www.phpfreaks.com/tutorial/php-security"PHP Security/a)/li liYou cannot catch the error in any way./li liYou cannot log the error./li liYou cannot control whether it should be output to the screen or not. It's okay to do that in a development environment, but certainly not in a production environment./li liIt prevents you from doing any sort of cleanup. It just ends the script abruptly./li/olpSo if your little ttor die()/tt trick is just for debugging purposes, how are you going to handle potential errors iafter/i you've deployed your application? Fortunately, PHP does actually include a function that allows you to raise PHP errors on runtime: tta href="http://php.net/trigger_error"trigger_error()/a/tt/p pThis function allows you to raise errors of type E_USER_NOTICE, E_USER_WARNING and E_USER_ERROR. These behave exactly like their non-USER counterparts, i.e. errors of type E_USER_ERROR are fatal and halts execution while the other two doesn't. If you are used to doing the ttor die()/tt it's also very easy to implement:/p ol class="code"li$resultnbsp;=nbsp;mysql_query('SELECTnbsp;foonbsp;FROMnbsp;bar',nbsp;$db)nbsp;ornbsp;trigger_error('Querynbsp;failed:nbsp;'nbsp;.nbsp;mysql_error($db),nbsp;E_USER_ERROR);/li/olpSyntactically this is very much like the previous code snippet, but much better. Because errors of these types behave like errors PHP would normally make you can also use all the facilities PHP has for a href="http://php.net/errorfunc"error handling/a. You can a href="http://php.net/set_error_handler"implement a custom error handler/a so you can display nice messages to your user, and you can a href="http://php.net/manual/en/errorfunc.configuration.php#ini.error-log"log the errors to a file/a. Finally you can a href="http://php.net/manual/en/errorfunc.configuration.php#ini.display-errors"disable output of errors/a in a production environment./p pAnother option is to use a href="http://php.net/manual/en/language.exceptions.php"exceptions/a. Example:/p ol class="code"liifnbsp;(!$resultnbsp;=nbsp;mysql_query('SELECTnbsp;foonbsp;FROMnbsp;bar',nbsp;$db))nbsp;{/lilinbsp;nbsp;nbsp;nbsp;thrownbsp;newnbsp;Exception('Younbsp;fail:nbsp;'nbsp;.nbsp;mysql_error($db));/lili}/li/olp Personally, I prefer exceptions because they're easily catchable using try-catch blocks, which makes it pretty easy to degrade if something unexpected, or rather an exception, something that doesn't behave as expected, occurs. As an added bonus you you will get a stack trace which aids in debugging./p pA great example of exception usage could be database transactions using a href="http://php.net/pdo"PDO/a (a href="http://php.net/mysqli"MySQLi/a supports it as well if you prefer that). When you normally run a query on a database server it will be committed instantaneously. When you start a transaction changes won't be committed until you explicitly say so. This allows you to rollback if you wish./p pWe might have a setup like this:/p pre class="bbcode"+---------+------------+-----------+-------+ | user_id | first_name | last_name | funds | +---------+------------+-----------+-------+ | 1 | Daniel | Egeberg | 500 | | 2 | John | Doe | 350 | +---------+------------+-----------+-------+/prepWe want to transfer 120 from Daniel to John. This involves two operations: 1) Removing funds from Daniel, and 2) Adding funds to John. We need both or none of those operations to finish successfully. Executing just one of them is not an acceptable scenario./p pHere is our transfer script:/p ol class="code"li$dbnbsp;=nbsp;newnbsp;PDO('mysql:host=localhost;dbname=test',nbsp;'user',nbsp;'password');/lili/lili$transferAmountnbsp;=nbsp;120;/lili$fromUserIdnbsp;=nbsp;1;/lili$toUserIdnbsp;=nbsp;2;/lili/lilitrynbsp;{/lilinbsp;nbsp;nbsp;nbsp;$db-gt;beginTransaction();/lilinbsp;nbsp;nbsp;nbsp;/lilinbsp;nbsp;nbsp;nbsp;$stmtnbsp;=nbsp;$db-gt;prepare('UPDATEnbsp;usersnbsp;SETnbsp;fundsnbsp;=nbsp;fundsnbsp;+nbsp;:amountnbsp;WHEREnbsp;user_idnbsp;=nbsp;:user_id');/lilinbsp;nbsp;nbsp;nbsp;/lilinbsp;nbsp;nbsp;nbsp;//nbsp;removenbsp;fundsnbsp;fromnbsp;sender/lilinbsp;nbsp;nbsp;nbsp;$stmt-gt;execute(array('amount'nbsp;=gt;nbsp;$transferAmountnbsp;*nbsp;-1,nbsp;'user_id'nbsp;=gt;nbsp;$fromUserId));/lilinbsp;nbsp;nbsp;nbsp;/lilinbsp;nbsp;nbsp;nbsp;//nbsp;addnbsp;fundsnbsp;tonbsp;recipient/lilinbsp;nbsp;nbsp;nbsp;$stmt-gt;execute(array('amount'nbsp;=gt;nbsp;$transferAmount,nbsp;'user_id'nbsp;=gt;nbsp;$toUserId));/lilinbsp;nbsp;nbsp;nbsp;/lilinbsp;nbsp;nbsp;nbsp;$db-gt;commit();nbsp;//nbsp;wenbsp;willnbsp;onlynbsp;getnbsp;tonbsp;thisnbsp;ifnbsp;bothnbsp;thenbsp;abovenbsp;queriesnbsp;executednbsp;successfully/lili}/lilicatchnbsp;(PDOExceptionnbsp;$e)nbsp;{/lilinbsp;nbsp;nbsp;nbsp;$db-gt;rollback();nbsp;//nbsp;damn...nbsp;well,nbsp;atnbsp;leastnbsp;wenbsp;cannbsp;rollnbsp;back/lilinbsp;nbsp;nbsp;nbsp;/lilinbsp;nbsp;nbsp;nbsp;echonbsp;'Sorry,nbsp;butnbsp;wenbsp;werenbsp;unablenbsp;tonbsp;transfernbsp;thenbsp;funds.nbsp;Pleasenbsp;contactnbsp;customernbsp;supportnbsp;ifnbsp;thenbsp;problemnbsp;persists.';/lilinbsp;nbsp;nbsp;nbsp;//nbsp;lognbsp;thisnbsp;incidentnbsp;somehow.nbsp;furthernbsp;infonbsp;isnbsp;availablenbsp;usingnbsp;$e-gt;getMessage()/lili}/li/olpFinally just a quick check that we did in fact transfer the money:/p pre class="bbcode"+---------+------------+-----------+-------+ | user_id | first_name | last_name | funds | +---------+------------+-----------+-------+ | 1 | Daniel | Egeberg | 380 | | 2 | John | Doe | 470 | +---------+------------+-----------+-------+/prepYup. Everything's good!/p pIn this case our good friend ttor die()/tt is simply not an option. If the first statement ran fine, but the second failed I would have just lost money on nothing, and because the programmer was too lazy to implement real error handling nobody would be able to figure out what happened, and the case couldn't be documented. I certainly would not appreciate that.../p pPeople need to stop that ttor die()/tt nonsense, and even more importantly, people need to stop teaching other people their own bad practice. Calling ttdie()/tt when something happens is inot/i an acceptable way of handling the situation./pdiv class="feedflare" a href="http://feeds.feedburner.com/~ff/phpfreaks?a=f6GhATCEMhk:w9RyBH2rnkw:yIl2AUoC8zA"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=yIl2AUoC8zA" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=f6GhATCEMhk:w9RyBH2rnkw:V_sGLiPBpWU"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=f6GhATCEMhk:w9RyBH2rnkw:V_sGLiPBpWU" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=f6GhATCEMhk:w9RyBH2rnkw:qj6IDK7rITs"img src="http://feeds.feedburner.com/~ff/phpfreaks?d=qj6IDK7rITs" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=f6GhATCEMhk:w9RyBH2rnkw:gIN9vFwOqvQ"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=f6GhATCEMhk:w9RyBH2rnkw:gIN9vFwOqvQ" border="0"/img/a a href="http://feeds.feedburner.com/~ff/phpfreaks?a=f6GhATCEMhk:w9RyBH2rnkw:F7zBnMyn0Lo"img src="http://feeds.feedburner.com/~ff/phpfreaks?i=f6GhATCEMhk:w9RyBH2rnkw:F7zBnMyn0Lo" border="0"/img/a /divimg src="http://feeds.feedburner.com/~r/phpfreaks/~4/f6GhATCEMhk" height="1" width="1"/