Edmonds Commerce : Web Development, Design, SEO

Archive for March, 2008

MySQL DB Admin GUI for Windows / XAMPP

Tuesday, March 25th, 2008

If you are using windows (with XAMPP) to develop your MySQL applications, you might currently be using phpMyAdmin for your DBA tasks. The phpMyAdmin package is an awesome tool and is a must have, however due to the fact that it runs under Apache and PHP - it can be tricky to use when dealing with big database dumps or other heavy processing.

At this stage, you may decide that the best thing to do is to hit the command line. That’s fair enough if you don’t mind using command line applications. If however you fancy keeping it GUI, then I can highly recommend using the free community edition of SQLyog.

This open source community edition is a free version of their main Enterprise Edition software which is paid for. If you are doing a lot of DBA work then you may want to consider supporting this company by handing over some cash for the fully featured software. The enterprise edition can handle external as well as local MySQL database administration, using SSH, SSL or HTTP/HTTPS tunnelling. It features all kinds of GUI functionality for building your database schema and designing queries. For the serious DBA’s out there it may well be worth a look.

For the occasional big DB import / export session on the local windows host though, the community edition does seem to suffice.

You can download both the community and the enterprise edition here:

http://www.webyog.com/en/downloads.php

To compare functionalty check out this page:

http://www.webyog.com/en/sqlyog_feature_matrix.php

Advanced PHP Debug Function

Thursday, March 20th, 2008

I have taken the debug function about as far as I can think of. This function will now take a variable and display it all in a nice easy to read format. It will also give the name of the variable being examined. It works with html, using htmlentites. It preserves the tab layout formatting for arrays making it easy to understand:

Heres How to Use It:

PHP:
  1. //For example, displaying $_POST information
  2. dbug($_POST);
  3.  
  4. //If using inside a function
  5. function something($blah){
  6. dbug($blah, get_defined_vars());
  7. }

Note that if called within the scope of a function (for example) you must give get_defined_vars().

And here are the neccessary functions

PHP:
  1. //DEbug Functions
  2.  
  3. //convert tabs to spaces
  4. function tab2space($text){
  5.     $text = str_replace('  ', '  ', $text);
  6.     $text = str_replace("\t", '    ', $text);
  7.     return $text;
  8. }
  9.  
  10. //return name of variable passed by reference
  11. function vname(&$var, $scope=false){
  12.     if($scope) $vals = $scope;
  13.     else      $vals = $GLOBALS;
  14.     $old = $var;
  15.     $new = 'THISONE';
  16.     $var = $new;
  17.     $vname = false;
  18.     foreach($vals as $key => $val) {
  19.         if($val !=='var'){
  20.             if($val === $new) $vname = $key;
  21.         }
  22.     }
  23.     $var = $old;
  24.     return $vname;
  25.   }
  26.  
  27.  
  28. function dbug(&$item, $scope=false){
  29.     $vname = vname(&$item,$scope);
  30.     echo '<hr><h3>Debug Info: $' . $vname  . '</h3>' . tab2space(nl2br(htmlentities(var_export($item, true)))) . '<hr>';   
  31. }

PHP Save Images Using cURL

Tuesday, March 18th, 2008

Some hosts disabled the ini setting allow_url_fopen. This also means that the ability to easily grab images by calling imagecreatefromjpeg($img) where $img is a url for an external image does not work.

This is a shame as this technique is pretty easy..

PHP:
  1. $remote_img = 'http://www.somwhere.com/images/image.jpg';
  2. $img = imagecreatefromjpeg($remote_img);
  3. $path = 'images/';
  4. imagejpeg($img, $path);

However I was tearing my hair out trying to get a product feed integration system to work on a host that has disabled the allow_url_fopen mechanism which meant the above wouldnt work.

Thankfully cURL was still working. So here is the function I made for grabbing and saving an image using cURL instead:

PHP:
  1. //Alternative Image Saving Using cURL seeing as allow_url_fopen is disabled - bummer
  2. function save_image($img,$fullpath){
  3.     $ch = curl_init ($img);
  4.     curl_setopt($ch, CURLOPT_HEADER, 0);
  5.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  6.     curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
  7.     $rawdata=curl_exec($ch);
  8.     curl_close ($ch);
  9.     if(file_exists($fullpath)){
  10.         unlink($fullpath);
  11.     }
  12.     $fp = fopen($fullpath,'x');
  13.     fwrite($fp, $rawdata);
  14.     fclose($fp);
  15. }

Another Problem Solved :-)

Debugging PHP Scripts

Monday, March 17th, 2008

When coding PHP, or more frequently when trying to customise or fix someone elses code, it can sometimes be tricky to figure out exactly what is going wrong.

In this kind of situation, it is often neccessary to go through the flow of the script and view the contents of the various strings and arrays at that stage of the script.

I have written this small function to help in this process:

PHP:
  1. function dbug($item){
  2.     echo '<hr><h3>Debug Info</h3><pre>' . (var_export($item, true)) . '</pre><hr>'
  3. }

