<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>James Rossiter</title>
	<atom:link href="http://jamesrossiter.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jamesrossiter.wordpress.com</link>
	<description>My Technical Blog for Design and Development</description>
	<lastBuildDate>Wed, 18 Jan 2012 16:36:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='jamesrossiter.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/ea2222d28e423df4ccf4dc213c9c113b?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>James Rossiter</title>
		<link>http://jamesrossiter.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://jamesrossiter.wordpress.com/osd.xml" title="James Rossiter" />
	<atom:link rel='hub' href='http://jamesrossiter.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Set Linux Firewall Rules for a Range of IP Addresses using Webmin</title>
		<link>http://jamesrossiter.wordpress.com/2011/12/08/set-linux-firewall-rules-for-a-range-of-ip-addresses-using-webmin/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/12/08/set-linux-firewall-rules-for-a-range-of-ip-addresses-using-webmin/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 12:14:56 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[networks]]></category>
		<category><![CDATA[webmin]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=365</guid>
		<description><![CDATA[Network address ranges are set slightly differently to standard wildcards. For example, to describe a range of IP addresses from 192.168.0.1 to 192.168.255.255 you use: 192.168.0.0/16 Where 16 describes the number of bits in the IP address that are used for comparison. In this case the 16 describes the first 2 bytes of the address: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=365&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Network address ranges are set slightly differently to standard wildcards. For example, to describe a range of IP addresses from 192.168.0.1 to 192.168.255.255 you use:</p>
<p>192.168.0.0/16</p>
<p>Where 16 describes the number of bits in the IP address that are used for comparison. In this case the 16 describes the first 2 bytes of the address: 192.168. You can read more about IP addressing at <a href="http://www.rhyshaden.com/ipadd.htm">Rhyshaden&#8217;s Data Network Resource</a> (and various other places).</p>
<p>To set your linux firewall up in webmin to use a range of IP addresses, just use the wildcard notation above. So in Webmin &#8211; Networking &#8211; Linux Firewall, when you are editing a rule in iptables you can put in 192.168.0.0/16 to describe a range of IPs (e.g. in the &#8220;source address or network&#8221; field to restrict access to a certain IP range). Manually setting these rules is more tricky but there are resources out there like <a href="http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables">Linux Home Networking</a> and the <a href="http://easyfwgen.morizot.net/gen/index.php">Easy Firewall Generator</a> to help. We just used Webmin as it makes this kind of work very easy indeed.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/365/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=365&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/12/08/set-linux-firewall-rules-for-a-range-of-ip-addresses-using-webmin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Create Certificates and Use SSL with MySQL and the ADOdb Database Abstraction Library for PHP</title>
		<link>http://jamesrossiter.wordpress.com/2011/12/05/create-certificates-and-use-ssl-with-mysql-and-adodb-database-abstraction-library-for-php/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/12/05/create-certificates-and-use-ssl-with-mysql-and-adodb-database-abstraction-library-for-php/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 12:38:30 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[adodb]]></category>
		<category><![CDATA[certificate]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqli]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[secure]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=355</guid>
		<description><![CDATA[This post is mainly for my own records and is the combination of 3 tutorials from KrWiki at waterlovinghead, Carl&#8217;s Whine Rack and Mad Irish. All 3 are almost 100% what I was looking for. I needed to set up a secure database connection between our live web server and database server, both running Ubuntu [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=355&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is mainly for my own records and is the combination of 3 tutorials from <a href="http://www.waterlovinghead.com/MysqlSSL">KrWiki at waterlovinghead</a>, <a href="http://mbrisby.blogspot.com/2008/06/adodb-php-mysql-ssl.html">Carl&#8217;s Whine Rack</a> and <a href="http://www.madirish.net/node/244">Mad Irish</a>. All 3 are almost 100% what I was looking for.</p>
<p>I needed to set up a secure database connection between our live web server and database server, both running Ubuntu Server. The 2 machines are completely separate and have their own IP address. The procedure for setting up an SSL connection between the two is similar to setting up a standard SSL certificate in Apache. First you create the certificates and sign them, then you configure the client (web server 192.168.0.2) and server (database server 192.168.0.1) to use them, finally you create a special MySQL user that uses SSL and connect using <a href="http://adodb.sourceforge.net/">ADOdb</a>. You don&#8217;t need to use ADOdb but it makes things a lot easier (see <a href="http://jamesrossiter.wordpress.com/tag/adodb/">my previous posts</a>).</p>
<p>It&#8217;s very important that your MySQL server has SSL enabled (most do by default). You can test this by connecting to your server and typing the SQL command:</p>
<p><code>SHOW VARIABLES LIKE '%ssl%'</code></p>
<p>Which should show &#8220;have_ssl&#8221; as either &#8220;DISABLED&#8221; or &#8220;YES&#8221;. If it says &#8220;NO&#8221; you will need to enable SSL (which might mean recompiling MySQL).</p>
<h2>Creating the certificates</h2>
<p>You need to create certificates for both the server (our database server) and the client (our web server). There are always a few ways of doing this described in various tutorials but this way is the easiest.</p>
<p>First create a directory somewhere that you will store your certificates in, e.g. &#8220;/var/ssl_certificates/&#8221; then go into the directory and type the following:</p>
<p><code>openssl genrsa 2048 &gt; ca-key.pem</code></p>
<p>Which will generate a 2048 bit RSA private key for the Certificate Authority (CA). Now you need to create a Certificate Authority (CA) certificate, which will be used later to sign our server and client certificates. It is possible to use an external CA but in this case we are self signing, which makes things easier.</p>
<p><code>openssl req -new -x509 -nodes -days 1000 -key ca-key.pem &gt; ca-cert.pem</code></p>
<p>You will be asked a few details: country name, state or province name, locality name, organisation name, organisational unit name, common name and email address. Set the common name to the name of your server e.g. 192.168.0.1. The ca-cert.pem file created is our CA certificate.</p>
<p>Now you can create the server certificate request:</p>
<p><code>openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem &gt; server-req.pem</code></p>
<p>This will ask for the same details as the CA certificate but will also ask you to put in a challenge password and optional company name. In our case, we are not going to be using the challenge password as we would have to enter it every time the SQL server started up.</p>
<p>Now sign the request using our CA certificate and key and generate the server certificate:</p>
<p><code>openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 &gt; server-cert.pem</code></p>
<p>Now we need to create a client certificate request. We need to create one for each client, but in this case we only need to create one for the web server:</p>
<p><code>openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem &gt; client-req.pem</code></p>
<p>You will be asked the same questions as for the server certificate request. The difference this time is that you need to put the client hostname in e.g. 192.168.0.2. Now sign this request and generate the client certificate:</p>
<p><code>openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 &gt; client-cert.pem</code></p>
<p>So now we should have several files in our directory. These are:</p>
<ul>
<li>ca-key.pem &#8211; The certificate authority (CA) key</li>
<li>ca-cert.pem &#8211; The certificate authority (CA) certificate</li>
<li>server-key.pem &#8211; The server key</li>
<li>server-req.pem &#8211; The server certificate request</li>
<li>server-cert.pem &#8211; The server certificate</li>
<li>client-key.pem &#8211; The client key</li>
<li>client-req.pem &#8211; The client certificate request</li>
<li>client-cert.pem &#8211; The client certificate</li>
</ul>
<p>So now we have the required certificates for both the server and the client we can set up both.</p>
<h2>Setting up the MySQL server and client to allow SSL</h2>
<p>All you need to do to set up the MySQL server to accept SSL requests is edit the MySQL my.cnf configuration file (usually in either /etc/my.cnf or /etc/mysql/my.cnf). Add the following lines in the [mysqld] section to point MySQL to the required files (in our case in /var/ssl_certificates/):</p>
<p><code>[mysqld]<br />
ssl-ca=/var/ssl_certificates/ca-cert.pem<br />
ssl-cert=/var/ssl_certificates/server-cert.pem<br />
ssl-key=/var/ssl_certificates/server-key.pem</code></p>
<p>Now restart the MySQL service to check it works by typing:</p>
<p>/etc/rc.d/init.d/mysqld restart</p>
<p>If everything is working fine it should just start up like normal.</p>
<p>Now to set up the client (our web server) we need to copy the 3 required client files ca-cert.pem, client-cert.pem &amp; client-key.pem to a directory on the client (e.g. /var/ssl_certificates/ again). Now you edit the my.cnf on the client (usually in either /etc/my.cnf or /etc/mysql/my.cnf) and add the following lines in the [client] section, which you may need to add yourself:</p>
<p><code>[client]<br />
ssl-ca=/var/ssl_certificates/ca-cert.pem<br />
ssl-cert=/var/ssl_certificates/client-cert.pem<br />
ssl-key=/var/ssl_certificates/client-key.pem</code></p>
<p>So now the client and server are set up to use the SSL certificates you created for all SSL connections between the two. Now we set up a user for the database who is forced to use SSL.</p>
<h2>Setting up a user to use SSL only</h2>
<p>It&#8217;s easiest to set up the user on the command line using the &#8220;mysql&#8221; command on the database server. So log in as your root user (or equivalent) on the database server and create a test database &#8220;test_ssl&#8221;:</p>
<p><code>create database test_ssl;</code></p>
<p>Now create a test user &#8220;test_user&#8221; with password &#8220;testpass&#8221; with the correct client hostname &#8220;192.168.0.2&#8243; and force them to use SSL when logging in:</p>
<p><code>grant all privileges on test_ssl.* to 'test_user'@'192.168.0.2' identified by 'testpass' require ssl;<br />
flush privileges;</code></p>
<p>Now we can create a test table &#8220;test&#8221; and insert some data so we can query it to test everything is working from PHP:</p>
<p><code>create table test (test_id int auto_increment primary key, test_data varchar(255));<br />
insert into test set test_data='foo';</code></p>
<p>Now we go back to ADOdb and PHP to test this all works.</p>
<h2>Connect to the database over SSL using ADOdb</h2>
<p>Simply create a .php file on your web server with the following code:</p>
<p><code>&lt;?php<br />
include('adodb5/adodb.inc.php'); // database libraries (must point to where your ADOdb libraries are kept)</code></p>
<p><code>$dsn = 'mysqli://test_user:testpass@192.168.0.1/test_ssl?clientflags=2048';<br />
$dbh = NewADOConnection($dsn);</code></p>
<p><code>$arr = $dbh-&gt;GetAll("SELECT * from test");<br />
print_r($arr);<br />
?&gt;</code></p>
<p>This should connect to our database using the test_ssl user and using SSL and print out the following on your web browser:</p>
<p><code>Array ( [0] =&gt; Array ( [0] =&gt; 1 [test_id] =&gt; 1 [1] =&gt; foo [test_data] =&gt; foo ) )</code></p>
<p>Now the great thing about this is that by using ADOdb we don&#8217;t need to worry about any kind of special connection string. The only thing that is different between an SSL connection and a standard connection is that SSL ues the &#8220;mysqli&#8221; command in the data source name rather than &#8220;mysql&#8221;, the rest of the code stays the same.</p>
<p>NOTE: It&#8217;s worth double checking that everything is working by executing <code>"show status like 'ssl_cipher'"</code> as a SQL query in the PHP above:</p>
<p><code>&lt;?php<br />
include('adodb5/adodb.inc.php'); // database libraries (must point to where your ADOdb libraries are kept)</code></p>
<p><code>$dsn = 'mysqli://test_user:testpass@192.168.0.1/test_ssl?clientflags=2048';<br />
$dbh = NewADOConnection($dsn);</code></p>
<p><code>$arr = $dbh-&gt;GetAll("show status like 'ssl_cipher'");<br />
print_r($arr-&gt;fields);<br />
?&gt;</code></p>
<p>which gives:</p>
<p><code>Array ( [0] =&gt; Ssl_cipher [Variable_name] =&gt; Ssl_cipher [1] =&gt; DHE-RSA-AES256-SHA [Value] =&gt; DHE-RSA-AES256-SHA )</code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/355/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=355&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/12/05/create-certificates-and-use-ssl-with-mysql-and-adodb-database-abstraction-library-for-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Copy VMWare Server virtual servers (Ubuntu) between physical machines, avoid locking errors and fix missing eth0</title>
		<link>http://jamesrossiter.wordpress.com/2011/10/05/copy-vmware-server-virtual-servers-ubuntu-between-physical-machines-avoid-locking-errors-and-fix-missing-eth0/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/10/05/copy-vmware-server-virtual-servers-ubuntu-between-physical-machines-avoid-locking-errors-and-fix-missing-eth0/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 11:10:54 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[eth0]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virtual server]]></category>
		<category><![CDATA[virtualisation]]></category>
		<category><![CDATA[virtualization]]></category>
		<category><![CDATA[vmware]]></category>
		<category><![CDATA[vmware server]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=351</guid>
		<description><![CDATA[I needed to copy a virtual Ubuntu Server install from our backup store to a new physical server (server A) as our old server (server B) suffered a major failure and wouldn&#8217;t even boot. This meant copying the whole VMWare directory containing the Ubuntu virtual machine from the backup store (a USB harddrive in this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=351&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I needed to copy a virtual Ubuntu Server install from our backup store to a new physical server (server A) as our old server (server B) suffered a major failure and wouldn&#8217;t even boot. This meant copying the whole VMWare directory containing the Ubuntu virtual machine from the backup store (a USB harddrive in this case) to the new physical server (server A). I had installed the free VMWare Server on both server B and A so that if anything happened to server B I would be able to get up and running quickly on server A.</p>
<p>Note: I am assuming you can install and configure VMWare Server for Windows, which is what I&#8217;m using here.</p>
<p>Once I copied the whole directory from the backup store to server A&#8217;s VMWare directory (in this case c:\vmware) I then used the VMWare web interface to &#8220;Virtual Machine &#8211; Add Virtual Machine to Inventory&#8221; which allowed me to select the .vmx file in my datastore that corresponded to my copied Ubuntu virtual machine.</p>
<p>On trying to start the virtual machine I get a warning message and a choice:</p>
<blockquote><p>msg.uuid.altered: This virtual machine may have been moved or copied. In order to configure certain management and networking features VMware Server needs to know which. Did you move this virtual machine, or did you copy it? If you don&#8217;t know, answer &#8220;I copied it&#8221;.</p></blockquote>
<p>I select &#8220;I copied it&#8221; and then click &#8220;ok&#8221;, which then brings up an error:</p>
<blockquote><p>&#8220;Power On Virtual Machine&#8221; failed to complete</p>
<p>If these problems persist, please contact your system administrator.<br />
Cannot open the disk &#8216;C:\vmware\VIRTUALSERVERNAME\VIRTUALSERVERNAME.vmdk&#8217; or one of the snapshot disks it depends on. Reason: Failed to lock the file.</p></blockquote>
<p>Ok, so it seems that because I copied the virtual server from the backup store it also included the .lck directories, which are used while the server is running. The simple fix is to delete these directories in C:\vmware\VIRTUALSERVERNAME\ and allow VMWare server to rebuild them. Once I had deleted the two directories &#8220;VIRTUALSERVERNAME.vmdk.lck&#8221; and &#8220;VIRTUALSERVERNAME.vmem.lck&#8221; I could start the virtual machine.</p>
<p>I then ran into another problem, which was that my network instance eth0 was not being set up correctly even with VMWare Server set to use &#8220;Bridged&#8221; networking which worked on the old server. Running &#8220;ifconfig -a&#8221; showed that eth0 wasn&#8217;t there and it didn&#8217;t have the static IP I had given it previously in &#8220;/etc/network/interfaces&#8221;. The loopback interface, l0, was there but not eth0.</p>
<p><a href="http://www.orzeszek.org/blog/2010/07/25/fix-missing-eth0-when-cloning-ubuntu-vmware-virtual-machines/">Orzeszek</a> has an easy solution for this, which is to delete the &#8220;/etc/udev/rules.d/70-persistent-net.rules&#8221; file and &#8220;sudo reboot&#8221; to allow Ubuntu to rebuild the file with the correct MAC address, set up by VMWare Server when we originally added the virtual machine to the inventory. Now everything should be working perfectly.</p>
<p>Some people have reported other errors, which can be fixed by changing the name of eth0 in &#8220;/etc/network/interfaces&#8221; to eth1, which I didn&#8217;t need to do but you might.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/351/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=351&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/10/05/copy-vmware-server-virtual-servers-ubuntu-between-physical-machines-avoid-locking-errors-and-fix-missing-eth0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Reduce the size of the winsxs directory in Windows 7 using DISM</title>
		<link>http://jamesrossiter.wordpress.com/2011/09/22/reduce-the-size-of-the-winsxs-directory-in-windows-7/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/09/22/reduce-the-size-of-the-winsxs-directory-in-windows-7/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 14:44:28 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[dism]]></category>
		<category><![CDATA[harddrive]]></category>
		<category><![CDATA[space]]></category>
		<category><![CDATA[ssd]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[windows 7]]></category>
		<category><![CDATA[winsxs]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=348</guid>
		<description><![CDATA[Looking for ways to shrink the massive Windows 7 install? The winsxs folder was 6.7GB on my tiny 60GB SSD, way too big for something that seems to just hold service pack backups. Microsoft are AWFUL at explaining how to deal with this, numerous searches always come up with &#8220;Don&#8217;t touch it, it&#8217;ll break Windows!&#8221;. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=348&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Looking for ways to shrink the massive Windows 7 install? The winsxs folder was 6.7GB on my tiny 60GB SSD, way too big for something that seems to just hold service pack backups. Microsoft are AWFUL at explaining how to deal with this, numerous searches always come up with &#8220;Don&#8217;t touch it, it&#8217;ll break Windows!&#8221;. Thanks to some <a href="http://social.technet.microsoft.com/Forums/en-US/w7itproperf/thread/09578403-a363-49ac-beb1-33f0da8d0e25/">helpful people on Technet</a> the solution is to use the Deployment Image Servicing and Management Tool (DISM). Just type the following in a command prompt:</p>
<blockquote><p>dism /online /cleanup-image /spsuperseded</p></blockquote>
<p>Instantly reduced my winsxs folder from 6.7GB to 4.5GB, which is a fair chunk of space on an SSD.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/348/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=348&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/09/22/reduce-the-size-of-the-winsxs-directory-in-windows-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Easily retrieve HTML content from websites using C# and HTML Agility Pack (HtmlAgilityPack)</title>
		<link>http://jamesrossiter.wordpress.com/2011/09/16/easily-retrieve-html-content-from-websites-using-c-and-html-agility-pack-htmlagilitypack/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/09/16/easily-retrieve-html-content-from-websites-using-c-and-html-agility-pack-htmlagilitypack/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 15:23:01 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html agility pack]]></category>
		<category><![CDATA[htmlagilitypack]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=341</guid>
		<description><![CDATA[I needed to retrieve a chunk of content (a product price) within a certain DIV (&#60;div class=&#8221;price&#8221;&#62;) on a website for a large number of search terms. The quickest way of doing this was to use the HtmlAgilityPack library for .NET to call the website&#8217;s search page (with custom search terms) and then pull out [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=341&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I needed to retrieve a chunk of content (a product price) within a certain DIV (&lt;div class=&#8221;price&#8221;&gt;) on a website for a large number of search terms. The quickest way of doing this was to use the <a href="http://htmlagilitypack.codeplex.com/">HtmlAgilityPack library for .NET</a> to call the website&#8217;s search page (with custom search terms) and then pull out the content I needed using the SelectNodes() method. SelectNodes() uses XPATH to search across the document, which sounds tricky but is easy when you know some basic rules. <a href="http://www.w3schools.com/xpath/xpath_syntax.asp">XPATH is described well on w3schools</a> if you need to know the syntax. You will need to download the Html Agility Pack .DLL and make a reference to it in your code.</p>
<p>The following is a simplified version of my code with a file reader/writer to read in a text file containing search terms line by line and output the result to another text file. The exact code will change depending on the website you are using, especially the XPATH in SelectNodes():</p>
<p><pre class="brush: csharp;">
using System;
using System.IO;
using HtmlAgilityPack;

namespace webget
{
  class Program
  {
    static void Main(string[] args)
    {
      string row = &quot;&quot;, line = &quot;&quot;;
      StreamReader infile = new StreamReader(&quot;input.csv&quot;);
      StreamWriter outfile = new StreamWriter(&quot;output.csv&quot;);

      // Create the Html Agility Pack object
      HtmlWeb hw = new HtmlWeb();

      while ((line = infile.ReadLine()) != null)
      {
        // load the website and store in a Htmldocument object
        HtmlDocument doc = hw.Load(&quot;http://www.website.com/search.php?keywords=&quot; + line.Trim());

        try
        {
          // loop through every DIV with class &quot;price&quot; on the website and extract the content
          foreach (HtmlNode link in doc.DocumentNode.SelectNodes(&quot;//div[@class='price']&quot;))
          {
            // clean up the content by removing any standard text items and the £ symbol
            string price = link.InnerText.Replace(&quot;£&quot;, &quot;&quot;).Replace(&quot;\r&quot;, &quot;&quot;).Replace(&quot;\t&quot;, &quot;&quot;).Replace(&quot;\n&quot;, &quot;&quot;).Trim();
            line += price + &quot;,&quot;;
          }
        }
        catch
        {
          line += &quot;,ERROR&quot;;
        }

        Console.WriteLine(line);
        outfile.WriteLine(line);
      }

     infile.Close();
     outfile.Close();
   }
  }
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/341/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=341&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/09/16/easily-retrieve-html-content-from-websites-using-c-and-html-agility-pack-htmlagilitypack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Combine JQuery, JSON and Zend Framework MVC actions to update page items dynamically using AJAX</title>
		<link>http://jamesrossiter.wordpress.com/2011/09/12/combine-jquery-json-and-zend-framework-mvc-actions-to-update-page-items-dynamically-using-ajax/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/09/12/combine-jquery-json-and-zend-framework-mvc-actions-to-update-page-items-dynamically-using-ajax/#comments</comments>
		<pubDate>Mon, 12 Sep 2011 14:26:58 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[Zend]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[json2.js]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=331</guid>
		<description><![CDATA[In order to populate and dynamically update a table on one of our Zend framework based pages without refreshing the page we had to use a combination of JQuery, JSON and standard Zend views/forms. The JQuery is part of the view and is inserted in &#60;script&#62; blocks while a standard Zend form is used to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=331&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In order to populate and dynamically update a table on one of our Zend framework based pages without refreshing the page we had to use a combination of JQuery, JSON and standard Zend views/forms. The JQuery is part of the view and is inserted in &lt;script&gt; blocks while a standard Zend form is used to populate the page with dropdown menus, text boxes etc. JSON is used to handle passing data between the client side JQuery and the server side Zend action.</p>
<p>The following is a simple example, which passes JSON stored by JQuery in a hidden field to a Zend action on the server to update a database. Where possible the code has been simplified (so no long winded database connection etc  etc). As getting Zend framework up and running can be a bit difficult from scratch, this is not covered here. The <a href="http://framework.zend.com/manual/en/learning.quickstart.html">Zend Framework Quickstart</a> is useful although personally I think it could be clearer for first time users. Although I use modules in Zend to split different sections of my web application into self contained areas, for this example I will keep it as simple as possible and not use modules. To keep things even more simple I am not going to describe any validation or POST handling of the Zend action, we are only concerned with JQuery/Zend integration.</p>
<p>The example action we are going to call is the LIST action in the VISIT controller, which will show a list of visits and allow us to add a new one using a simple one textbox interface. JQuery will be used to pull all the required table data from the server and handle the visual client side aspect of adding a new visit.</p>
<p>The controller VisitController.php will have a very simple LIST action that looks like the following:<br />
<code><br />
public function listAction()<br />
{<br />
<code>  </code>// set the view title to "Visit List"<br />
<code>  </code>$this-&gt;view-&gt;title = "Visit List";<br />
<code>  </code>// create a new Form_ListVisit() form object and add it to the view<br />
<code>  </code>$newVisitForm = new Form_ListVisit();<br />
<code>  </code>$this-&gt;view-&gt;form = $listVisitForm;<br />
}<br />
</code><br />
All this action does is set the view title, generate a Form object from a Zend form Form_ListVisit() and set the view form to this object (thereby placing the form on the page). The action will not do anything without a corresponding view script and Zend form, which both need to be created as separate files in the correct location in your file structure (more than likely /views/scripts/visit/list.phtml and /forms/ListVisit.php). Again, use of views and Zend forms is standard Zend Framework practice and is beyond the scope of this simple example.</p>
<p>For the view, currently without any JQuery, it will also be very simple:<br />
<code><br />
&lt;?php<br />
<code>  </code>echo "&lt;h1&gt;".$this-&gt;title."&lt;/h1&gt;";<br />
<code>  </code>echo $this-&gt;form;<br />
<code>  </code>echo "&lt;div class='statusmessage'&gt;&lt;/div&gt;";<br />
?&gt;<br />
</code><br />
All this does is place the title and the form on the page that is displayed to the user, both the title and the form are set in the controller (see above). In a moment the JQuery will be placed in a &lt;script&gt; tag above this &lt;?php ?&gt; section, although it is a good idea to refactor your code to keep the view as simple as possible by having the JQuery code in a separate .js file. The &#8220;statusmessage&#8221; div will be used by JQuery to place success/error message on screen when we update the database.</p>
<p>The ListVisit.php Zend form file is more complicated and in the real world can take a while to write, including all the objects, decorators, subforms, validation options etc. In this case we keep it very simple and just add a single hidden field that we will use to store a single JSON string and a textbox to handle user input:<br />
<code><br />
class Form_ListVisit extends \ZendX_JQuery_Form<br />
{<br />
<code>  </code>public function init()<br />
<code>  </code>{<code>  </code><br />
<code>  </code><code>  </code>// add the hidden field used to store our JSON string<code>  </code><br />
<code>  <code>  </code></code>$hiddenjson = $this-&gt;createElement('hidden','hiddenjson');<br />
<code>  <code>  </code></code>$this-&gt;addElement($hiddenjson);<br />
<code>  </code><code>  </code>// add the textbox used to handle user input<br />
<code>  </code><code>  </code>$inputfield = $this-&gt;createElement('text', 'inputfield', array('Label' =&gt; 'Enter new data here'));<br />
<code>  </code><code>  </code>$this-&gt;addElement($inputfield);<br />
<code>  </code>}<br />
}<br />
</code><br />
So on loading the NEW action on the VISIT controller we end up with a blank page with only a title that says &#8220;Visit List&#8221; and a single textbox. The hidden field placed on the page by the Zend form is there but is empty, there is no table on screen and no other links. In this example we are going to add everything else we need, such as the table of visits, link to add new visit and link to save to the database, using JQuery. The communication between the client side and the server is handled using JQuery&#8217;s .post method and another Zend action which is set to take in JSON and only return a JSON string.</p>
<p>JQuery is used to generate a simple single column table and add two links to the page. The first link &#8220;Add New Visit&#8221; will add whatever is in the textbox to our very simple single column table. The second link &#8220;Save to Database&#8221; will update the database with the values of our table by calling the SAVEDATA action on the VISIT controller. The SAVEDATA action takes in a JSON string, does something to the database and returns a JSON string to the client. The possibilities that result from passing JSON between client and server using this JQuery method are amazing and make it trivial to create AJAX interfaces with JQuery and Zend.</p>
<p>IMPORTANT: I had to include the well known <a href="https://github.com/douglascrockford/JSON-js">json2.js script by Douglas Crockford</a> in order to get my JSON encoding and decoding working correctly in all browsers. This script saved a lot of headaches and is only 17k (and can probably be minified).</p>
<p>In the view, in the &lt;script&gt;&lt;/script&gt; at the top we first need to add in the JQuery that will be loaded on document ready (standard JQuery practice):<br />
<code><br />
$(document).ready(function(){<br />
<code>  </code>// create the two links to "Add New Visit" and "Save to Database" and place before statusmessage div<br />
<code>  </code>$( "div.statusmessage" ).before("&lt;a href='#' id='addvisitbutton'&gt;Add New Visit&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='#' id='savedatabutton'&gt;Save to Database&lt;/a&gt;");<br />
<code>  </code>// create the empty simple one column table to store our visits and place it after the statusmessage div<br />
<code>  </code>$('div.statusmessage').after("&lt;table id='visittable'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Visit Name&lt;/th&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;");<br />
<code>  </code>// handle "Add New Visit" button click<br />
<code>  </code>$( "#addvisitbutton" ).click(function() {<br />
<code>  </code><code>  </code>addvisit();<br />
<code>  </code>});<br />
<code>  </code>// handle "Save to Database" button click<br />
<code>  </code>$( "#savedatabutton" ).click(function() {<br />
<code>  </code><code>  </code>savedata();<br />
<code>  </code>});<br />
}<br />
</code><br />
Note that the click handling functions that have been added to the 2 links call either addvisit() or savedata(). These 2 functions are described above and outside the JQuery $(document).ready() as follows:<br />
<code><br />
function addvisit(){<br />
<code>  </code>// get a JSON object from the value of the hidden data field (will be empty initally)<br />
<code>  </code>var jparsed = JSON.parse($("#hiddenjson").val());<br />
<code>  </code>// create a new row to add to the JSON data based on the contents of the text field<br />
<code>  </code>var row = [$("#coughscore").val()];<br />
<code>  </code>// add the row to the end of the table<br />
<code>  </code>jparsed.push(row);<br />
<code>  </code>// set the hidden value to a JSON string representing the contents of the JSON object<br />
<code>  </code>$("#hiddenjson").val(JSON.stringify(jparsed));<br />
<code>  </code>// remove all rows from the visittable table of class "datarow", all new data rows will be of this class<br />
<code>  </code>$("#visittable tbody tr.datarow").remove();<br />
<code>  </code>// iterate through the JSON object  and append the data rows to the visittable table<br />
<code>  </code>for(var i=0;i&lt;jparsed.length;i++)<br />
<code>  </code>{<br />
<code>  <code>  </code></code>rowstring += "&lt;tr class='datarow'&gt;";<br />
<code>  <code>  </code></code>var obj = jparsed[i];<br />
<code>  <code>  </code></code>for(var j=0;j&lt;obj.length;j++)<br />
<code>  </code><code>  </code>{<br />
<code>  </code><code>  </code><code>  </code>rowstring += "&lt;td&gt;" + obj[j] + "&lt;/td&gt;";<br />
<code>  <code>  </code></code>}<br />
<code>  <code>  </code></code>rowstring += "&lt;/tr&gt;";<br />
<code>  </code>}<br />
<code>  </code>$("#visittable tbody").append(rowstring);<br />
}<br />
</code><br />
When a row is added to the table the hidden field is updated to contain a JSON string describing the whole table. It is this JSON string that is passed to the SAVEDATA action of the VISIT controller by the savedata() function&#8217;s .post(), where it is converted to an object by some simple PHP code and then stored in the database:<br />
<code><br />
function savedata(){<br />
<code>  </code>// get the host name and correct controller url using a little Javascript/PHP and the built in Zend url() function<br />
<code>  </code>var host = 'http://' + window.location.hostname + '&lt;?php echo $this-&gt;url(array('controller'=&gt;'visit'),"",true); ?&gt;';<br />
<code>  </code>// get the JSON string stored in the hidden field<br />
<code>  </code>var jsondata = $("#hiddenjson").val();<br />
<code>  </code>// use JQuery's .post() function to post to the Zend SAVEDATA action on the VISIT controller<br />
<code>  </code>$.post(host+"/savedata",{<br />
<code>  <code>  </code></code>// send the value of the jsondata variable (the JSON string) in the POST as "jsondata"<br />
<code>  <code>  </code></code>jsondata: jsondata<br />
<code>  </code>},<br />
<code>  </code>// handle the returning JSON data from the SAVEDATA action<br />
<code>  </code>function(data)<br />
<code>  </code>{<br />
<code>  <code>  </code></code>// convert the returning JSON data to an object using .eval()<br />
<code>  </code><code>  </code>obj = window.eval(data);<br />
<code>  </code><code>  </code>// set the value of the statusmessage div to the 'notes' field in the JSON returned by the SAVEDATA action<br />
<code>  <code>  </code></code>// (this is either "Succcess" or "Failure" in this example)<br />
<code>  </code><code>  </code>$('.statusmessage').html(obj['notes']);<br />
<code>  </code>},<br />
<code>  <code>  </code></code>"json");<br />
<code>  </code>}<br />
}<br />
</code><br />
The SAVEDATA action is a standard Zend action on the VISIT controller with the addition of a couple of important lines of code to avoid rendering a view:<br />
<code><br />
public function savedataAction()<br />
{<br />
<code>  </code>// disable the Zend layout<br />
<code>  </code>$this-&gt;_helper-&gt;layout-&gt;disableLayout();<br />
<code>  </code>// suppress auto-rendering and displaying a view<br />
<code>  </code>$this-&gt;_helper-&gt;viewRenderer-&gt;setNoRender();<br />
<code>  </code>// retrieve the jsondata string from the POST variables<br />
<code>  </code>$jsondata = $_POST['jsondata'];<br />
<code>  </code>// create an object to store the success or failure message strings and return them to JQuery.<br />
<code>  </code>$data['notes'] = "";<br />
<code>  </code>// decode the JSON string and turn into an object<br />
<code>  </code>if($dec = Zend_Json::decode($jsondata))<br />
<code>  </code>{<br />
<code>  <code>  </code></code>// do important things with the converted JSON object, e..g write to database etc..<br />
<code>  <code>  </code></code>//<br />
<code>  <code>  </code></code>// set the return message to Success<br />
<code>  </code><code>  </code>$data['notes'] = "Success";<br />
<code>  </code>}<br />
<code>  </code>else<br />
<code>  </code>{<br />
<code>  </code><code>  </code>// conversion from JSON string to PHP object failed, so return Error<br />
<code>  <code>  </code></code>$data['notes'] = "Error";<br />
<code>  </code>}<br />
<code>  </code>// encode the returning object into a JSON string<br />
<code>  </code>$json = Zend_Json::encode($data);<br />
<code>  </code>// echo the JSON string back to JQuery, where it is handled according to the definition in the .post() function<br />
<code>  </code>echo $json;<br />
}<br />
</code><br />
So now you can pass JSON objects between the client and the server using JQuery and json2.js. In this example JQuery is used to populate a table client-side and then pass the data for storage in the database on the server.</p>
<p>Alternatively you can use a Zend action and a JavaScript function to pull data from the server and display it as a table. This is really useful for displaying tabular data and is just a modification of the method above. The JavaScript function retrievedata() to pull data from the server using a new RETRIEVEDATA action and JQuery&#8217;s .post() function and add it to our visittable table is as follows:</p>
<p><code>function retrievedata(){<br />
<code>  </code>// get the host name and correct controller url using a little Javascript/PHP and the built in Zend url() function<br />
<code>  </code>var host = 'http://' + window.location.hostname + '&lt;?php echo $this-&gt;url(array('controller'=&gt;'visit'),"",true); ?&gt;';<br />
<code>  </code>// get the JSON string stored in the hidden field<br />
<code>  </code>var jsondata = $("#hiddenjson").val();<br />
<code>  </code>// use JQuery's .post() function to post to the Zend RETRIEVEDATA action on the VISIT controller<br />
// note that we don't actually post any data this time, we only retrieve data<br />
<code>  </code>$.post(host+"/savedata",{<br />
<code>  </code>},<br />
<code>  </code>// handle the returning JSON data from the <code>RETRIEVEDATA </code>action<br />
<code>  </code>function(data)<br />
<code>  </code>{<br />
<code>  <code>  // clean up and convert the returned JSON to a string<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>// (this step required as sometimes Zend JSON is not always "correct")<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>var json = JSON.stringify(data);<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>// convert JSON string to object<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code>var jparsed = JSON.parse(json);<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code>// create a blank string ready to store a single html row of the table<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code>var rowstring = "";<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>// iterate through the JSON object adding the html for a row of the table each time<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>for(var i=0;i&lt;jparsed.length;i++)<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>{<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code><code><code><code>  </code></code></code>rowstring += "&lt;tr class='datarow'&gt;";<br />
<code><code><code>  <code><code><code>  <code><code><code>  </code></code></code></code></code></code></code></code></code>var obj = jparsed[i];<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code><code><code><code>  </code></code></code>// iterate through each column of the row, adding the html for a table cell each time<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code><code><code><code>  </code></code></code>for(var j=0;j&lt;obj.length;j++)<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code><code><code><code>  </code></code></code>{<br />
<code><code><code>  <code><code><code>  <code><code><code>  <code><code><code>  </code></code></code></code></code></code></code></code></code></code></code></code>rowstring += "&lt;td&gt;" + obj[j] + "&lt;/td&gt;";<br />
<code><code><code>  </code></code></code><code><code><code>  <code><code><code>  </code></code></code></code></code></code>}<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code><code><code><code>  </code></code></code>rowstring += "&lt;/tr&gt;";<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code>}<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code>// append the newly formed rowstring to the table<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>$("#visittable tbody").append(rowstring);<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>// set the hidden field to the JSON string<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>$("#hiddenjson").val(json);</code></code><br />
<code>  </code><code><code><code></code></code></code>},<br />
<code>  <code>  </code></code>"json");<br />
<code>  </code>}<br />
}</code></p>
<p>The RETRIEVEDATA action (simplified to remove database queries) looks like:<br />
<code><br />
public function retrievedataAction()<br />
{<br />
<code><code><code>  </code></code></code>$this-&gt;_helper-&gt;layout-&gt;disableLayout();<br />
<code><code><code>  </code></code></code>$this-&gt;_helper-&gt;viewRenderer-&gt;setNoRender();<br />
<code><code><code>  </code></code></code>// get array of objects from database using ORM<br />
<code><code><code>  </code></code></code>// alternatively, use standard SQL connection etc etc<br />
<code><code><code>  </code></code></code>// e.g. $arr = SomeORMMethod("visits");<br />
<code><code><code>  </code></code></code>$output = array();<br />
<code><code><code>  </code></code></code>foreach($arr as $key =&gt; $value)<br />
<code><code><code>  </code></code></code>{<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>$row = array();<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>$row[0] = $value-&gt;visitName;<br />
<code><code><code>  <code><code><code>  </code></code></code></code></code></code>$row[1] = $value-&gt;visitDate;<br />
<code><code><code>  </code></code></code><code><code><code>  </code></code></code>$output[] = $row;<br />
<code><code><code>  </code></code></code>}<br />
<code><code><code>  </code></code></code>$json = Zend_Json::encode($output);<br />
<code><code><code>  </code></code></code>echo $json;<br />
}</code></p>
<p>You may have noticed that all of this can be done without Zend at all. If you read the <a href="http://api.jquery.com/jQuery.post/">JQuery .post() documentation</a> it becomes a bit clearer, especially if you end up not using JSON at all. I know there are other methods out there to do this, but since I&#8217;m heavily involved with Zend at the moment I thought it would make sense to try and explain this example, as I used it in my own code. Also note, there is no security at all on this example; you will need to manage sessions, use encrypted data etc to make this secure.</p>
<p>The basic framework of JQuery/JSON/Zend means you can easily create rich MVC apps with AJAX and the flexibility of JQuery means that you don&#8217;t even have to use Zend at all! You can apply the same basically identical approach with Microsoft MVC, CakePHP or even with your own frameworks, all you need to do is modify the actions.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/331/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=331&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/09/12/combine-jquery-json-and-zend-framework-mvc-actions-to-update-page-items-dynamically-using-ajax/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Allow larger file downloads than 50mb from SharePoint (fix error 0x800700DF)</title>
		<link>http://jamesrossiter.wordpress.com/2011/04/04/allow-larger-file-downloads-than-50mb-from-sharepoint-fix-error-0x800700df/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/04/04/allow-larger-file-downloads-than-50mb-from-sharepoint-fix-error-0x800700df/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 08:50:26 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[0x800700DF]]></category>
		<category><![CDATA[50mb]]></category>
		<category><![CDATA[downloads]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[large]]></category>
		<category><![CDATA[limit]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=326</guid>
		<description><![CDATA[I ran into a 0x800700DF error when trying to download a 100mb file from SharePoint using Windows Explorer. I tend to do all my file operations in SharePoint with the WebDAV interface by pointing Windows Explorer to \\portal.server.name\portal\ and logging in with an account with permissions to access the portal. The 0x800700DF error when attempting [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=326&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I ran into a 0x800700DF error when trying to download a 100mb file from SharePoint using Windows Explorer. I tend to do all my file operations in SharePoint with the WebDAV interface by pointing Windows Explorer to \\portal.server.name\portal\ and logging in with an account with permissions to access the portal. The 0x800700DF error when attempting to copy large files is actually described as:</p>
<blockquote><p>Error 0x800700DF: The file size exceeds the limit allowed and cannot be saved.</p></blockquote>
<p>The fix involves changing a registry setting on your client machine to allow 4GB downloads (the maximum possible). From <a href="http://answers.microsoft.com/en-us/windows/forum/windows_xp-hardware/error-0x800700df-the-file-size-exceeds-the-limit/d208bba6-920c-4639-bd45-f345f462934f">Microsoft Answers</a>:</p>
<blockquote><p>FileSizeLimitInBytes is set to 5000000 which limits your download so just set it to maximum! (this is client side btw on windows 7)</p>
<p><strong>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters</strong></p>
<ul>
<li> Right click on the FileSizeLimitInBytes and click Modify</li>
<li>Click on Decimal</li>
<li>In the Value data box, type 4294967295, and then click OK. Note this sets the maximum you can download from the Webdav to 4 gig at one time, I haven’t figured out how to make it unlimited so if you want to download more you need to split it up.</li>
</ul>
</blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/326/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=326&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/04/04/allow-larger-file-downloads-than-50mb-from-sharepoint-fix-error-0x800700df/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Connect your free wordpress.com blog to Twitter using your RSS feed and Feedburner</title>
		<link>http://jamesrossiter.wordpress.com/2011/03/16/connect-your-free-wordpress-com-blog-to-twitter-using-your-rss-feed-and-feedburner/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/03/16/connect-your-free-wordpress-com-blog-to-twitter-using-your-rss-feed-and-feedburner/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 16:53:38 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[feed]]></category>
		<category><![CDATA[feedburner]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=295</guid>
		<description><![CDATA[This blog is currently hosted for free on wordpress.com, which means it is always up to date and doesn&#8217;t rely on my own hosting, unlike my website at jamesrossiter.co.uk. Although there are several advantages to hosting on wordpress.com the main disadvantage is that you can&#8217;t load plugins or write your own. One of the plugins [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=295&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This blog is currently hosted for free on <a href="http://www.wordpress.com">wordpress.com</a>, which means it is always up to date and doesn&#8217;t rely on my own hosting, unlike my website at <a href="http://www.jamesrossiter.co.uk">jamesrossiter.co.uk</a>. Although there are several advantages to hosting on wordpress.com the main disadvantage is that you can&#8217;t load plugins or write your own. One of the plugins I miss most is the <a href="http://wordpress.org/extend/plugins/wordpress-tweeter/">WordPress Tweeter plugin</a>, which allows WordPress to integrate nicely with <a href="http://www.twitter.com">Twitter</a> by posting to Twitter when new posts are written and even when posts are updated.</p>
<p>One workaround for this is to use the built in Publicize feature under Settings &#8211; Sharing on your wordpress.com blog. Unfortunately, it&#8217;s terrible.. It doesn&#8217;t add #hashtags or allow you to customise anything. The alternative is to add your RSS feed to <a href="http://feedburner.google.com">Feedburner</a>.</p>
<p>Once you have signed up to Feedburner and added your RSS feed (http://yourblogname.wordpress.com/feed) open it on the Feedburner dashboard and click on the &#8220;Publicize&#8221; tab at the top. Now click on the &#8220;Add a Twitter Account&#8221; and allow Twitter access. Now whenever you create a new post, your RSS feed will be updated and Feedburner will push a link to your new blog post (based on the title) to Twitter.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/295/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=295&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/03/16/connect-your-free-wordpress-com-blog-to-twitter-using-your-rss-feed-and-feedburner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Using ADODB to easily connect to MySQL and Microsoft SQL Server from PHP</title>
		<link>http://jamesrossiter.wordpress.com/2011/03/16/using-adodb-to-easily-connect-to-mysql-and-microsoft-sql-server-from-php/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/03/16/using-adodb-to-easily-connect-to-mysql-and-microsoft-sql-server-from-php/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 16:35:33 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[adodb]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=286</guid>
		<description><![CDATA[In previous posts I&#8217;ve talked about connecting to Microsoft SQL Server from PHP using ODBC and using mssql_connect to connect directly. The most important thing I&#8217;ve realised is not to re-invent the adodb wheel, which has shown to be a really great cross-platform way of connecting to databases. The best thing about adodb is that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=286&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In previous posts I&#8217;ve talked about <a href="http://jamesrossiter.wordpress.com/2011/03/08/connecting-to-microsoft-sql-server-using-odbc-from-ubuntu-server/">connecting to Microsoft SQL Server from PHP using ODBC</a> and <a href="http://jamesrossiter.wordpress.com/2011/03/08/connecting-to-microsoft-sql-server-from-php-in-ubuntu-using-mssql_connect/">using mssql_connect to connect directly</a>. The most important thing I&#8217;ve realised is not to re-invent the adodb wheel, which has shown to be a really great cross-platform way of connecting to databases.</p>
<p>The best thing about <a href="http://adodb.sourceforge.net/">adodb</a> is that just by changing the connection string I can talk to MySQL and Microsoft SQL Server without changing any of my code. I&#8217;ve used this for performance and migration testing and it&#8217;s been perfect, with none of the <a href="http://jamesrossiter.wordpress.com/2011/03/08/connecting-to-microsoft-sql-server-using-odbc-from-ubuntu-server/">strange hangs</a> I noticed with a standard ODBC connection. Currently I am using Ubuntu Server 10.10 to host all the PHP, which has overall been a pretty good experience, apart from these strange hangs.</p>
<p>If you are in Ubuntu Server you may need to install some ODBC packages in order to get adodb to work. Some of these packages are not totally necessary but I would recommend them for testing ODBC connections etc:</p>
<blockquote><p>sudo apt-get install php5-odbc unixodbc unixodbc-dev freetds-dev sqsh tdsodbc</p></blockquote>
<p>Now you need to create a SQL user in either your MySQL or SQL Server database. Make sure you map the SQL Server user as a database owner on the DB you want to connect to and give them the same default schema. The reason for this is I couldn&#8217;t get the connection in adodb to work with the actual DB specified (unlike in MySQL).</p>
<p><a href="http://adodb.sourceforge.net/">Download adodb5</a> and place the directory in the root of your webserver and add the following to the top of your PHP file:</p>
<blockquote><p>include(&#8216;adodb5/adodb.inc.php&#8217;);</p></blockquote>
<p>Now open up your PHP file and insert the following for SQL Server with IP &#8220;the.ser.ver.ip&#8221;:</p>
<blockquote><p>$dbcstring = &#8220;mssql://username:password@the.ser.ver.ip&#8221;;</p></blockquote>
<p>Or the following for MySQL:</p>
<blockquote><p>$dbcstring = &#8220;mysql://username:password@the.ser.ver.ip/databasename?persist&#8221;;</p></blockquote>
<p>Create a connection to the database:</p>
<blockquote><p>$DB = NewADOConnection($dbcstring);</p></blockquote>
<p>Now you can use the built in commands in adodb to easily pull data from the database and display it on screen. It doesn&#8217;t matter which database you are connecting to, the commands are now the same. This is the main advantage of adodb in my opinion, along with the ease of use:</p>
<blockquote><p>$arr = $DB-&gt;GetAll(&#8220;SELECT column FROM table&#8221;);<br />
for($i=0;$i&lt;count($arr);$i++)<br />
{<br />
echo $arr[$i][0]  . &#8220;&lt;br/&gt;&#8221;;<br />
}</p></blockquote>
<p>It&#8217;s worth reading <a href="http://phplens.com/lens/adodb/docs-adodb.htm">the guide on adodb</a> for the commands you can use, such as $DB-&gt;GetRow(), $DB-&gt;GetOne() and $DB-&gt;Execute(). The great thing is that adodb makes everything so simple you can treat your data as arrays or you can go further and make use of some of the more advanced functionality. Either way, by using adodb you massively cut down on code rewrites when you migrate to a new database.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/286/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/286/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/286/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/286/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/286/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/286/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/286/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/286/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/286/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/286/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/286/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/286/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/286/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/286/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=286&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/03/16/using-adodb-to-easily-connect-to-mysql-and-microsoft-sql-server-from-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
		<item>
		<title>Connecting to Microsoft SQL Server using ODBC from Ubuntu Server</title>
		<link>http://jamesrossiter.wordpress.com/2011/03/08/connecting-to-microsoft-sql-server-using-odbc-from-ubuntu-server/</link>
		<comments>http://jamesrossiter.wordpress.com/2011/03/08/connecting-to-microsoft-sql-server-using-odbc-from-ubuntu-server/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 16:18:35 +0000</pubDate>
		<dc:creator>James Rossiter</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[adodb]]></category>
		<category><![CDATA[FreeTDS]]></category>
		<category><![CDATA[isql]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[odbc]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[sqsh]]></category>

		<guid isPermaLink="false">http://jamesrossiter.wordpress.com/?p=278</guid>
		<description><![CDATA[Previously I showed how to connect to Microsoft SQL Server in PHP using mssql_connect(). This works but is not as neat as using ODBC. Unfortunately when writing this guide I got stuck at the last hurdle when trying to use ODBC and adodb in PHP. I could connect to the database using: include(&#8216;adodb5/adodb.inc.php&#8217;); $connection=&#38; ADONewConnection(&#8216;odbc_mssql&#8217;); [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=278&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Previously I <a title="Connecting to Microsoft SQL Server from PHP in Ubuntu using mssql_connect()" href="http://jamesrossiter.wordpress.com/2011/03/08/connecting-to-microsoft-sql-server-from-php-in-ubuntu-using-mssql_connect/">showed how to connect to Microsoft SQL Server in PHP using mssql_connect()</a>. This works but is not as neat as using ODBC.</p>
<p>Unfortunately when writing this guide I got stuck at the last hurdle when trying to use ODBC and adodb in PHP. I could connect to the database using:</p>
<blockquote><p>include(&#8216;adodb5/adodb.inc.php&#8217;);<br />
$connection=&amp; ADONewConnection(&#8216;odbc_mssql&#8217;);<br />
$connection-&gt;Connect(&#8216;datasourcename&#8217;,'username&#8217;,'password&#8217;);</p></blockquote>
<p>Or using odbc_connect:</p>
<blockquote><p>$connection= odbc_connect(&#8216;datasourcename&#8217;, &#8216;username&#8217;, &#8216;password&#8217;);</p></blockquote>
<p>But selecting data using &#8220;$connection-&gt;GetAll()&#8221; or &#8220;odbc_exec()&#8221; just resulted in a page that never loaded. Fortunately the ODBC part worked, there was just something I haven&#8217;t figured out yet with ODBC in PHP.</p>
<p>This guide will show you how to set up ODBC in Ubuntu using FreeTDS to talk to Microsoft SQL Server. I am trying to work out why the server connects fine but won&#8217;t execute queries in PHP. When I find out why I will update this post. To create this guide I went off <a href="http://ubuntuforums.org/showthread.php?p=6956316#post6956316">a post on Ubuntu forums</a> with some additions. There are a lot of steps, but at least some of the programs you use along the way allow you to check things are working as expected before you come to test in PHP.</p>
<p>First you need to install php5-odbc in Ubuntu:</p>
<blockquote><p>sudo apt-get install php5-odbc</p></blockquote>
<p>Now you need to add freetds to create a connection and talk to your server, plus a few other handy programs:</p>
<blockquote><p>sudo apt-get install unixodbc unixodbc-dev freetds-dev sqsh tdsodbc</p></blockquote>
<p>Edit the example server details or create a new one in /etc/freetds/freetds.conf to point to your server (in my case I called it &#8220;sqlserver&#8221;):</p>
<blockquote><p>[sqlserver]<br />
host = ip.add.ress<br />
port = 1433<br />
tds version = 7.0</p></blockquote>
<p>You can check the connection is set up using sqsh:</p>
<blockquote><p>sqsh -S sqlserver -U username -P password</p></blockquote>
<p>Alternatively, you can connect directly to the ip.add.ress:</p>
<blockquote><p>sqsh -S ip.add.ress -U username -P password</p></blockquote>
<p>Now in sqsh you can select from a table in your SQL Server database and display it on screen by entering your query and &#8220;go&#8221; on the next line:</p>
<blockquote><p>1&gt; select * from databasename.dbo.table<br />
2&gt; go</p></blockquote>
<p>Hopefully you should see your data on screen. The next step is to configure ODBC so check where the config files are located using:</p>
<blockquote><p>odbcinst -j</p></blockquote>
<p>Which should say &#8220;DRIVERS: /etc/odbcinst.ini&#8221; and &#8220;SYSTEM DATA SOURCES: /etc/odbc.ini&#8221; which are the files we will be editing.</p>
<p>Now we set up the FreeTDS driver so it can be used by ODBC so open &#8220;/etc/odbcinst.ini&#8221; (was a blank file in my case) and add:</p>
<blockquote><p>[FreeTDS]<br />
Description = TDS driver (Sybase/MS SQL)<br />
Driver = /usr/lib/odbc/libtdsodbc.so<br />
Setup = /usr/lib/odbc/libtdsS.so<br />
CPTimeout =<br />
CPReuse =<br />
FileUsage = 1</p></blockquote>
<p>Open &#8220;/etc/odbc.ini&#8221; and create the system data source &#8220;datasourcename&#8221; that we will use everywhere (including in PHP):</p>
<blockquote><p>[datasourcename]<br />
Driver = FreeTDS<br />
Description  = ODBC connection via FreeTDS<br />
Trace = No<br />
Servername = sqlserver<br />
Database = databasename</p></blockquote>
<p>It&#8217;s important to note that &#8220;Servername&#8221; here refers to the server details in /etc/freetds/freetds.conf NOT to an IP address.</p>
<p>You can test the connection works using isql:</p>
<blockquote><p>isql -v datasourcename username password</p></blockquote>
<p>Now you can use this data source &#8220;datasourcename&#8221; in PHP, which is the goal! To test the connection works I tried odbc_connect():</p>
<blockquote><p>$connection = odbc_connect(&#8216;datasourcename&#8217;, &#8216;username&#8217;, &#8216;password&#8217;);<br />
if (!$connection) die(&#8220;Connection failed&#8221;);<br />
else echo &#8220;works&#8221;;</p></blockquote>
<p>Which does work. Now I just need to work out why queries such as the following cause PHP to hang:</p>
<blockquote><p>$query = odbc_exec($connection, &#8216;SELECT column FROM table&#8217;) or die (odbc_errormsg());</p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jamesrossiter.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jamesrossiter.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jamesrossiter.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jamesrossiter.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jamesrossiter.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jamesrossiter.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jamesrossiter.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jamesrossiter.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jamesrossiter.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jamesrossiter.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jamesrossiter.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jamesrossiter.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jamesrossiter.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jamesrossiter.wordpress.com/278/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jamesrossiter.wordpress.com&amp;blog=4114587&amp;post=278&amp;subd=jamesrossiter&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jamesrossiter.wordpress.com/2011/03/08/connecting-to-microsoft-sql-server-using-odbc-from-ubuntu-server/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4e6786c817235ddc8dd779a75ff8ae76?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rossinio</media:title>
		</media:content>
	</item>
	</channel>
</rss>