This script will take any item and print out detailed information for you in a nicely formatted and easy to read way.

For an example when you might decide to use this functionality, you could check the contents of your $_POST

PHP:
  1. <?php
  2. /*very top of script */
  3. dbug($_POST);

MySQL Add Column if Not Exists - PHP Function

Thursday, March 13th, 2008

This is a nice little function which I struggled to find elsewhere on the web.

As discussed elsewhere this is not the kind of thing that should be included in a public facing script, but for administration tools etc its pretty handy:

PHP:
  1. function add_column_if_not_exist($db, $column, $column_attr = "VARCHAR( 255 ) NULL" ){
  2.     $exists = false;
  3.     $columns = mysql_query("show columns from $db");
  4.     while($c = mysql_fetch_assoc($columns)){
  5.         if($c['Field'] == $column){
  6.             $exists = true
  7.             break;
  8.         }
  9.     }      
  10.     if(!$exists){
  11.         mysql_query("ALTER TABLE `$db` ADD `$column`  $column_attr");
  12.     }
  13. }

This function grabs the column information for the table, then it loops through the info looking for the column. If it finds the column then it acknowledges that it exists and ceases the loop.

After this stage, the function checks to see if exists is true or not, and if it is not true then it adds the column with the attributes defined when calling the function.

The default attributes are for a VARCHAR field up to 255 characters in length and NULL enabled.

PHP and Zip Files

Thursday, March 13th, 2008

There aren't many things you can't do with PHP. One of the things you can do is deal with zip files.

PHP has a built in class for dealing with zip files which allows you to create them, unpack them, add and delete things from them and generally use them within your scripts.

Recently on a spidering / product feed integration job that I have been working on I needed to grab a load of image zip files and unpack them all into a folder called 'images/' (surprisingly enough)

Here is how I did it:

PHP:
  1. function unpack_zips($directory, $destination = 'images/'){
  2.     $files = dir_list($directory);
  3.     //print_r($files);
  4.     $zips = array();
  5.     foreach($files as $k=>$file){
  6.         if(stristr($file, '.zip')){
  7.             $zips[] = $directory . $file;
  8.         }
  9.     }
  10.     print_r($zips);
  11.     $zip = new ZipArchive;
  12.     foreach($zips as $z){
  13.         if ($zip->open($z) === TRUE) {
  14.             $zip->extractTo($directory . $destination);
  15.             $zip->close();
  16.             //echo "<h3>$z OK</h3>";
  17.         } else {
  18.             echo"<h3 style=\"color: red;\">$z Failed</h3>";
  19.             bottom();
  20.         }   
  21.     }
  22. }
  23.  
  24. function dir_list($directory){
  25.     echo $directory;
  26.     if ($handle = opendir($directory)) {
  27.         while (false !== ($file = readdir($handle))) {
  28.             if($file != '.' && $file != '..'){
  29.                 $return[] = $file;
  30.             }
  31.         }
  32.         closedir($handle);
  33.         return $return;
  34.     }else{   
  35.         return false;
  36.     }
  37. }

There are two functions. The first function is the one that deals with the Zip files. The second function is called by the first function and simply lists all files within a specified directory.

These two functions combined allowed me to find all zip files in a particular folder and then unpack them all into a destination folder.

Related Resources

http://www.phpclasses.org/browse/package/945.html

http://www.phpit.net/article/creating-zip-tar-archives-dynamically-php/

Online Backend System

Monday, March 10th, 2008

What could be more convenient than having all of your business systems integrated into one online package. No more hassles moving information from online to offline systems. No more out of date or vague information regarding stock figures or supplier invoices.

For an online business with a well specified and rigorously backed up dedicated server, it makes a lot of sense to move away from applications that run on the desktop to applications that run on the server. For your employees to interact with your business systems, they only need a broadband internet connection and a web browser. This in turn opens up the possiblity of moving away from costly and insecure windows desktops to a more robust and cheaper to run Ubuntu Linux desktop. Preloaded with firefox web browser and the open office suite of office applications, Ubuntu is an excellent choice for a business desktop.

If you want to increase productivity whilst simultaneously slashing operating costs, get in touch with Edmonds Commerce today to find out how a bespoke online business system can improve your business.

Product Feed Integration and Scraping Products from Supplier Web Sites

Wednesday, March 5th, 2008

One of the big tasks that any ecommerce retail business must undertake is the continual updating and inserting of products into the catalogue. Done one by one, this task can take a ridiculous amount of time. In some instances there is no better option, but in the vast majority of cases there is!

Product Feed

The ideal scenario is that your supplier makes available an up to date product feed which is regularly updated and contains all of the information you need to insert those products into your catalogue. The challenge with this is that it is highly unlikely that you will literally be able to upload this data as is. The reason being that each ecommerce system has its own quirks and separate ways of doing things. Before you can upload this data into your feed, it is highly likely that it will need to be altered and prepared for insertion.

You could do updating by hand - but that brings us back to our first point. Doing things by hand can take a ridiculously large amount of time. Instead - we recommend that you have a script which does all this preparation for you.

In fact this task is something that Edmonds Commerce specialise in. Not least because it is something that we have done plenty of and so we have a good understanding of how to do the job. Furthermore - we understand how to do the job well.

Spidering and Scraping Products from Supplier Web Site

If your supplier does not provide a feed, or if the feed they supply does not have all of the information that you want, you might think you are stuck. You are not!

It is perfectly possible to build a system which will visit every product on your suppliers web site and grab all of the information and pictures and then save them into a format that you can insert into your catalogue system. It is even possible to extend the scraping system so that it goes all the way and inserts the products into your site for you.

Again this is something that Edmonds Commerce specialise in.

Conclusion

If you find that you or your staff are spending large amounts of time manually copying and pasting information from supplier web sites - you need to ask yourself if that is really cost effective. Whilst developing a script to process a feed or scrape a supplier web site might involve a significant initial outlay - the humongous saving in staff time ensures that you will quickly recoup this cost and then will be straight into a profitable scenario. Furthermore your catalogue will be absolutely up to date with the latest pictures, information and prices meaning that you have the best chance to sell those products.

If you want to discuss how Edmonds Commerce could help you achieve these great goals of cost reduction and totally up to date catalogue - please do get in touch.

Apache, mod_rewrite and SEO

Tuesday, March 4th, 2008

Dynamic database driven web sites tend to use various GET variables to define which content to display on that particular page. This is perfectly normal and reasonable. However it does make things a little confusing for search engine spiders as not every GET variable pertains to alternative content. Often GET is used for session, or maybe referrer tracking - or pretty much any piece of information which your web site may use.

This can mean that your product page about fluffy banana shaped teddy bears has the address

CODE:
  1. mysite.com/index.php?cat=123&amp;product=333&amp;breadcrumb=123_43_2&amp;session_id=89o7324kjhlef8y234h

Not only does this make life difficult for search engine spiders, but its not exactly the most memorable url for your visitors either.

There is a solution and its called mod_rewrite.

Apache is part of the LAMP stack which is one of the most popular software and operating system combinations used to power web servers. Mod_rewrite is a particular plugin for Apache which allows you to create rules which will rewrite urls when they meet specific criteria.

The only really tricky part about setting up rewrite rules is that by neccessity they rely on regular expressions. Regular expressions can seem like a dark art at first, and often even for a seasoned coder familiar with a bit of regex, decoding someone elses expression can take a bit of brain power to say the least!

However there is no real reason to worry as all you really need to do is to learn how to achieve what you want. You do not need to learn the ins and outs of every particular regex function or operator.

For example take this

CODE:
  1. RewriteEngine On
  2.  
  3. RewriteRule ^(.*)\.p(.*).html$ product.php?products_id=$2&amp;%{QUERY_STRING} [L]

This rewrite rule will take a url in the form of:
mysite.com/whatever-you-want-here.p.[products_id].html

And automatically convert it so that to your web system it is the url:
mysite.com/product.php?products_id=[products_id]

All you need to do now is devise a nice way of dynamically generating all of those nice keyword rich urls for your product pages and you are in business.

If you want any help enabling the power of mod_rewrite to give your web site properly search engine friendly URLS, get in touch today.

Related Blogs
http://www.crazyleafdesign.com/blog/check-if-mod_rewrite-is-activated-on-your-server/
http://www.jtpratt.com/2008/01/22/how-to-fix-htaccess-file-for-mod_rewrite-and-addhandler-on-godaddy-subdomain/
http://pensae.com/2008/01/14/when-mod_rewrite-doesnt-work/
http://www.logon2.com.au/blog/archive/web-design/php-apache-mod-rewrite-tutorial/
http://blogs.ittoolbox.com/c/codesharp/archives/when-bugs-become-features-22068
http://geniustechblog.com/htaccess-mod_rewrite-tutorials-developer-tools/
http://jeremyhermanns.org/2006/09/30/learning-to-use-mod_rewrite/

MySQL Copy Table from One Database to Another

Monday, March 3rd, 2008

Sometime in MySQL you want to copy an entire table from one database to a separate database. One example of when you would want to do this is if you are making a backup of a table before you apply some kind of processing to that table. There is nothing worse than ruining a database table and losing valuable information. To make an instant backup is so easy that there really is no excuse not to make backups at important or risky stages.

Here is how to do it:

MySQL:
  1. DROP TABLE IF EXISTS `backup_db.backup_table`;
  2. CREATE TABLE `backup_db.backup_table` SELECT * FROM `live_db.live_table`;

This will delete your existing backup table completely, then will remake it copying all structural information and content from the live_table in the live_db.

Related Blogs
http://www.phpclasses.org/browse/package/4017.html
http://www.sematopia.com/?p=61
http://www.yinfor.com/blog/archives/2008/02/mysql_backup_and_recovery_meth.html