<?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/"
    >

<channel>
    <title>Webmonkey &#187; Databases</title>
    <atom:link href="http://www.webmonkey.com/category/databases/feed/" rel="self" type="application/rss+xml" />
    <link>http://www.webmonkey.com</link>
    <description>The Web Developer&#039;s Resource</description>
    <lastBuildDate>Fri, 05 Apr 2013 20:20:46 +0000</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <generator>http://wordpress.org/?v=3.4.2</generator>
    
    <item>
        <title>Behind the Scenes at Instagram: Tools for Building Reliable Web Services</title>
        <link>http://www.webmonkey.com/2012/04/behind-the-scenes-at-instagram-tools-for-building-reliable-web-services/</link>
        <comments>http://www.webmonkey.com/2012/04/behind-the-scenes-at-instagram-tools-for-building-reliable-web-services/#comments</comments>
        <pubDate>Tue, 10 Apr 2012 16:58:59 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=55514</guid>
        		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Instagram]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2012/04/Instagram_logo-200x100.png" type="image/png" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2012/04/Instagram_logo.png" alt="Behind the Scenes at Instagram: Tools for Building Reliable Web Services" /></div>Want to build a web service that sells for a cool billion dollars? Instagram's developers have some advice for you: Choose your tools wisely.]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><img class="aligncenter size-full wp-image-55519" title="Instagram_logo" src="http://www.webmonkey.com/wp-content/uploads/2012/04/Instagram_logo.png" alt="" width="200" height="200" />In case you missed it, yesterday <a href="http://www.wired.com/epicenter/2012/04/facebook-buys-instagram/">Facebook acquired Instagram</a>, a photo-sharing service with some 30 million users and hundreds of millions of images on its servers.</p>
<p>The reported sale price of one billion dollars no doubt has many developers dreaming of riches, but how do you build a service and scale it to the size and success of Instagram? At least part of the answer lies in choosing your tools wisely.</p>
<p>Fortunately for outside developers, Instagram&#8217;s devs have been documenting the tools they used all along. The company&#8217;s <a href="http://instagram-engineering.tumblr.com/">engineering blog</a> <a href="http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances-dozens-of">outlined its development stack</a> last year and has further detailed <a href="http://instagram-engineering.tumblr.com/post/12202313862/storing-hundreds-of-millions-of-simple-key-value-pairs">how it uses</a> several of the tools it&#8217;s chosen.</p>
<p>Instagram uses an interesting mashup of tried-and-true technologies alongside more cutting-edge tools, mixing SQL databases with NoSQL tools like Redis, and chosing to host its traditional Ubuntu servers in Amazon&#8217;s cloud.</p>
<p>In a blog post last year Instagram <a href="http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances-dozens-of">outlined its core principles</a> when it comes to chosing tools, writing, &#8220;keep it very simple, don&#8217;t reinvent the wheel [and] go with proven and solid technologies when you can.&#8221;</p>
<p>In other words, go with the boring stuff that just works.</p>
<p>For Instagram that means a Django-based stack that runs on Ubuntu 11.04 servers and uses PostgreSQL for storage. There are several additional layers for load balancing, push notifications, queues and other tasks, but overwhelmingly Instagram&#8217;s stack consists of stolid, proven tools.</p>
<p>Among the newer stuff is Instagram&#8217;s use of <a href="http://redis.io/">Redis</a> to store <a href="http://instagram-engineering.tumblr.com/post/12202313862/storing-hundreds-of-millions-of-simple-key-value-pairs">hundreds of millions of key-value pairs</a> for fast feeds, and <a href="http://gunicorn.org/">Gunicorn</a> instead of Apache as a web server.</p>
<p>All in all it&#8217;s a very impressive setup that has, thus far, helped Instagram avoid the down time that has plague many similar services hit with the same kind of exponential growth. (Twitter, I&#8217;m looking at you.) For more details on how Instagram looks behind the scenes and which tools the company uses, be sure to check out <a href="http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances-dozens-of">the blog post</a> as well as <a href="http://instagram-engineering.tumblr.com/archive">the archives</a>.</p>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2012/04/behind-the-scenes-at-instagram-tools-for-building-reliable-web-services/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>OpenStreetBlock Gives Geodata the Human Touch</title>
        <link>http://www.webmonkey.com/2011/04/openstreetblock-gives-geodata-the-human-touch/</link>
        <comments>http://www.webmonkey.com/2011/04/openstreetblock-gives-geodata-the-human-touch/#comments</comments>
        <pubDate>Thu, 07 Apr 2011 17:27:18 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=50509</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[geodata]]></category>
		<category><![CDATA[maps]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2011/04/openstreetblock.jpg" type="image/jpeg" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2011/04/openstreetblock.jpg" alt="OpenStreetBlock Gives Geodata the Human Touch" /></div>Location-based web services are all the rage right now, but for most of us the actual geographic location isn&#8217;t very interesting &#8212; do you know where &#8220;40.737813,-73.997887&#8243; is off the top of your head? No? How about &#8220;West 14th Street bet. 6th Ave. and 7th Ave?&#8221; For the geographic web to become useful geodata has [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->
<p><a href="http://www.webmonkey.com/wp-content/uploads/2011/04/openstreetblock.jpg"><img src="http://www.webmonkey.com/wp-content/uploads/2011/04/openstreetblock.jpg" alt="" title="openstreetblock" width="520" height="316" class="aligncenter size-full wp-image-50510" /></a>Location-based web services are all the rage right now, but for most of us the actual geographic location isn&#8217;t very interesting &#8212; do you know where &#8220;40.737813,-73.997887&#8243; is off the top of your head? No? How about &#8220;West 14th Street bet. 6th Ave. and 7th Ave?&#8221;</p>
<p>For the geographic web to become useful geodata has to be converted into something humans actually understand. Enter <a href="http://transit.frumin.net/openstreetblock/">OpenStreetBlock</a>.</p>
<p>OpenStreetBlock is a new web service that takes geographic coordinates (latitude/longitude pairs) and turns them into an actual city block description. The result is textual information which, in many cases, will be even more meaningful to your users than the ubiquitous pin on a map.</p>
<p>If you&#8217;d like to play around with a sampling of data from New York, head over to <a href="http://transit.frumin.net/openstreetblock/">OpenStreetBlock and try out the New York demos</a>.</p>
<p>If you&#8217;ve ever wanted to <a href="http://www.webmonkey.com/2009/07/source_code_offers_a_glimpse_of_the_magic_behind_everyblockdotcom/">build your own version of EveryBlock</a> &#8212; which pinpoints events, news stories and public data at the city-block level &#8212; OpenStreetBlock will go a long way toward getting you there. So long as you can pull geo coordinates out of your source data, OpenStreetBlock can turn that into more meaningful information.</p>
<p>Under the hood OpenStreetBlock relies on OpenStreetMap data and uses PHP in conjunction with a geographic database to turn your coordinates into block descriptions.</p>
<p>As cool as OpenStreetBlock is, getting it up and running on your own site will require a bit of work. Luckily, there are some good tutorials available that will walk you through the process of installing and setting up many of the prerequisites like PostgreSQL and PostGIS (I&#8217;ll assume you already have an Apache server with PHP installed).</p>
<p>To get started with OpenStreetBlock, <a href="https://github.com/fruminator/openstreetblock">grab the code from GitHub</a>. The next thing you&#8217;ll need is a PostgreSQL database with all the PostGIS tools installed. Luckily those are also prerequisites for GeoDjango, so head over to the <a href="http://docs.djangoproject.com/en/dev/ref/contrib/gis/install/#spatial-database">GeoDjango installation page</a>, skip the Django-specific parts and just follow the Postgres and PostGIS installation instructions.</p>
<p>Next you&#8217;ll need to download <a href="http://wiki.openstreetmap.org/wiki/Osmosis">Osmosis</a> and <a href="http://wiki.openstreetmap.org/wiki/Osm2pgsql">Osm2pgsql</a> to convert OpenStreetMap data into something Postgres can handle. Head over to <a href="http://www.openstreetmap.org/">OpenStreetMap</a>, zoom into an area you&#8217;d like to query with OpenStreetBlock and then choose &#8220;export.&#8221; Select the OpenStreetMap XML Data option and save the file.</p>
<p>From there you can check out the guide to importing the OpenStreetMap XML Data in the <a href="https://github.com/fruminator/openstreetblock/blob/master/README">OpenStreetBlock read me</a>. </p>
<p><strong>See Also:</strong><br/></p>
<ul>
<li><a href="http://www.webmonkey.com/2010/03/where-20-simplegeo-to-launch-itunes-for-geodata/">Where 2.0: SimpleGeo to Launch &#8216;iTunes for Geodata&#8217;</a></li>
<li><a href="http://www.webmonkey.com/2009/07/source_code_offers_a_glimpse_of_the_magic_behind_everyblockdotcom/">EveryBlock Source Code Release Offers Glimpse of the Magic Behind the Curtain</a></li>
<li><a href="http://www.webmonkey.com/2010/01/user-contributed_announcements_give_everyblock_a_human_touch/">User-Contributed Announcements Give EveryBlock a Human Touch</a></li>
<li><a href="http://www.webmonkey.com/2010/08/beautiful-websites-stamens-pretty-maps/">Beautiful Websites: Stamen&#8217;s Pretty Maps</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2011/04/openstreetblock-gives-geodata-the-human-touch/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Open Data&#8217;s Access Problem, and How to Solve it</title>
        <link>http://www.webmonkey.com/2010/09/open-datas-access-problem-and-how-to-solve-it/</link>
        <comments>http://www.webmonkey.com/2010/09/open-datas-access-problem-and-how-to-solve-it/#comments</comments>
        <pubDate>Wed, 22 Sep 2010 19:05:34 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=48785</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[Gov20]]></category>
		<category><![CDATA[government]]></category>
		<category><![CDATA[Gurstein]]></category>
		<category><![CDATA[Open data]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2010/09/punchcard580.jpg" type="image/jpeg" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2010/09/punchcard580.jpg" alt="Open Data&#8217;s Access Problem, and How to Solve it" /></div>The recent Gov 2.0 summit in Washington D.C. saw several promising new announcements which will help government agencies share code and best practices for making public data available to developers. The idea behind new projects like Challenge.gov, the FCC&#8217;s new developer tools and the Civic Commons is that by giving developers access to data previously [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->
<p><img src="http://www.webmonkey.com/wp-content/uploads/2010/09/punchcard580.jpg" alt="" title="punchcard" /></p>
<p>The recent <a href="http://www.gov2summit.com/gov2010">Gov 2.0 summit</a> in Washington D.C. saw several promising new announcements which will help government agencies share code and best practices for making public data available to developers.</p>
<p>The idea behind new projects like <a href="http://challenge.gov/">Challenge.gov</a>, the <a href="http://reboot.fcc.gov/developer/">FCC&#8217;s new developer tools</a> and the <a href="http://civiccommons.com/2010/09/introducing-civic-commons/">Civic Commons</a> is that by giving developers access to data previously stored in dusty filing cabinets, they can create tools to give ordinary citizens greater access to that data.</p>
<p>Unfortunately, not everything open data project leads to good things. It is critical that if open data is made available on the web, it must be accompanied by some effort to ensure everyone can access it.</p>
<p>We&#8217;ve seen an explosion in creative hacks that use this newly available data to provide excellent online resources. Public data sites like <a href="http://www.webmonkey.com/2008/01/everyblock_launches_hyper-local_news_service_for_big_cities/">EveryBlock</a>, or the Sunlight Foundation&#8217;s <a href="http://www.webmonkey.com/2010/03/sunlight-labs-offering-5k-for-best-government-data-mashups/">Design for America contest</a> have highlighted some of the amazing ways open data can make our lives better. Whether it&#8217;s finding out crime stats, real estate values, health hazards and business license statuses in your neighborhood, or visualizing how the government is spending your tax dollars through innovative maps, open data and what you can do with it is the current hotness among web developers.</p>
<p>Most of the benefits are close to home &#8212; in the U.S., just about everyone has access to online government resources thanks to web-enabled computers in free public libraries.</p>
<p>But extend that argument to the rest of the world and the number of people that really have access to the data drops significantly. If you don&#8217;t have an easy way to get online, you can&#8217;t benefit from open data.</p>
<p>Michael Gurstein, Executive Director of the <a href="http://www.communityinformatics.net/">Center for Community Informatics Research</a>, recently highlighted some of the <a href="http://gurstein.wordpress.com/2010/09/02/open-data-empowering-the-empowered-or-effective-data-use-for-everyone/">problems with open data accessibility</a>.</p>
<p>Gurstein points out a number of assumptions about open data that are often overlooked by those most enthusiastic about making such data publicly available.</p>
<p>Worse, he shows how such data can be used against you.</p>
<p><span id="more-48785"></span></p>
<p>Gurstein&#8217;s example of the dark side of open data is Bangalore, India&#8217;s digitization of land records, which gives every citizen a way to see who owns what in Bangalgore. On the surface, it seems like a good thing, but the upper classes and corporations have been using the land records data to gain ownership of land from the unknowing poor.</p>
<p>The data, writes Gurstein, allowed the well-to-do to instruct surveyors and lawyers how to most effectively &#8220;challenge titles, exploit gaps in title, take advantage of mistakes in documentation, identify opportunities and targets for bribery&#8221; among other things. Details are in <a href="http://casumm.files.wordpress.com/2008/09/bhoomi-e-governance.pdf">this PDF</a>.</p>
<p>It isn&#8217;t necessary to go all the way to India to find examples of open data leading to unintended consequences.</p>
<p>In an e-mail exchange, Gurstein told me of a similar case in Nova Scotia where efforts to make titles, deeds and other land data led to very same situation &#8212; companies pouring over 19th century deeds, ancient maps and other newly available data, finding oversights, misfiled papers and other means to seize land from owners.</p>
<p>Of course unintended consequences aren&#8217;t a reason to stop making data available. For Gurstein, the solution is to make sure that open data isn&#8217;t just thrown onto the web, but that universal accessibility is built in so it can really benefit everyone.</p>
<p>How that is done will vary considerably by location and the type of data in question, but without such efforts Gurstein worries that &#8220;the outcome of &#8216;open data&#8217; may be quite the opposite to that which is anticipated (and presumably desired) by its strongest proponents.&#8221;</p>
<p>It might come as a shock to some of the more enthusiastic open data proponents, but there is more to open data than just dredging it out of the Indiana Jones-style warehouses where it currently gathers dust. Putting it online for &#8220;anyone&#8221; access and just walking away isn&#8217;t necessarily a recipe for good things.</p>
<p>Gurstien also pointed out several solutions to me, which <a href="http://gurstein.wordpress.com/2010/09/09/open-data-2-effective-data-use/">he lists in a follow-up blog post</a>. These solutions would help ensure that what happened in Nova Scotia and Bangalore won&#8217;t happen elsewhere. Among the things he believes governments and other data providers need to take into account are:</p>
<ul>
<li><strong>Advocacy</strong> &#8212; Perhaps the most important of Gurstein&#8217;s guidelines is to ensure that everyone knows the data is available, making sure that a community&#8217;s resources are sufficient for turning the data into some kind of project with local benefits.</li>
<li><strong>Internet access</strong> &#8212; Especially a concern in rural areas, the level of internet access is the cornerstone to open data. Just because data is on the web does not mean everyone can get to it. And if not everyone has access, then your data isn&#8217;t &#8220;open.&#8221;</li>
<li><strong>Content and formatting</strong> &#8212; If the data just a raw GIS database that most people won&#8217;t understand, then even internet access doesn&#8217;t matter because only those with specific skills (or the money to hire them) will be able to do anything with the data.</li>
<li><strong>Computer/software skills</strong> &#8212; Similar to content and formatting issues is having access to GIS tools and other specialty software. As Gurstein says &#8220;techies know how to do the visualization stuff, university and professional types know how to use the analytical software but ordinary community people might not know how to do either.&#8221;</li>
</ul>
<p>It&#8217;s also worth pointing out that Gurstein has several examples of open data being used in constructive ways. He isn&#8217;t arguing that we shouldn&#8217;t put government and other data online, just that we should keep in mind that the data isn&#8217;t necessarily useful to everyone in its most raw forms.</p>
<p>As Tim O&#8217;Reilly <a href="https://twitter.com/timoreilly/status/23179898934">notes</a> in conjunction with Gurstein&#8217;s post, &#8220;we need to think deeply about the future&#8221; &#8212; to consider all the consequences of open data, not just the ones we&#8217;d like to see.</p>
<p><em>Punchcard scan by Steve Collins/<a href="http://www.flickr.com/photos/24876360@N03/4069007704/">Flickr</a>/CC</em></p>
<p><strong>See Also:</strong><br/></p>
<ul>
<li><a href="http://www.webmonkey.com/2010/03/sunlight-labs-offering-5k-for-best-government-data-mashups/">Sunlight Labs Offering $5K for Best Government Data Mashups</a></li>
<li><a href="http://www.webmonkey.com/2008/01/everyblock_launches_hyper-local_news_service_for_big_cities/">EveryBlock Launches Hyper-local News Service for Big Cities</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/09/open-datas-access-problem-and-how-to-solve-it/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>Big Data in the Deep Freeze: John Jacobsen of IceCube</title>
        <link>http://www.webmonkey.com/2010/07/big-data-in-the-deep-freeze-john-jacobsen-of-icecube/</link>
        <comments>http://www.webmonkey.com/2010/07/big-data-in-the-deep-freeze-john-jacobsen-of-icecube/#comments</comments>
        <pubDate>Fri, 23 Jul 2010 21:16:51 +0000</pubDate>

                <dc:creator>Michael Calore</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=48144</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Other]]></category>
		<category><![CDATA[IceCube]]></category>
		<category><![CDATA[oscon]]></category>
		<category><![CDATA[OSCON2010]]></category>
		<category><![CDATA[video]]></category>
        <description><![CDATA[<p>John Jacobsen works for the <a href="http://www.icecube.wisc.edu/info/">IceCube telescope project</a>, the world's largest neutrino detector, located at the South Pole. The project's mission is to search for the radioactive sub-atomic particles that have been generated by violent astrophysical events: "exploding stars, gamma ray bursts, and cataclysmic phenomena involving black holes and neutron stars," according to the project website.

<p>Jacobsen is one of the people in charge of handling all the Big Data collected by IceCube. In the video, shot this week at the <a href="http://www.oscon.com/oscon2010">O'Reilly OSCON 2010</a> conference in Portland, Oregon, John explains how they collect a terabyte of raw data per hour, then send everything to IceCube's remote research and backup facilities using a finicky satellite hook-up.

<p>Antarctica is one of the least accomidating places on Earth to perform scientific research with computers. It's the driest place on the planet -- atmospheric humidity hovers around zero -- and bursts of static electricity can cause catastrophic harm to IceCube's data stores. The lack of humidity causes the server clusters' cooling systems to break down. And if something fails, a spare might take six months to arrive.]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><object width="580" height="351"><param name="movie" value="http://www.youtube.com/v/v9VUk9xB6co&amp;hl=en_US&amp;fs=1?hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/v9VUk9xB6co&amp;hl=en_US&amp;fs=1?hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="580" height="351"></embed></object></p>
<p>John Jacobsen works for the <a href="http://www.icecube.wisc.edu/info/">IceCube telescope project</a>, the world&#8217;s largest neutrino detector, located at the South Pole. The project&#8217;s mission is to search for the radioactive sub-atomic particles that have been generated by violent astrophysical events: &#8220;exploding stars, gamma ray bursts, and cataclysmic phenomena involving black holes and neutron stars,&#8221; according to the project website.</p>
<p>Jacobsen is one of the people in charge of handling the massive amounts of data collected by IceCube. In the video, shot this week at the <a href="http://www.oscon.com/oscon2010">O&#8217;Reilly OSCON 2010</a> conference in Portland, Oregon, John explains how they collect a terabyte of raw data per hour, then send everything to IceCube&#8217;s remote research and backup facilities using a finicky satellite hook-up.</p>
<p>Antarctica is one of the least accommodating places on Earth to perform scientific research with computers. It&#8217;s the driest spot on the planet &#8212; atmospheric humidity hovers around zero &#8212; and bursts of static electricity threaten the integrity of IceCube&#8217;s data stores. The lack of humidity causes the server clusters&#8217; cooling systems to break down. And if something fails, a spare might take six months to arrive.</p>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/07/big-data-in-the-deep-freeze-john-jacobsen-of-icecube/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>Sunlight Labs Offering $5K for Best Government Data Mashups</title>
        <link>http://www.webmonkey.com/2010/03/sunlight-labs-offering-5k-for-best-government-data-mashups/</link>
        <comments>http://www.webmonkey.com/2010/03/sunlight-labs-offering-5k-for-best-government-data-mashups/#comments</comments>
        <pubDate>Mon, 29 Mar 2010 18:30:30 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=47046</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Visual Design]]></category>
		<category><![CDATA[contest]]></category>
		<category><![CDATA[goverment]]></category>
		<category><![CDATA[Sunlight Foundation]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2010/03/designforamerica.png" type="image/png" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2010/03/designforamerica.png" alt="Sunlight Labs Offering $5K for Best Government Data Mashups" /></div>Artists, web developers and data visualization geniuses, here&#8217;s a chance to strut your stuff, serve your country and win some serious money in the process. Sunlight Foundation, a non-profit organization that provides tools to make government data more transparent, has announced a new contest called Design for America. Billed as a &#8220;design and data visualization [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><img src="http://www.webmonkey.com/wp-content/uploads/2010/03/designforamerica.png" alt="designforamerica" title="designforamerica" width="560" height="155" class="aligncenter size-full wp-image-47049" /></p>
<p>Artists, web developers and data visualization geniuses, here&#8217;s a chance to strut your stuff, serve your country and win some serious money in the process.</p>
<p>Sunlight Foundation, a non-profit organization that provides tools to make government data more transparent, has announced a new contest called <a href="http://sunlightlabs.com/contests/designforamerica/">Design for America</a>. Billed as a &#8220;design and data visualization extravaganza,&#8221; Sunlight is encouraging the public to create and publish data visualizations that help make complex government data easier for people to digest and interact with.</p>
<p>There are several different categories open for submission, including: visualizations of Recovery.gov data that shows how the stimulus money is being spent, visualizations showing how a bill becomes a law, a redesign of a .gov website, and a redesign of any government form. Top prize in each category is a cool $5,000.</p>
<p>Creations can be in any form &#8212; a website, a game, a poster, a sculpture, whatever &#8212; though we suspect most of the entries will be either posters or interactive Flash graphics.</p>
<p>The contest is being run by Sunlight Labs, the skunkworks wing of the larger Sunlight Foundation. The Sunlight group spends most of its energy collecting government data, organizing it into publicly accessible databases, then creating tools that make it easier for ordinary people to access that data. The non-profit works with organizations like <a href="http://www.opencongress.org/">OpenCongress</a>, <a href="http://maplight.org/">MapLight</a>, <a href="http://www.followthemoney.org/">FollowTheMoney</a> and <a href="http://www.usaspending.gov/">USASpending.gov</a>. Sunlight also maintains a <a href="http://wiki.sunlightlabs.com/Main_Page#Public_APIs_for_government_data">list of APIs</a> developers can use to access the data.</p>
<p>The Design for America contest encourages participants to sift through the vast datasets available from all of these organizations, as well as the datasets maintained by Sunlight Foundation and any raw government data that&#8217;s available. As the Sunlight Labs blog says, the goal of the contest is to &#8220;tell interesting stories&#8221; that go beyond what can be an overwhelming amount of unfiltered data.</p>
<p>Visualizations can be in any medium, not just the web, so if you&#8217;re a video or infographic specialist, you can still enter the contest. The main criteria for judging are the visual quality of the artwork and how well the underlying information is conveyed.</p>
<p><span id="more-47046"></span></p>
<p>Design for America follows in the footsteps of Sunlight&#8217;s <a href="http://www.sunlightlabs.com/contests/appsforamerica/">Apps for America contests</a>, which sought to bring transparency and accountability to government using open web applications to mine government data sites. Apps for America generated a number of useful apps &#8212; like RSS feeds for the House Committee schedule, <a href="http://www.earmarkwatch.org/">GovPulse</a> and the <a href="http://www.earmarkwatch.org/">Earmark Watch</a> tool, among others. With any luck, the Design for America contest will generate some equally useful and enlightening visualizations of government data.</p>
<p>If you&#8217;d like to test your mashup and design chops, head over to Sunlight Labs and have a look at the full contest rules. One important thing for designers to keep in mind &#8212; your entry needs to be licensed under a <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons By-Attribution</a> or <a href="http://www.opensource.org/licenses/alphabetical">Creative Commons 0</a> license, or an <a href="http://www.opensource.org/licenses/alphabetical">OSI approved license</a> for those submitting code.</p>
<p>The contest judges vary by category, but the list includes some big names in the online design world &#8212; Nicholas Feltron and Nathan Yau are both on the list, as are various members of Sunlight Labs and other design gurus. </p>
<p>Design for America submissions are due by May 17 and the winners will be announced at the <a href="http://www.gov2expo.com/gov2expo2010">Gov 2.0 Expo</a> in Washington, D.C. on May 27. </p>
<p><strong>See Also:</strong><br/></p>
<ul>
<li><a href="http://www.webmonkey.com/2009/05/historical_map_mashups_turn_cities_into_glass_onions_of_time/">Historical Map Mashups Turn Cities Into Glass Onions of Time</a></li>
<li><a href="http://www.webmonkey.com/2010/01/user-contributed_announcements_give_everyblock_a_human_touch/">User-Contributed Announcements Give EveryBlock a Human Touch</a></li>
<li><a href="http://www.webmonkey.com/2009/12/the_twitter_api_is_becoming_far_more_than_just_an_api_for_twitter/">Twitter API Is Becoming Far More than Just an API for Twitter</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/03/sunlight-labs-offering-5k-for-best-government-data-mashups/feed/</wfw:commentRss>
        <slash:comments>4</slash:comments>

        
    </item>
    
    <item>
        <title>Build a Website With Flash and MySQL &#8211; Lesson 1</title>
        <link>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_1/</link>
        <comments>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_1/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=682</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Multimedia]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Overview There&#8217;s always been somewhat of a disconnect between designer-types and backend-types. And we&#8217;re not just talking about hairstyles, eyewear, and the contents of their bookshelves &#8212; designers and programmers approach problems in different ways, and their individual plans of attack don&#8217;t always jibe. Of course, you want your site to be sleek, fast, and [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><b>Overview</b>

</p><p>There&#8217;s always been somewhat of a disconnect between designer-types and backend-types. And we&#8217;re not just talking about hairstyles, eyewear, and the contents of their bookshelves &#8212; designers and programmers approach problems in different ways, and their individual plans of attack don&#8217;t always jibe. Of course, you want your site to be sleek, fast, and bleeding-edge, but are you willing to compromise stability, scalability, and compatibility just so the users can ooh and aah at a few pretty pictures? Web design has always been a balancing act, and the ideologies of each camp often clash.

</p><p>But Webmonkey&#8217;s here to say that it doesn&#8217;t have to be that way. It is possible to create a site that has a lightweight Flash frontend, a dreamy interface, and a scalable, secure, and dynamic backend.

</p><p>Webmonkey Scott has found the balance between eye-catching design and backend database wizardry. Lucky for us, he&#8217;s agreed to share this knowledge in a two-day tutorial. He&#8217;s even put together a hands-on project that shows you how to build an easy-to-update blog using Flash. That&#8217;s right, a Flash-based blog &#8212; it sounds a little loony, but this blog pulls content from a MySQL database and feeds it into the dynamic Flash frontend using a few lines of PHP code.

</p><p>In day one, Scott talks you through the construction of an open source MySQL database using both the phpMyAdmin tool and mysql on the command line. You&#8217;ll learn how to add blog entries to the database and then you&#8217;ll learn how to run queries in PHP. Topics such as basic database organization and the behavior of variables are also covered in this lesson.

</p><p>Day two shows you how to design and build the blog&#8217;s Flash frontend. You&#8217;ll use common Flash ActionScript objects to pull the content from your MySQL database to the different areas of your blog&#8217;s user interface. You&#8217;ll also learn some common workarounds to keep all of your content flowing smoothly.

</p><p>Whether you are designer or a programmer, it&#8217;s time to roll up those sleeves and get ready to see how the other half lives. Even if those of you who don&#8217;t feel a particular loyalty to either side of the fence will still discover that there&#8217;s plenty of hands-on knowledge to be gained.

</p><p>We&#8217;re not promising that designers will sell their $500 pencil sharpeners, start marrying UNIX geeks, and honeymooning in Cancun before breeding programmer/designer children, but we will insist that they sit in a room alone together until they can build a useful website that everyone can agree on. Hey, stranger things have happened. Like <a href="http://www.mcsweeneys.net/links/lists/carrottop.html" class="external text" title="http://www.mcsweeneys.net/links/lists/carrottop.html" rel="nofollow">Carrot Top</a>.



</p><span id="more-682"></span><p><br />

</p>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#Building_with_Flash_and_MySQL">Building with Flash and MySQL</a></li>

<li><a href="#PHP_Basics">PHP Basics</a></li>



<li><a href="#Using_MySQL">Using MySQL</a></li>

<li><a href="#Creating_the_Database">Creating the Database</a></li>

<li><a href="#Entering_Data">Entering Data</a></li>

<li><a href="#Add_a_Dash_of_PHP">Add a Dash of PHP</a></li>

<li><a href="#Strings.2C_Sealing_Wax.2C_Fancy_Stuff">Strings, Sealing Wax, Fancy Stuff</a></li>







</ol>

</td></tr></tbody></table>



<a name="Building_with_Flash_and_MySQL"></a><h4> <span class="mw-headline">Building with Flash and MySQL</span></h4>

<p>From the beginning, the database has been the sole province of programming geeks. For designers, usually geeks themselves, but with backgrounds in color theory or animation rather than code architecture, the jargon surrounding databases is often confusing, overwhelming, and intimidating. Even so, the irony is that designers are sometimes the very people who can benefit the most from using a database.

</p><p>Many designers can create eye-popping sites full of life, but it&#8217;s rare to find a designer who can sustain that initial vibrancy as the site ages. How often have you seen an amazing-looking site that was created, hyped, then abandoned?

</p><p>Database integration can propel a website from a well-designed but infrequently updated bore to a dynamically generated, updated-on-the-fly extravaganza for the mind. Connecting your design to content driven by a database gives you or your clients a site that can be updated easily without ever needing to touch the design elements themselves. Also, this separation of content and container will make your job as a designer much easier. With the continuous flow of timely content from your easy-to-update database, your site will stay fresh and youthful. It works better than any of those creams from France, anyway.

</p><p>As a good designer, you&#8217;re capable of translating loosely held, often ill-conceived ideas into the sites we all use and enjoy. What&#8217;s more you make them look <i>good</i>. But perhaps dealing with raw code is not your forte. Not to worry, it&#8217;s not as difficult as you might think.

</p><p>To get the full benefits a database offers, we&#8217;re going to feed our content into a Flash movie rather than an HTML page. Why would you want to do that, you ask? As a seasoned Web surfer, you&#8217;re probably familiar with the so-called &#8220;blink&#8221; of HTML. The process goes a little something like this:You click a link, the link then sends a command (often via PHP, which we&#8217;ll use here) to a database to retrieve whatever information you&#8217;re after. Once the database has retrieved your information, it sends that info back to the page that requested it. Now, if that page is HTML, your browser must weed through the results and shape them accordingly. But, before it can do any of that, the browser must first empty out the old page and create that momentary blank browser window &#8211; the blink of HTML.

</p><p>This doesn&#8217;t happen with Flash. Flash can load the data into the very same place from which it was requested without a visible refresh. No blink. No redrawing of elements that haven&#8217;t changed. In short, a smoother, less distracting transition for your user which leads to a better, more enjoyable viewing experience.

</p><p>Everybody convinced? Then let&#8217;s get started.

</p>

<a name="PHP_Basics"></a><h4> <span class="mw-headline">PHP Basics</span></h4>



<p>If you&#8217;ve worked with databases before, even if you&#8217;ve always fed the content into HTML pages, you&#8217;ll have a head start here. I&#8217;ll be assuming that you have MySQL and PHP installed and running on your server. If you&#8217;re going to be doing this through your Web hosting company, check to see if they already have the necessary software installed. If you find that you need to install either program, check out <a href="/2010/02/PHP_and_MySQL_Tutorial" title="Tutorial:PHP and MySQL Tutorial"> PHP and MySQL Tutorial</a>, which will also be a helpful read for those of you who&#8217;ve never worked with PHP since it goes into a little more detail on the syntax. The <a href="http://www.mysql.com" class="external text" title="http://www.mysql.com" rel="nofollow">homebase for MySQL</a> has a full manual available for download, as does the <a href="http://www.php.net" class="external text" title="http://www.php.net" rel="nofollow">official PHP site</a>. Take advantage of these free resources. Many hardworking volunteers have created them for you, and answers to most nitty-gritty questions can be found on one of those sites.

</p><p>If your website is hosted by someone other than yourself, you will have to ask your hosting company how to connect and interact with your database. Most good hosting companies will have you interact with your database via your Web browser and the <a href="http://www.phpmyadmin.net/home_page/" class="external text" title="http://www.phpmyadmin.net/home_page/" rel="nofollow">phpMyAdmin</a> program. The application will give you a nice graphical interface for creating tables and entering information. Also, phpMyAdmin shows you the actual MySQL syntax for your actions, which will let you get a better feel for how MySQL works. Really good hosting companies will let you connect directly via a secure shell or some other graphical program of your choice.

</p><p>There are many other graphical ways to interact with MySQL, but for the purpose of this tutorial, I will be giving examples from a terminal interface using the mysql client program, which comes with the MySQL package.

</p><p>Why use a terminal when GUIs of all shapes and sizes are available? Graphical interfaces may allow you to interact and manipulate data, but they often do so without letting you understand exactly what it is you&#8217;re doing. Typing the commands in a terminal session will help you not only learn the SQL syntax but understand how and why you&#8217;re doing what you&#8217;re doing. Knowledge of the SQL syntax will give you a better understanding of how to use PHP to manipulate SQL data. And what are you going to do when you land that dream project you spent months pitching only to learn you aren&#8217;t going to have access to a GUI? Over-reliance on GUIs is not the monkey way. Don&#8217;t let the command line intimidate you.

</p><p>To take full advantage of the organization a database offers, it helps to sit down ahead of time with a pen and piece of paper (made from trees &#8230; or even better, recycled material &#8230; like in high school) and plan out your database. Databases are simply means of organizing information into tables. Tables are made up of columns and rows. Typically each vertical column is some category of information and each horizontal row is an individual instance of that information. Too abstract? Think of your monthly bank statement. If it&#8217;s anything like mine, it&#8217;s a simple table (full of zeros). Across the top are column definitions (check number, payee, amount, et cetera). Reading horizontally, each line contains values that are given meaning by the column they&#8217;re in. MySQL databases work very much the same way. We create tables, define columns, and enter rows of data. The main difference is that our information will be searchable by any criteria we define.

</p><p>Unfortunately, those MySQL searches cannot be run directly from your browser. Thus, while we can enter the commands and search in our terminal (or GUI bad monkey, no banana), we can&#8217;t write some HTML code and duplicate those search results. But that&#8217;s OK, because there are other languages that <i>can</i> duplicate them. The two main languages used in a database search, or <i>query</i>, are PHP and Perl. For our purposes, which will be to deliver Web content to Flash, we&#8217;re going to use PHP. PHP was developed to specialize in database connections on the Web.



</p><p>Chances are many of the sites you visit everyday are generated using PHP. You&#8217;ve been seeing the benefits without ever knowing what was going on behind the nicely formatted information you receive. How did PHP give you your information without you even knowing it was doing so? If you view the source of a PHP page you will only see HTML. Where the <i>heck</i> is the PHP and how does it do what it does? We&#8217;ll get to that part a little later. Right now let&#8217;s dive into MySQL and feed it some information.

</p>

<a name="Using_MySQL"></a><h4> <span class="mw-headline">Using MySQL</span></h4>

<p>Databases are serious stuff my friends, and databases call for serious examples. When I think of seriousness and integrity on the Web, the first thing that comes to mind is the weblog. Ahem.

</p><p>Anyway let&#8217;s suppose you&#8217;re one of the two people who don&#8217;t yet have a blog. Or even better, let&#8217;s suppose you want to create a weblog that&#8217;s a little different from the endlessly repeated templates you see everyday. Let&#8217;s suppose for a moment that you want to create your very own <i>Flash</i>-based weblog to tell the world about your ever-growing collection of florescent feather boas or your serialized, Charles Dickens-style Great American Novel (Great British Novel just doesn&#8217;t have the same ring, sorry). Whatever it is, you plan on telling the world something about it each and every day.

</p><p>Well then, let&#8217;s think about this for a moment. Your user interface will be a Flash .swf file that will display content from your MySQL database. How do you want to organize your data? That&#8217;s really up to you. The simplest approach is the date-based model that most weblogs out there function on:one date, one title, one entry. Our simplest case calls for a table that contains the following information:

</p><p><img src="http://www.wired.com/wired/webmonkey/stuff/Flash_MySQL_chart1.gif" alt="Flash_MySQL_chart1.gif">

</p><p>Before we run off to create this table, let&#8217;s first look at some potential problems with our mock-up (remember: measure twice, cut once). While this table meets our most basic needs, we might want to include a few other things. Let&#8217;s say for instance that down road, when we get more sophisticated with our site, we want to be able to search according to subject. Well, right this minute we aren&#8217;t going to bother with a subject column, but in the future we might want to add a whole separate table to contain metadata of this sort. To link a new table to this one we&#8217;d need an index column. So our mock-up should include an ID column which will cover us if we&#8217;d ever like to add to our database. We&#8217;ll also be using the ID column to simplify the process of finding the newest entry.

</p><p><img src="http://www.wired.com/wired/webmonkey/stuff/Flash_MySQL_chart2.gif" alt="Flash_MySQL_chart2.gif">

</p><p>Alright, we&#8217;ve done all of our paperwork. Our database-to-be looks pretty robust, so let&#8217;s go ahead and create it.



</p>

<a name="Creating_the_Database"></a><h4> <span class="mw-headline">Creating the Database</span></h4>

<p>For this example, I&#8217;m going to assume you&#8217;re using the mysql client (note the all lowercase mysql, this denotes the client program that comes free with MySQL) in the command line. To fire up the mysql client, start up a new terminal window and login to your server using the format:<tt>/Path/To/mysql/ -h yourHostname -u yourUser -p</tt>. Enter your password when prompted. Now we&#8217;re going to issue the following commands (and don&#8217;t forget your semicolons):

</p>

<pre class="brush: js">mysql&gt; CREATE DATABASE blog_db;

</pre>

<p>This command tells MySQL to create a new database named blog_db (you can give it whatever name you like, just adjust everything accordingly). Now switch to the new database.

</p>

<pre class="brush: js">mysql&gt; USE blog_db;



</pre>

<p>You can verify that you&#8217;re actually using the blog_db by issuing a SELECT DATABASE() command which will tell basic information about our newly created blog_db database, namely, that it contains nothing. An empty database is a useless database, so let&#8217;s create a table. Your input will look like this:

</p>

<pre class="brush: js">CREATE TABLE blog_entries (



 id INT NOT NULL AUTO_INCREMENT ,



 date DATETIME NOT NULL ,



 title VARCHAR (30 )NOT NULL ,



 entry LONGTEXT NOT NULL ,



 PRIMARY KEY (id)



 );

</pre>

<p>OK what the hell is all that gibberish? Let&#8217;s walk through it one statement at a time.

</p><p>The CREATE statement should be obvious:It creates a new table by the name of blog_entries. Next, we fill out our table. But we don&#8217;t want just a table, we want to define our four columns that we&#8217;re going to use to organize our data. So, &#8220;id&#8221; is the first column and will be an integer, defined by INT(). The NOT NULL statement simply means that each row must have a value for this column. As you can see, I&#8217;ve set the table up to require values for all the columns. If you need some rows of a table left blank, simply change the statement to NULL which will allow blanks, or &#8220;null values&#8221; in database speak. The AUTO_INCREMENT statement tells MySQL to assign a new value for each row and to increment that number each time we enter another row. In other words, the first entry will get a value of 1, the second 2, and so on. This way, we don&#8217;t have to keep track of what entry number we&#8217;re on; we let MySQL do it for us. This will allow us to always find the most recent entry by querying for the largest number. This information will come in handy when we start writing queries in PHP.

</p><p>Next is DATETIME, a predefined format that will have MySQL stamp each entry with the current date and time. VARCHAR, on the next line, is short for variable character. This means that entries in the title column will be filled with characters of varying length. I chose to cut them off at 30 characters, but you can specify any number you&#8217;d like (up to 255). The last datatype we&#8217;re using is LONGTEXT. LONGTEXT allows up to 4,294,967,295 characters. That&#8217;s over one million words per entry &#8212; possibly overkill for our purposes, but I thought we&#8217;d play it safe. You could also use MEDIUMTEXT if you&#8217;re feeling less wordy than me. PRIMARY KEY is somewhat more complex, and I&#8217;m not going to explain it here, other than to say that if a column is AUTO_INCREMENTed it must be a primary key.

</p><p>Whew! Alright, just to make sure that MySQL created things the way we expect, issue the command DESCRIBE blog_entries and you should see the following:

</p><p><img src="http://www.wired.com/wired/webmonkey/stuff/Flash_MySQL_chart3.gif" alt="Flash_MySQL_chart3.gif">

</p><p>Notice the date format is year-month-day. Putting the year first takes some getting used to, but this is how MySQL handles dates &#8212; you&#8217;re just going to have to keep that in mind. We&#8217;re good monkeys, flexible and capable of adaptation.

</p>

<a name="Entering_Data"></a><h4> <span class="mw-headline">Entering Data</span></h4>

<p>Okay, we have our table all set up. Now we just need to enter some data. Entering information into MySQL can be very laborious when done by hand. For this reason, extensions were written to read from tab-delimited text files. However, since our table is pretty simple, and it&#8217;s unlikely that we&#8217;ll be entering more than one row at a time, I&#8217;m going to go ahead and enter things the old fashioned way. When your data gets more complex, you&#8217;ll want to investigate how to enter from external files. A good starting point would be the <a href="http://www.mysql.com/" class="external text" title="http://www.mysql.com/" rel="nofollow">MySQL site</a>.



</p>

<pre class="brush: js"> INSERT INTO blog_entries VALUES



 (



 '',NOW(),'my first blog entry','your text here'



 );



</pre>

<p>The main thing to notice here is that the first value is blank. The <i> value for the ID column tells MySQL to go ahead and insert the auto increment number, in this case, the integer one. The NOW() function gives us the current date and time. If you wanted to forge an older or newer date and time, you could enter them by hand in the format discussed earlier (YYYY-MM-DD 00:00:00). Double check to see that everything looks the way it should by issuing your first real query:</i>

</p>

<pre class="brush: js">SELECT * FROM blog_entries;

</pre>

<p>and you should see:

</p><p><img src="http://www.wired.com/wired/webmonkey/stuff/Flash_MySQL_chart4.gif" alt="Flash_MySQL_chart4.gif">

</p><p>I went ahead and inserted a few more entries to give us more to play with when we get to the Flash end of our blog. See, that wasn&#8217;t too bad was it? Alright, maybe a little, but take a deep breath and move on to the PHP anyway.

</p>

<a name="Add_a_Dash_of_PHP"></a><h4> <span class="mw-headline">Add a Dash of PHP</span></h4>



<p>When a user arrives at our blog, we want the following two things to happen:First, we want the latest entry to be displayed. Second, we want to display a list of past entries, which will be links to our older postings. I&#8217;m going to make the archives show both entry and date so you can see how both methods would work. The information we need to retrieve is stored in our table named &#8220;blog_entries&#8221;, which is part of the database named &#8220;blog_db&#8221;. The Flash piece we&#8217;re going to build will need to query the database for that information, and to do so, we will utilize a PHP file.

</p><p>If you&#8217;re familiar with Flash ActionScript, PHP should look familiar to you. Like ActionScript, PHP is a scripting language and therefore has a similar syntax. The one big difference from ActionScript is that PHP variables must always begin with a $. Just like in Actionscript, we&#8217;re going to write some functions and use them to interact with our blog_db database. The reason I spent so much time on the MySQL section is that the commands we used there to see the entries in our database are the same as the ones we&#8217;ll use in our PHP scripts. For our purposes, PHP is going to act as a middleman, sending queries from Flash to MySQL and then returning results back from MySQL to Flash.

</p><p>So, diving right in. Fire up your favorite text editor, create a new document and save it with the extension .php. Now enter in the following code. (<i>Your browser will probably wrap this code, so try copying the <a href="http://www.wired.com/wired/webmonkey/stuff/Flash_MySQL_phpcode1.txt" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/Flash_MySQL_phpcode1.txt" rel="nofollow">raw source</a></i>)

</p><p><br />

</p>

<pre class="brush: js">&lt;?php

mysql_pconnect ("yourHost", "yourUserName", "yourPassword");



mysql_select_db ("blog_db");

$qResult = mysql_query ("SELECT * FROM blog_entries ORDER BY id DESC");



$nRows = mysql_num_rows($qResult);

$rString ="&amp;n=".$nRows;





for ($i=0; $i&lt; $nRows; $i++){

	$row = mysql_fetch_array($qResult);

	$rString .="&amp;id".$i."=".$row['id']."&amp;"."&amp;title".$i."=".$row['title']."&amp;"."&amp;date".$i."=".$row['date']."&amp;"."&amp;entry".$i."=".$row['entry']."&amp;";

}

echo $rString."&amp;";



?&gt;



</pre>

<p><br />

Now let&#8217;s go through it line by line. The first few lines are PHP&#8217;s way of connecting to our database, just like what we did earlier in our terminal program. How does this work you ask? PHP, like ActionScript, has a bevy of built-in functions, and one of them is mysql_pconnect(). So then it&#8217;s just a matter of plugging in the right parameters for our database. The mysql_select_db() function is just like the USE function we typed earlier in our terminal. It tells MySQL which database we want to query. Then we have these lines:

</p>

<pre class="brush: js">$qResult = mysql_query ("SELECT * FROM blog_entries ORDER BY entry_id DESC");



 $nNows = mysql_num_rows($qResult);



 $rString = "&amp;n=".$Nrows;

</pre>

<p><br />

Here we&#8217;ve created three variables (remember variables in PHP must begin with a $). The variable $qResult is our actual query to the database (qResult is short for Query Result &#8212; get it?). The parameter is a string which tells MySQL to select all the information in our blog_entries table and return them in an ordered list. The ORDER BY command will order our result by the id column, starting with the largest number and reading down in descending order. This means that the rows of data returned start with the newest entry and read down to the oldest. Now you can see why we used the auto increment feature when we set up our table.

</p><p>The variable $nRows uses the function mysql_num_rows() to store the number of rows in our database (nRows is short for number of rows). We need to know how many rows we have so that we can write a loop to cycle through and read each row. Then we will write some code to format each row into a URL encoded string, which we will then pass on to our Flash movie. $rString is the variable we will use to pass the data to Flash (rString being my shorthand for Returned String). Next comes the loop to read all the data in our table.

</p>

<pre class="brush: js">for ($i=0; $i&lt; $nRows; $i++){



 	$row = mysql_fetch_array($qResult);



 	$rString .="&amp;id".$i."=".$row['id']."&amp;"."&amp;title".$i."=".$row['title']."&amp;".



 	"&amp;date".$i."=".$row['date']."&amp;"."&amp;file".$i."=".$row['entry']."&amp;";



 }



 echo $rString."&amp;";



</pre>

<p>&#8220;Oh my god!&#8221; you scream, &#8220;What is that string of nonsense?&#8221; Good question.

</p><p>The first thing we&#8217;ve done is set up a for loop. This loop says:for a variable $i, which is initially equal to zero, and for as long as $i remains less than our variable $nRows, increment the variable $i by one each time you perform the following loop. We do this so that PHP will loop through each row of our MySQL table and give each row its own unique number. This way when we pass the information to Flash, we can separate each entry and send it to the appropriate place.

</p><p>Next, we&#8217;ve taken advantage of another built-in PHP function (don&#8217;t worry &#8212; it won&#8217;t sue). We&#8217;ve created the variable $row and assigned it the function mysql_fetch_array(). Our parameter is the variable $qResult which we defined earlier as our query. This function takes the long string of information that is our variable $qResult and breaks it into an array. The new array contains all our table columns and the rows of data. Using the $row array we can access each element by name. Let&#8217;s just pause for a moment and consider that there are brilliant programmers out there who made this possible with one simple line of code.

</p><p>Done pausing? Great, let&#8217;s move on.

</p>

<a name="Strings.2C_Sealing_Wax.2C_Fancy_Stuff"></a><h4> <span class="mw-headline">Strings, Sealing Wax, Fancy Stuff</span></h4>

<p>OK now let&#8217;s concentrate on that really long and confusing line, the meat of our for loop. It turns out that Flash has to receive external information in the form of a URL-encoded string (actually, if you install Flash Remoting on your server, it can receive information as straight record sets, but Flash Remoting is beyond the scope of this article &#8212; visit the <a href="http://www.macromedia.com/software/flashremoting/" class="external text" title="http://www.macromedia.com/software/flashremoting/" rel="nofollow">Macromedia</a> site if you&#8217;re interested in learning more). The string our Flash movie will be looking for is a bunch of incremented variables squeezed between ampersands. If we include linebreaks to make it more readable it looks like this:

</p>

<pre class="brush: js">&amp;id0=1&amp;



 &amp;title0=myfirstEntry&amp;



 &amp;date0=2003:10:10 03:30:02&amp;



 &amp;entry0=some text&amp;

</pre>

<p>The variable $rString in our PHP code contains all the necessary formatting syntax to ensure that Flash gets this string. The PHP code looks confusing because we&#8217;re concatenating (joining together) strings (everything in quotes) with elements in our $row array.

</p><p>Let&#8217;s break it down some more. In PHP we write (I&#8217;ve put extra spaces between each element to make it easier to follow):

</p>

<pre class="brush: js"> $rString.=  "&amp;id".  $i.  "=".  $row['id'].  "&amp;"  et cetera...



</pre>

<p><br />

$rString is our PHP variable which will get passed to Flash. We&#8217;ve assigned it to a big long concatenated string of smaller strings and elements of the array $row. In PHP the . (dot) operator is used to concatenate elements of a string. &#8220;&amp;id&#8221; starts our string off and gets joined with the variable $i. Now the variable $i is the incremented element in our loop, so it will be an integer. Because we set $i=0 in our loop, the first time through the loop it will be 0, the second time it will be 1, and so on. For this reason, each row in our MySQL table has a unique identifying number. We then join the $i variable with an equals sign. So far we have given Flash the following information:

</p>

<pre class="brush: js"> &amp;id1=

</pre>

<p>Now we assign this newly created &#8220;id&#8221; variable an element in our $row array ($row[id]). Essentially we&#8217;re writing id=id, pretty simple right? The first number in our MySQL column was 1, so the first time through our loop we return a 1. We then tack on another string so that this element of our big string (the one being passed to Flash) is enclosed in ampersands the way we want it to be. All Flash is going to see is:

</p>

<pre class="brush: js"> &amp;id1=1&amp;

</pre>

<p>The rest of our variable $rString does the same formatting for the rest of our columns so that we can pass Flash our completed string which will look like this:

</p>

<pre class="brush: js"> &amp;id0=1&amp;&amp;title0=myfirstEntry&amp;&amp;date0=2003:10:10 03:30:02&amp;&amp;entry0=some text&amp;



</pre>

<p>Now for the final and really easy bit of code:

</p>

<pre class="brush: js">echo $rString."&amp;";



 ?&gt;

</pre>

<p>Since Flash is going to read the results of our PHP code, we have to make sure that we use the echo command, to tell PHP (when it gets done processing all the things we&#8217;ve told it to do) to display the completed string shown above. Echo is the same as print. In fact, you can use the command print if you so desire. The <tt>?&gt;</tt> simply closes our PHP code just like <tt>&nbsp;/html¢</tt> would close an HTML document.

</p><p>To test and make sure everything is working, upload the .php file to the server and point your browser to its location. You should be greeted by a stark white page with unformatted black text that reads:

</p>

<pre class="brush: js"> &amp;id0=1&amp;&amp;title0=myfirstEntry&amp;&amp;date0=2003:10:10 03:30:02&amp;&amp;entry0=some text&amp;



</pre>

<p>Okay, you&#8217;re done. With PHP that is. Time for a break. Crack your knuckles, lean back, smoke &#8216;em if you got &#8216;em, and relax. That was some terribly complicated stuff you just waded through.

</p><p>A quick note about security:Did it make you nervous to type your password in plain text at the beginning of our PHP file? It should. Granted, PHP is a server-side technology and there is no easy way to view this file as we&#8217;re seeing it. But that doesn&#8217;t mean it can&#8217;t be done. A more secure method of sending this information is to use an include statement. What we do is take the mysql_pconnect statement and move it to a separate file. Name it connect.inc, and now move it to a location on your server where the general public can&#8217;t access it. Then change the mysql_connect statement above to read include (&#8220;connect.inc&#8221;). Also, don&#8217;t forget to tell PHP where the include file is. We need to edit the PHP initialization file to point to the directory in which you just placed the include file. Typically, the initialization file lives in the <tt>/usr/local/apache/php</tt> directory. If your server isn&#8217;t running Apache, refer to your documentation. Not only is this method more secure, it saves you from having to type the whole connect statement every time you write a new PHP document for this database.

</p><p>Now rest up and get ready for <a href="/2010/02/Build_a_Website_With_Flash_and_MySQL_-_Lesson_2" title="Tutorial:Build a Website With Flash and MySQL - Lesson 2"> lesson 2</a>!

</p><p>

</p>



<div id="series">



<div class="series_hdr">From the series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><strong class="selflink"> Build a Website With Flash and MySQL &#8211; Lesson 1</strong><br />

<a href="/2010/02/Build_a_Website_With_Flash_and_MySQL_-_Lesson_2" title="Tutorial:Build a Website With Flash and MySQL - Lesson 2"> Build a Website With Flash and MySQL &#8211; Lesson 2</a>

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_1/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>Build a Website With Flash and MySQL &#8211; Lesson 2</title>
        <link>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_2/</link>
        <comments>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_2/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=684</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[In Build a Website With Flash and MySQL &#8211; Lesson 1, we successfully created a MySQL database, filled it with blog entries, and learned how to query it. Now we&#8217;re going to move on to the fun stuff:creating a Flash container to display our blog entries as we pull them out of the database. I&#8217;m [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>In <a href="/2010/02/Build_a_Website_With_Flash_and_MySQL_-_Lesson_1" title="Tutorial:Build a Website With Flash and MySQL - Lesson 1"> Build a Website With Flash and MySQL &#8211; Lesson 1</a>, we successfully created a MySQL database, filled it with blog entries, and learned how to query it. Now we&#8217;re going to move on to the fun stuff:creating a Flash container to display our blog entries as we pull them out of the database. I&#8217;m going to help you build something along the lines of what you&#8217;ll encounter at my own Flash blog site, <a href="http://www.luxagraf.com/" class="external text" title="http://www.luxagraf.com/" rel="nofollow">Luxagraf</a>.

</p><p>Fire up Flash and create a new document. The first thing we need is a nice big text field to display our entries. You could create a text field in ActionScript if you like, using the createTextField() method. I don&#8217;t know about you, but my stomach for code is still full from yesterday, so I&#8217;ve just drawn a text field using the cursor tool and given it an instance name of entries_txt. In the Properties Inspector, set the text to be dynamic, multi-line, and HTML formatted. For safety&#8217;s sake, select the character option and click &#8220;embed all characters.&#8221; Flash has some issues with dynamic textfields that don&#8217;t have embedded characters, especially if you put your text <a href="http://www.macromedia.com/support/flash/ts/documents/maskprintembed.htm" class="external text" title="http://www.macromedia.com/support/flash/ts/documents/maskprintembed.htm" rel="nofollow">under a mask</a>.<span id="more-684"></span>

</p><p>I&#8217;ve also attached a scrollbar to the text field and given it an instance name of sb.

</p><p><img src="http://www.wired.com/wired/webmonkey/stuff/Flash_MySQL_shot1.jpg" alt="Flash_MySQL_shot1.jpg">

</p><p>My design is minimalist, but you can load up your movie with cool graphics, nifty background animation, menus, and more. And you can rest assured that while Flash is retrieving your data, your design will keep your user otherwise enthralled until the data loads. You might even include a loading progress bar if you want to give modem users some feedback so they know that something is happening. Creating a progress bar for external data is a little more complex than one for an external .swf, but it&#8217;s not too bad. Colin Moock, author of <i>ActionScript:The Definitive Guide</i>, has a sample <a href="http://www.moock.org/asdg/codedepot/" class="external text" title="http://www.moock.org/asdg/codedepot/" rel="nofollow">available</a>.



</p><p>To show our list of archived entries, we&#8217;ll need a second, smaller text field, which I&#8217;ve named archive_txt. I&#8217;ve attached another scrollbar to the archive text field and given it instance name sb2. Set the archive text field up the same way:dynamic, multiline and HTML. You don&#8217;t need to embed the font again since it can use the characters from the first text field.

</p><p>That&#8217;s it for the graphics. Now let&#8217;s get back to code!

</p>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#Linking_Flash_to_the_Database">Linking Flash to the Database</a></li>

<li><a href="#Loading_Up_on_Content">Loading Up on Content</a></li>



<li><a href="#Publishing_the_Finished_Product">Publishing the Finished Product</a></li>

<li><a href="#Allow_Me_to_Extrapolate">Allow Me to Extrapolate</a></li>



</ol>

</td></tr></tbody></table>



<a name="Linking_Flash_to_the_Database"></a><h4> <span class="mw-headline">Linking Flash to the Database</span></h4>

<p>Create a new layer on top of the last one and name it &#8220;actions&#8221; or something similar. Now open up the Actions panel (F9) and paste in the following code. It should display correctly below, but if your browser refuses to wrap text properly, use the <a href="http://www.wired.com/wired/webmonkey/stuff/flashcode3.txt" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/flashcode3.txt" rel="nofollow">plain text</a> or <a href="http://www.wired.com/wired/webmonkey/stuff/flashcode1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/flashcode1.html" rel="nofollow">HTML</a> version of the raw code.



</p>

<pre class="brush: js">//function to load external data using the loadVars() object

//l=name of loadVars object

//n=name of text field

//t=trigger to decide whether to show all entries or just one.

//e= entry number to display (number)

//f=file to load from (string)

function lv(l, n, t, e, f) {

	sb.setSize(null, 200);

	sb2.setSize(null, 50);

	//create a new loadVars object if one doesn't already exist

	//if it does, use it

	if (l == undefined) {

		l = new LoadVars();

		l.onLoad = function() {

			var i;

			//clear out any text that might already be there

			n.htmlText = "";

			//to show a single entry at a time we use the

			//following code

			if (t == undefined) {

				n.htmlText += "&lt;b&gt;"+this["title"+e]+"  -

				"+this["date"+e]+"&lt;/b&gt;&lt;br&gt;&lt;br&gt;";

				n.htmlText += this["entry"+e];

			} else {

				//cycle through and show all entries

				for (i=0; i&lt;this.n; i++) {

					n.htmlText += "&lt;u&gt;

					&lt;a href='asfunction:_root.loadArc,

					"+this["id"+i]+"'&gt;"+this["title"+i]+"  -

					"+this["date"+i]+"&lt;/a&gt;&lt;/u&gt;&lt;br&gt;";

				}

			}

			sb.update();

			sb2.update();

		};

	}

	l.load(f);

}



</pre>

<p>What we have here is a reasonably generic function that you can use to load external data in any Flash movie provided you know how it works and how to modify it. I&#8217;ll walk you through it line by line and hopefully you can see where you might have to change things to suit your needs.

</p><p>First off, let&#8217;s define our single letter variables in a little more detail. First we have &#8220;l&#8221;, which will become a new instance of the loadVars() object. The object needs to have an instance name so we&#8217;ll give it one when we call the function. Next we have &#8220;n&#8221; which will be the name of the text field. If you&#8217;re following along with my example, we&#8217;re going to use the instance name of the text fields we created earlier (entries_txt and archive_txt). By making this a variable that&#8217;s passed to the function, we can create as many textboxes as we want and we don&#8217;t have to rework our main loadVars function. &#8220;t&#8221; is for trigger (like the horse, but smaller). This variable may be unnecessary for your needs, but I&#8217;ve put it in there so that I can use the same function to load both the main text and archives. For the main textfield, I&#8217;ll pass a value of undefined because I only want to show the latest entry. For the archive textfield, we can pass any value other than undefined. In my own work I tend to pass the string &#8220;cycle&#8221; so I know what it is I&#8217;m doing without looking back at the actual function, but you could pass it the string &#8220;webmonkey rocks&#8221; and it would do the same thing.

</p><p>The next variable is &#8220;e,&#8221; which we won&#8217;t be using initially, but which will help us when we get to the archive section by allowing us to select entries by number. Last we have &#8220;f&#8221;, which is short for file, as in the .php file we&#8217;re calling. In the last section, use whatever name you used when you saved your .php file. I chose blog.php.

</p><p>It&#8217;s worth asking why I didn&#8217;t use more descriptive variable names in the function. Well, that&#8217;s partially due to laziness, but it&#8217;s also because using single letters seems to make things happen a bit faster.

</p>

<a name="Loading_Up_on_Content"></a><h4> <span class="mw-headline">Loading Up on Content</span></h4>

<p>Okay, now that we&#8217;ve spelled out our variables, we&#8217;ll move on to the function and its inner workings. To load our database information into Flash we&#8217;re going to be using the loadVars() object. As with most Flash objects, the first step is to create a new instance of the object. In this function we&#8217;ve started with an if statement.

</p><p><br />

</p>

<pre class="brush: js"> if (l == undefined) {



 		l = new LoadVars();

</pre>

<p><br />

The if statement checks to see whether we have a loadVars object by the name of &#8220;l&#8221; and, if not, it creates one. Now, since &#8220;l&#8221; will be defined in our function call, we can create loadVars objects left and right if we want to. On the other side of the coin, if we already have a loadVars object by the name we&#8217;ll call, we don&#8217;t have to waste time creating a new one. The next thing we need to do is define the onLoad method of our loadVars() object. Flash needs to know what to do with the information it&#8217;s about to get. So we define the function to process our data. Here&#8217;s the section of the code from page two that we&#8217;re dealing with:



</p>

<pre class="brush: js">l.onLoad = function() {

			var i;

			n.htmlText = "";

			//to show a single entry at a time we use the

			//following code

			if (t == undefined) {

					n.htmlText += "&lt;b&gt;"+this["title"+e]+"

					-  "+this["date"+e]+"&lt;/b&gt;&lt;br&gt;&lt;br&gt;";

					n.htmlText += this["entry"+e];

			} else {

				//cycle through and show all entries

				for (i=0; i" +this["title"+i]+"

					-  "+this["date"+i]+"&lt;/a&gt;&lt;/u&gt;&lt;br&gt;";

				}

			}

</pre>

<p>The first thing in our function is a variable i. I should point out here that, just as we used $i in our PHP code, we&#8217;ll call this variable i as well. Using i for incremented variables is just a programming convention. If there is a good reason for it, I&#8217;m not aware of it. You can ignore convention and use whatever you like, just don&#8217;t use any of the letters we&#8217;ve already assigned. The key thing to note is the use of var to define the variable. In Flash, var creates a local variable; that is, the variable i is only defined in this function. Outside this function you can use i again and it won&#8217;t mess things up. Local variables, as this practice is called, use up less memory since they get used and wiped away immediately afterward. Next we empty out our textfield:

</p>

<pre class="brush: js">n.htmlText = "";

</pre>



<p>Now we&#8217;re going to set up two possible ways of handling our data using our &#8220;t&#8221; variable as a selector. The code reads &#8220;if the variable t is undefined then do the first chunk of code, else do the second chunk of code.&#8221; The first chunk of code is just formatting for the information that was passed from MySQL. Our variable n, which will be the name of our text field, gets its htmlText property defined.

</p>

<pre class="brush: js"> n.htmlText += "&lt;b&gt;"+this["title"+e]+"  -  "+this["date"+e]+"&lt;/b&gt;&lt;br&gt;&lt;br&gt;";



 n.htmlText += this["entry"+e];

</pre>

<p>Here we&#8217;re concatenating a string again like we did in PHP, except in Flash we concatenate strings with the + operator. The first element is an HTML bold tag to highlight the title. The title itself comes from the array we defined in PHP this["title"+e]. &#8220;This&#8221; refers to the function we&#8217;re in, which is the onLoad handler, meaning anything with the &#8220;this&#8221; designation uses the PHP passed data. So, this.["title"+e] refers to the title column in our MySQL table plus our variable e. We could have just said this.["title"+0], but then we wouldn&#8217;t be able to use this function in our archives section. Next we have a dash to separate the title and date. Then, we join the rest of the string which is the same code, but this time we use the &#8220;date&#8221; element of our PHP array. Lastly, we close the bold tag and add some <br /> tags to put a little space between the title and the entry itself. The entry itself is written on a separate line so it will be displayed below the date and title. Once again we use an element of the PHP array, this time the &#8220;entry&#8221; element, which contains the main text.

</p><p>But what about our other case? Can we display a list of past entries listed by title and date without text? Of course, but first let&#8217;s look at how our function will get to this point. If we define the variable t, the if statement we just wrote evaluates to false so Flash jumps to the else clause. The else clause then tells Flash to execute a loop so all of our entries will be displayed at once. Remember for loops? Well this one should look familiar from the PHP section. It&#8217;s essentially the same loop with one subtle difference:the second condition, iThe way we&#8217;re handling the data in the archives textbox is a little different, too. We&#8217;ve set our text to underline using the HTML tag &lt;u&gt; and wrapped everything in an HTML link (note that this should all be on one line with no hard returns).



</p>

<pre class="brush: js"> n.htmlText += "&lt;u&gt;&lt;a href='asfunction:_root.loadArc,"+this["id"+i]+"'&gt;"



 +this["title"+i]+"  -  "+this["date"+i]+"&lt;/a&gt;&lt;/u&gt;&lt;br&gt;";

</pre>

<p>Our href tag might look a little strange to veteran HTML coders. Flash has a little-known feature that allows you to call a function from within an HTML tag. The syntax is asfunction:location/nameOfFunction,variable. The limiting thing is that you can pass only one variable using this method. The quickest way around that problem is to pass a variable as long string and then break it apart in your function, but that won&#8217;t be an issue for us since we have only one variable to pass.

</p><p>The last line our onLoad function uses the variable &#8220;s&#8221; to update our scrollbar. The lines after our onLoad function call the .load method of the loadVars object and pass the name of our .php file. This tells our loadVars object to go ahead and read the .php file. It might seem backwards to define the onLoad handler before calling the load function, but <i>you must define the onload handler first</i>.

</p>

<a name="Publishing_the_Finished_Product"></a><h4> <span class="mw-headline">Publishing the Finished Product</span></h4>



<p>Alright! We&#8217;re so close, I can taste it. Now that we&#8217;ve written our main function, let&#8217;s handle that asfunction we&#8217;re calling to, but haven&#8217;t yet defined.

</p><p>Copy this code into your Flash movie:

</p>

<pre class="brush: js"> function loadArc(passed) {



 	arcNum = passed-1;



 	lv(blog_lv, entries_txt, undefined, arcNum, "blog.php");



 }

</pre>

<p>All this function does is take the entry number passed from our lv function, subtract 1, and then call the lv function again with the new number. Why subtract one? Remember that our PHP loop starts counting at zero, but our MySQL auto increment starts at one. This means we&#8217;re always one number behind. Simple solution to the problem:subtract one.

</p><p>More copy and paste:

</p>

<pre class="brush: js"> //for the large entry textfield



 lv(blog_lv, entries_txt, undefined, 0, "blog.php");



 //for the archives text field



 lv(archive_lv, archive_txt, "cycle", null, "blog.php");

</pre>

<p>These lines call the function lv with all of our variables defined. When this code gets executed Flash will jump up and read our lv() function and then look for our PHP file which will query our database, extract and format our information and send it back to Flash where it will be displayed. I know it sounds like an incredibly long and complex process, but it will actually happen in fractions of a second and your user won&#8217;t have to sit idly waiting for the entire page to redraw itself.

</p><p>OK, publish the movie and upload it to your site. You&#8217;re done! Now, when a user comes to the site and loads the Flash piece, they&#8217;ll see the latest entry in the big text box and a list of past entries in the smaller one. Try clicking on the links in the archive list. You should see the Flash movie bring up past entries in the larger text box.

</p><p>You can see a working version of this very system over at my own blog site, <a href="http://www.luxagraf.com" class="external text" title="http://www.luxagraf.com" rel="nofollow">Luxagraf</a>. While you&#8217;re poking around, click on the &#8220;Browse Archives&#8221; tab at the bottom of the Flash window and you&#8217;ll see my second textbox full of archived entries show up.



</p><p>We did it! Primitive though it may be, we&#8217;ve created a Flash-based blog and learned a few things about Flash and database integration. Now let&#8217;s take a look at some places we can expand our code and make it more useful to a wider range of applications.

</p>

<a name="Allow_Me_to_Extrapolate"></a><h4> <span class="mw-headline">Allow Me to Extrapolate</span></h4>

<p>My main goal with this tutorial was to give you, the designer/programmer (which you can now truthfully call yourself!) a starting point from which to extrapolate and expand. You&#8217;ve made it this far, and for that you should be proud, but you probably have some questions. With this in mind, I wanted to address a few things.

</p><p>First off, we only scratched the surface of MySQL and PHP. To start thinking in more general terms, I suggest visiting the developer&#8217;s sites for the two technologies. Perhaps you should also join some mailing lists and see what others are doing with MySQl and PHP. Since there is no way to sit back and anticipate what a particular project may require, it&#8217;s a good idea to look around and see how other people are using these tools.

</p><p>Some examples that spring to mind for PHP/MySQL projects are a discussion board, or perhaps a backend application that lets your client update content without having to access MySQL directly. Once you have a better idea of what you can do with a database and have polished up your PHP knowledge, you will start to see some holes in our example. For instance, what if your want your PHP query to be dynamic? Suppose you want to return a query based on user input (i.e. some sort of search criteria defined by the user)? It&#8217;s not hard to do that at all. From the Flash end, you simply need to use the sendAndLoad() method of the LoadVars() class rather than the simple load() method (look it up in the <a href="http://www.macromedia.com/support/flash/action_scripts/actionscript_dictionary/" class="external text" title="http://www.macromedia.com/support/flash/action_scripts/actionscript_dictionary/" rel="nofollow">ActionScript Dictionary</a>) and then write your PHP query string with a POST variable. PHP and Flash are both very flexible tools, and you&#8217;ll find that the functionality you can achieve by using them is close to unlimited.

</p><p>The final concern I wanted to address is Macromedia&#8217;s release of Flash MX 2004. Aside from the fact that software manufacturers seem intent on coming up with ever more confusing product names and pricing schemes, the more pertinent question is &#8220;Does our example still work?&#8221;

</p><p>The short answer is yes. Judging from my own experience with Flash MX 2004 Professional and the Flash Player 7, the behaviors associated with loadVars() remain the same. There is, however, a new set of data components in Flash MX 2004. I have not explored these new tools in great depth, but it&#8217;s very possible they may simplify the code necessary to access external data sources. In my readings, the new components seem to be geared toward moving data between component sets. However, there is a fair price to be paid. Just dragging the new dataGrid component onto the Flash stage is going to bump your file size up by 58Kb. In comparison, the code we&#8217;ve written is only as large as the scrollbars you use. It&#8217;s also worth noting that none of these components can query MySQL directly &#8211; several rather expensive server technologies are supported, but not the free, open source solution.

</p><p>This raises yet another issue:By no means is Flash limited to PHP and MySQL interaction. Everything we&#8217;ve done can be done with ASP or other proprietary software so long as you know how to get the returned data into a URL encoded string. Then there is XML data which is also not hard to feed into Flash&#8230;

</p><p>Hopefully this tutorial can serve as a kind of gateway, providing an entrance into the world of dynamic content for Flash movies. How much of it you use is always going to depend on your own projects and needs. If nothing else, you have left the five percent nation of non-weblog creators and joined the thronging masses. Now take this project and see if you can adapt it to your own creative needs.

</p><p>



</p>



<div id="series">

<div class="series_hdr">From the series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Build_a_Website_With_Flash_and_MySQL_-_Lesson_1" title="Tutorial:Build a Website With Flash and MySQL - Lesson 1"> Build a Website With Flash and MySQL &#8211; Lesson 1</a><br />

<strong class="selflink"> Build a Website With Flash and MySQL &#8211; Lesson 2</strong>

</p>



</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_2/feed/</wfw:commentRss>
        <slash:comments>1</slash:comments>

        
    </item>
    
    <item>
        <title>PHP and MySQL Tutorial &#8211; Lesson 2</title>
        <link>http://www.webmonkey.com/2010/02/php_and_mysql_tutorial_-_lesson_2/</link>
        <comments>http://www.webmonkey.com/2010/02/php_and_mysql_tutorial_-_lesson_2/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=735</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[In this lesson, we&#8217;re going to dive right in and create some simple yet useful pages using PHP and MySQL. Let&#8217;s start by displaying the database we created yesterday in Lesson 1, but with a little more panache. First, let&#8217;s query our database using the following code. &#60;html&#62; &#60;body&#62; &#60;?php $db = mysql_connect("localhost", "root"); mysql_select_db("mydb",$db); [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>In this lesson, we&#8217;re going to dive right in and create some simple yet useful pages using PHP and MySQL. Let&#8217;s start by displaying the database we created yesterday in <a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_1" title="Tutorial:PHP and MySQL Tutorial - Lesson 1">Lesson 1</a>, but with a little more panache.
</p><p>
<span id="more-735"></span>
</p><p>First, let&#8217;s query our database using the following code.

</p>

<pre class="brush: js">

 &lt;html&gt;



 &lt;body&gt;



 &lt;?php



 $db = mysql_connect("localhost", "root");



 mysql_select_db("mydb",$db);



 $result = mysql_query("SELECT * FROM employees",$db);



 echo "&lt;table border=1&gt;n";



 echo "&lt;tr&gt;&lt;td&gt;Name&lt;/td&gt;&lt;td&gt;Position&lt;/tr&gt;n";



 while ($myrow = mysql_fetch_row($result)) {



 		printf("&lt;tr&gt;&lt;td&gt;%s&nbsp;%s&lt;/td&gt;&lt;td&gt;%s&lt;/td&gt;&lt;/tr&gt;n",

 		$myrow[1], $myrow[2], $myrow[3]);



 }



 echo "&lt;/table&gt;n";



 ?&gt;



 &lt;/body&gt;





 &lt;/html&gt;

</pre>

<p>You probably noticed that we introduced a couple of new features here. Most obvious is the <tt>while()</tt> loop. The loop says that as long as there are new rows of data to be grabbed (using the <tt>mysql_fetch_row()</tt> function), assign that row to the <tt>$myrow</tt> variable. Then execute the instructions between the curly brackets ({}). Take a look for a second, and this should make sense.

</p><p>The <tt>mysql_fetch_row()</tt> function bears a closer look. One small problem with <tt>mysql_fetch_row()</tt> is that it returns an <a href="/2010/02/Array" title="Reference:Array"> Array</a> that supports only numeric references to the individual fields. So the first field is referred to as 0, the second as 1, and so on. With complex queries this can become something of a nightmare.



</p><p>Now let&#8217;s examine the loop in more detail. The first few lines you&#8217;ll recognize from the example in *<a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_1" title="Tutorial:PHP and MySQL Tutorial - Lesson 1"> lesson 1</a>

. Then in the <tt>while()</tt> loop we fetch a row from the result and assign it to the array <tt>$myrow</tt>. Then we print the contents of the array on the screen with the <tt>printf</tt> function. After that it loops around again, and another row is assigned to <tt>$myrow</tt>. It will do this until it runs out of rows to grab.

</p><p>The great thing about a <tt>while()</tt> loop is that if your query returns no records, you won&#8217;t get an error message. The first time through there won&#8217;t be any data to assign to <tt>$myrow</tt>, and the program will just move on.



</p><p>But if the query returns no data, we have no way of letting the user know, and we should probably provide some sort of message. This is possible, so let&#8217;s do it.

</p>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#Stay_Informed">Stay Informed</a></li>

<li><a href="#Link_Intelligently">Link Intelligently</a></li>



<li><a href="#Throw_in_Some_Forms">Throw in Some Forms</a></li>

<li><a href="#Make_the_Forms_Smarter">Make the Forms Smarter</a></li>

<li><a href="#All_Together_Now">All Together Now</a></li>

</ol>

</td></tr></tbody></table>



<a name="Stay_Informed"></a><h4> <span class="mw-headline">Stay Informed</span></h4>



<p>Take a look at this script.

</p>

<pre class="brush: js"> &lt;html&gt;



 &lt;body&gt;



 &lt;?php



 $db = mysql_connect("localhost", "root");



 mysql_select_db("mydb",$db);



 $result = mysql_query("SELECT * FROM employees",$db);



 if ($myrow = mysql_fetch_array($result)) {



   echo "&lt;table border=1&gt;n";



   echo "&lt;tr&gt;&lt;td&gt;Name&lt;/td&gt;&lt;td&gt;Position&lt;/td&gt;&lt;/tr&gt;n";



   do {



     printf("&lt;tr&gt;&lt;td&gt;%s&nbsp;%s&lt;/td&gt;&lt;td&gt;%s&lt;/tr&gt;n", $myrow["first"], $myrow["last"], $myrow["address"]);



   } while ($myrow = mysql_fetch_array($result));



 	echo "&lt;/table&gt;n";



 } else {



 	echo "Sorry, no records were found!";



 }



 ?&gt;



 &lt;/body&gt;



 &lt;/html&gt;

</pre>

<p>There are a number of new features introduced here, but they&#8217;re quite simple. First, there&#8217;s the <tt>mysql_fetch_array()</tt> function. This is exactly the same as <tt>mysql_fetch_row()</tt> with one nice exception:Using this function, we can refer to fields by their names (such as <tt>$myrow["first"]</tt>) rather than their numbers. This should save us some headaches. We&#8217;ve also introduced a do/while loop and an if-else statement.



</p><p>The if-else statement says that if we can assign a row to <tt>$myrow</tt>, then continue; otherwise skip to the <tt>else</tt> section and do what&#8217;s in there.

</p><p>The do/while loop is a variation of the <tt>while()</tt> loop we used on the last page. We need the do/while loop here for a very good reason:With the initial if statement, we assigned the first row returned by the query to the variable <tt>$myrow</tt>. If at this point we executed a regular while statement (such as <tt>while ($myrow = mysql_fetch_row($result)</tt>), we&#8217;d be kicking the first record out of the variable and replacing it with the second record. But the do/while loop lets us test the condition after the code has been run once. So there&#8217;s no chance of us accidentally skipping a row.

</p><p>Finally, if there are no records returned at all, the statements contained in the <tt>else{}</tt> portion will be executed. To see this portion in action, change the SQL statement to <tt>SELECT * FROM employees WHERE id=6</tt> or something else that will return no records.



</p><p>Now let&#8217;s extend this looping and if-else code to make one fancy-schmancy page. You&#8217;re going to love it.

</p>

<a name="Link_Intelligently"></a><h4> <span class="mw-headline">Link Intelligently</span></h4>

<p>We&#8217;re going to take that looping power we just learned and use it in a more practical example. But before we proceed here, you should know how to work with forms, the querystring, and the GET and POST methods.

</p><p>Right now I&#8217;m going to work with the querystring. As you should know, there are three ways to get information into the querystring. The first is to use the GET method in a form. The second is to type the information into the URL on your browser. And third, you can embed a querystring in a standard link. Just make the anchor tag look something like this:&lt;a href=&#8221;<a href="http://my_machine/mypage.php3?id=1" class="external free" title="http://my_machine/mypage.php3?id=1" rel="nofollow">http://my_machine/mypage.php3?id=1</a>&#8220;&gt;. We&#8217;re going to use this technique right now.First off, lets query our database again and list the employee names. Look at the following script. Much of this should look pretty familiar by now.

</p>

 <pre class="brush: js">&lt;html&gt;



&lt;body&gt;



&lt;?php







$db = mysql_connect("localhost", "root");



mysql_select_db("mydb",$db);



$result = mysql_query("SELECT * FROM employees",$db);



if ($myrow = mysql_fetch_array($result)) {



  do {



    printf("&lt;a href="%s?id=%s"&gt;%s&nbsp;%s&lt;/a&gt;&lt;br&gt;n", $PHP_SELF, $myrow["id"], $myrow["first"], $myrow["last"]);



  } while ($myrow = mysql_fetch_array($result));



} else {



  echo "Sorry, no records were found!";



}



?&gt;







&lt;/body&gt;







&lt;/html&gt;

</pre>

<p>Everything&#8217;s about the same except the <tt>printf</tt> function, so let&#8217;s look at it in some detail.First notice that each quotation mark is preceeded by a backslash. The backslash tells PHP to display the character following it, rather than treat it as part of the code. Also note the use of the variable $PHP_SELF. This variable, which stores the script&#8217;s name and location, is passed along with every PHP page. It&#8217;s helpful here because we just want this file to call itself. Using $PHP_SELF, we can be sure that will happen, even if the file is moved to another directory &#8211; or even another machine.

</p><p>As I just mentioned, these links will recall the page. On the second time through, however, some information will be added to the querystring.PHP does a nifty thing when it sees a name=value pair in the querystring. It automatically creates a variable with the name and value the querystring indicated. This feature allows us to test if it&#8217;s the first or second time through this page. All we have to do is ask PHP if the variable <tt>$id</tt> exists.Once I know the answer to that question, I can display a different set of information the second time through. Here&#8217;s how:

</p>

<pre class="brush: js">&lt;html&gt;



&lt;body&gt;



&lt;?php







$db = mysql_connect("localhost", "root");



mysql_select_db("mydb",$db);



// display individual record



if ($id) {



   $result = mysql_query("SELECT * FROM employees WHERE id=$id",$db);



   $myrow = mysql_fetch_array($result);



   printf("First name:%sn&lt;br&gt;", $myrow["first"]);



   printf("Last name:%sn&lt;br&gt;", $myrow["last"]);



   printf("Address:%sn&lt;br&gt;", $myrow["address"]);



   printf("Position:%sn&lt;br&gt;", $myrow["position"]);



} else {



    // show employee list



   $result = mysql_query("SELECT * FROM employees",$db);



    if ($myrow = mysql_fetch_array($result)) {



      // display list if there are records to display



      do {



        printf("&lt;a href="%s?id=%s"&gt;%s&nbsp;%s&lt;/a&gt;&lt;br&gt;n", $PHP_SELF, $myrow["id"], $myrow["first"], $myrow["last"]);



      } while ($myrow = mysql_fetch_array($result));



    } else {



      // no records to display



      echo "Sorry, no records were found!";



    }



}







?&gt;





&lt;/body&gt;



&lt;/html&gt;

</pre>

<p>This code is getting complex now, so I&#8217;ve started to use comments to keep track of what&#8217;s going on. You can use // to make a single-line comment or /* and */ to start and end a large comment block.

</p><p>And there we have it:your first truly useful PHP/MySQL script! Now let&#8217;s take a look at how to plug forms into it and send information back into the database.

</p>

<a name="Throw_in_Some_Forms"></a><h4> <span class="mw-headline">Throw in Some Forms</span></h4>

<p>We&#8217;ve managed to get data from a database without much difficulty. But what about sending data the other way? It&#8217;s not a problem with PHP.First let&#8217;s create a page with a simple form.

</p>

<pre class="brush: js">&lt;html&gt;



&lt;body&gt;







&lt;form method="post" action="&lt;?php echo $PHP_SELF?&gt;"&gt;



First name:&lt;input type="Text" name="first"&gt;&lt;br&gt;



Last name:&lt;input type="Text" name="last"&gt;&lt;br&gt;



Address:&lt;input type="Text" name="address"&gt;&lt;br&gt;



Position:&lt;input type="Text" name="position"&gt;&lt;br&gt;



&lt;input type="Submit" name="submit" value="Enter information"&gt;



&lt;/form&gt;





&lt;/body&gt;



&lt;/html&gt;

</pre>

<p>Note the use of $PHP_SELF again. Like I said in Lesson 1, you can use PHP anywhere inside your HTML code. You&#8217;ll also notice that each form element matches the field name in the database. This is not compulsory; it&#8217;s just a good idea so you can get your head around your code later on.

</p><p>Also notice that I&#8217;ve given the Submit button a <tt>name</tt> attribute. I&#8217;ve done this so I can test for the existence of a <tt>$submit</tt> variable. That way, when the page is called again, I&#8217;ll know whether someone used this form.I should mention that you don&#8217;t have to have a page that loops back on itself. You can span two, three, or more pages, if you like. This way everything stays compact.

</p><p>OK, let&#8217;s add some code that will check for the form input. Just to prove that the form input does make it through, I&#8217;ll dump all the variables to the screen with <tt>$HTTP_POST_VARS</tt>. This is a useful debugging feature. If you ever need to see all the variables on a page, use <tt>$GLOBALS</tt>.



</p>

<pre class="brush: js">&lt;html&gt;



&lt;body&gt;



&lt;?php







if ($submit) {



  // process form



  while (list($name, $value) = each($HTTP_POST_VARS)) {



    echo "$name = $value&lt;br&gt;n";



  }



} else{



  // display form



 &nbsp;?&gt;



  &lt;form method="post" action="&lt;?php echo $PHP_SELF?&gt;"&gt;



  First name:&lt;input type="Text" name="first"&gt;&lt;br&gt;



  Last name:&lt;input type="Text" name="last"&gt;&lt;br&gt;



  Address:&lt;input type="Text" name="address"&gt;&lt;br&gt;



  Position:&lt;input type="Text" name="position"&gt;&lt;br&gt;



  &lt;input type="Submit" name="submit" value="Enter information"&gt;



  &lt;/form&gt;



  &lt;?php







} // end if







?&gt;







&lt;/body&gt;







&lt;/html&gt;

</pre>

<p>Now that this is looking good, let&#8217;s take the form information and post it to the database.

</p>

<pre class="brush: js">&lt;html&gt;



&lt;body&gt;







&lt;?php







if ($submit) {



  // process form



  $db = mysql_connect("localhost", "root");



  mysql_select_db("mydb",$db);



  $sql = "INSERT INTO employees (first,last,address,position) VALUES ('$first','$last','$address','$position')";



  $result = mysql_query($sql);



  echo "Thank you! Information entered.n";



} else{







  // display form







 &nbsp;?&gt;







  &lt;form method="post" action="&lt;?php echo $PHP_SELF?&gt;"&gt;



  First name:&lt;input type="Text" name="first"&gt;&lt;br&gt;



  Last name:&lt;input type="Text" name="last"&gt;&lt;br&gt;



  Address:&lt;input type="Text" name="address"&gt;&lt;br&gt;



  Position:&lt;input type="Text" name="position"&gt;&lt;br&gt;



  &lt;input type="Submit" name="submit" value="Enter information"&gt;



  &lt;/form&gt;







  &lt;?php







} // end if







?&gt;







&lt;/body&gt;







&lt;/html&gt;

</pre>

<p>You&#8217;ve now inserted data into the database. It&#8217;s still far from perfect. What if someone leaves a field blank or enters text when we want a numeric entry? What if there&#8217;s an error somewhere?Don&#8217;t worry. We&#8217;ll get to that.

</p>

<a name="Make_the_Forms_Smarter"></a><h4> <span class="mw-headline">Make the Forms Smarter</span></h4>

<p>Throughout this tutorial, I&#8217;ve been loading the SQL statement into a variable ( <tt>$sql</tt>) before firing the query at the database with <tt>mysql_query()</tt>. This is useful for debugging. If something goes wrong, you can always echo the SQL to the screen to examine it for mistakes.



</p><p>We already know how to get data into the database. Now let&#8217;s try modifying records that are already in the database. Editing data combines two elements we&#8217;ve already seen:displaying data on the screen and sending data back to the database via form input. However, editing is slightly different in that we have to show the appropriate data in the form.First, let&#8217;s recycle the code from Lesson 1 to display the employee names on our page. But this time through, we&#8217;re going to populate our form with employee information. It should look a little like this:

</p><p><br />

</p>

<pre class="brush: js">&lt;html&gt;



&lt;body&gt;



&lt;?php







$db = mysql_connect("localhost", "root");



mysql_select_db("mydb",$db);



if ($id) {



  // query the DB



  $sql = "SELECT * FROM employees WHERE id=$id";



  $result = mysql_query($sql);



  $myrow = mysql_fetch_array($result);



 &nbsp;?&gt;







  &lt;form method="post" action="&lt;?php echo $PHP_SELF?&gt;"&gt;



  &lt;input type=hidden name="id" value="&lt;?php echo $myrow["id"]&nbsp;?&gt;"&gt;



  First name:&lt;input type="Text" name="first" value="&lt;?php echo $myrow["first"]&nbsp;?&gt;"&gt;&lt;br&gt;



  Last name:&lt;input type="Text" name="last" value="&lt;?php echo $myrow["last"]&nbsp;?&gt;"&gt;&lt;br&gt;



  Address:&lt;input type="Text" name="address" value="&lt;?php echo $myrow["address"]&nbsp;?&gt;"&gt;&lt;br&gt;



  Position:&lt;input type="Text" name="position" value="&lt;?php echo $myrow["position"]&nbsp;?&gt;"&gt;&lt;br&gt;



  &lt;input type="Submit" name="submit" value="Enter information"&gt;



  &lt;/form&gt;







  &lt;?php







} else {



  // display list of employees



  $result = mysql_query("SELECT * FROM employees",$db);



  while ($myrow = mysql_fetch_array($result)) {



    printf("&lt;a href="%s?id=%s"&gt;%s&nbsp;%s&lt;/a&gt;&lt;br&gt;n", $PHP_SELF, $myrow["id"], $myrow["first"], $myrow["last"]);



  }



}







?&gt;







&lt;/body&gt;



&lt;/html&gt;

</pre>

<p><br />

We just echoed the field information into the <tt>value</tt> attribute of the each element, which was fairly easy. Let&#8217;s build on this a little more. We will add the ability to send the edited code back to the database. Again, we&#8217;re going to use the Submit button to test whether we need to process the form input. Also note the slightly different SQL statement we use.

</p>

<pre class="brush: js">&lt;html&gt;



&lt;body&gt;



&lt;?php







$db = mysql_connect("localhost", "root");



mysql_select_db("mydb",$db);



if ($id) {



  if ($submit) {



    $sql = "UPDATE employees SET first='$first',last='$last',address='$address',position='$position' WHERE id=$id";



    $result = mysql_query($sql);



    echo "Thank you! Information updated.n";



  } else {



    // query the DB



    $sql = "SELECT * FROM employees WHERE id=$id";



    $result = mysql_query($sql);



    $myrow = mysql_fetch_array($result);



   &nbsp;?&gt;







    &lt;form method="post" action="&lt;?php echo $PHP_SELF?&gt;"&gt;



    &lt;input type=hidden name="id" value="&lt;?php echo $myrow["id"]&nbsp;?&gt;"&gt;



    First name:&lt;input type="Text" name="first" value="&lt;?php echo $myrow["first"]&nbsp;?&gt;"&gt;&lt;br&gt;



    Last name:&lt;input type="Text" name="last" value="&lt;?php echo $myrow["last"]&nbsp;?&gt;"&gt;&lt;br&gt;



    Address:&lt;input type="Text" name="address" value="&lt;?php echo $myrow["address"]&nbsp;?&gt;"&gt;&lt;br&gt;



    Position:&lt;input type="Text" name="position" value="&lt;?php echo $myrow["position"]&nbsp;?&gt;"&gt;&lt;br&gt;



    &lt;input type="Submit" name="submit" value="Enter information"&gt;



    &lt;/form&gt;



	&lt;?php



	}



} else {







  // display list of employees



  $result = mysql_query("SELECT * FROM employees",$db);



  while ($myrow = mysql_fetch_array($result)) {



    printf("&lt;a href="%s?id=%s"&gt;%s&nbsp;%s&lt;/a&gt;&lt;br&gt;n", $PHP_SELF, $myrow["id"], $myrow["first"], $myrow["last"]);



  }



}







?&gt;







&lt;/body&gt;





&lt;/html&gt;

</pre>

<p><br />

And that&#8217;s that. We&#8217;ve managed to combine most of the features we&#8217;ve seen into one script. You can also see how we&#8217;ve used an <tt>if()</tt> statement inside another <tt>if()</tt> statement to check for multiple conditions.It&#8217;s time to put it all together and make one killer script.

</p>

<a name="All_Together_Now"></a><h4> <span class="mw-headline">All Together Now</span></h4>

<pre class="brush: js">We'll finish up this lesson by putting everything into a single page that can add, edit, and remove entries from the database. It's an extension of what we've covered so far and makes for a good review. Let's take a look.



</pre>

 <pre class="brush: js"> &lt;html&gt;



 &lt;body&gt;







 &lt;?php







 $db = mysql_connect("localhost", "root");



 mysql_select_db("mydb",$db);







 if ($submit) {



   // here if no ID then adding else we're editing



   if ($id) {



     $sql = "UPDATE employees SET first='$first',last='$last',address='$address',position='$position' WHERE id=$id";



   } else {



     $sql = "INSERT INTO employees (first,last,address,position) VALUES ('$first','$last','$address','$position')";



   }



   // run SQL against the DB



   $result = mysql_query($sql);



   echo "Record updated/edited!&lt;p&gt;";



 } elseif ($delete) {



 	// delete a record



     $sql = "DELETE FROM employees WHERE id=$id";



     $result = mysql_query($sql);



     echo "$sql Record deleted!&lt;p&gt;";



 } else {



   // this part happens if we don't press submit



   if (!$id) {



     // print the list if there is not editing



     $result = mysql_query("SELECT * FROM employees",$db);



     while ($myrow = mysql_fetch_array($result)) {



       printf("&lt;a href="%s?id=%s"&gt;%s&nbsp;%s&lt;/a&gt; n", $PHP_SELF, $myrow["id"], $myrow["first"], $myrow["last"]);



 	  printf("&lt;a href="%s?id=%s&amp;delete=yes"&gt;(DELETE)&lt;/a&gt;&lt;br&gt;", $PHP_SELF, $myrow["id"]);



     }



   }







  &nbsp;?&gt;





   &lt;P&gt;



   &lt;a href="&lt;?php echo $PHP_SELF?&gt;"&gt;ADD A RECORD&lt;/a&gt;



   &lt;P&gt;



   &lt;form method="post" action="&lt;?php echo $PHP_SELF?&gt;"&gt;





   &lt;?php







   if ($id) {



     // editing so select a record



     $sql = "SELECT * FROM employees WHERE id=$id";



     $result = mysql_query($sql);



     $myrow = mysql_fetch_array($result);



     $id = $myrow["id"];



     $first = $myrow["first"];



     $last = $myrow["last"];



     $address = $myrow["address"];



     $position = $myrow["position"];



     // print the id for editing







    &nbsp;?&gt;



     &lt;input type=hidden name="id" value="&lt;?php echo $id&nbsp;?&gt;"&gt;



     &lt;?php



   }







  &nbsp;?&gt;



   First name:&lt;input type="Text" name="first" value="&lt;?php echo $first&nbsp;?&gt;"&gt;&lt;br&gt;





   Last name:&lt;input type="Text" name="last" value="&lt;?php echo $last&nbsp;?&gt;"&gt;&lt;br&gt;



   Address:&lt;input type="Text" name="address" value="&lt;?php echo $address&nbsp;?&gt;"&gt;&lt;br&gt;



   Position:&lt;input type="Text" name="position" value="&lt;?php echo $position&nbsp;?&gt;"&gt;&lt;br&gt;





   &lt;input type="Submit" name="submit" value="Enter information"&gt;



   &lt;/form&gt;







 &lt;?php







 }







 ?&gt;







 &lt;/body&gt;



 &lt;/html&gt;

</pre>

<p>This looks complex, but it really isn&#8217;t. The script is broken up into three parts. The first <tt>if()</tt> statement checks to see whether the Submit button has been pressed, and if it has, it checks to see whether the variable <tt>$id</tt> exists. If doesn&#8217;t, then we&#8217;re adding a record. Otherwise, we&#8217;re editing a record.Next we check to see whether the variable <tt>$delete</tt> exists. If it does, we delete a record. Note that with the first <tt>if()</tt> statement we checked for a variable that came through as a POST, and in this one, the variable would be part of a GET.



</p><p>Finally, we take the default action that displays the list of employees and the form. Again we check for the existence of the <tt>$id</tt> variable. If it exists, we query the database to display the relevant record. Otherwise, we display a blank form.We&#8217;ve now put all we&#8217;ve learned into one script. We used <tt>while()</tt> loops and <tt>if()</tt> statements, and we ran the gamut of the basic SQL statements &#8211; SELECT, INSERT, UPDATE, and DELETE. Lastly, we&#8217;ve looked at how we can pass information from one page to another using URLs and form input.

</p><p>In <a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_3" title="Tutorial:PHP and MySQL Tutorial - Lesson 3"> lesson 3</a> we&#8217;ll look at how to make the page more intelligent.

</p>

<ul><li><a href="/2010/02/PHP_and_MySQL_Tutorial" title="Tutorial:PHP and MySQL Tutorial"> PHP and MySQL Tutorial</a>



</li><li><a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_1" title="Tutorial:PHP and MySQL Tutorial - Lesson 1"> PHP and MySQL Tutorial &#8211; Lesson 1</a>

</li><li><strong class="selflink"> PHP and MySQL Tutorial &#8211; Lesson 2</strong>

</li><li><a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_3" title="Tutorial:PHP and MySQL Tutorial - Lesson 3"> PHP and MySQL Tutorial &#8211; Lesson 3</a>

</li></ul>

<p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/php_and_mysql_tutorial_-_lesson_2/feed/</wfw:commentRss>
        <slash:comments>1</slash:comments>

        
    </item>
    
    <item>
        <title>PHP and MySQL Tutorial &#8211; Lesson 3</title>
        <link>http://www.webmonkey.com/2010/02/php_and_mysql_tutorial_-_lesson_3/</link>
        <comments>http://www.webmonkey.com/2010/02/php_and_mysql_tutorial_-_lesson_3/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=737</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Welcome to the third and final lesson for this tutorial. If you&#8217;ve gone through Lesson 1 and Lesson 2, you already know the essentials for installing and writing useful scripts with MySQL and PHP. We&#8217;re going to look at some useful PHP functions that should make your life a lot easier. First, let&#8217;s look at [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Welcome to the third and final lesson for this tutorial. If you&#8217;ve gone through <a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_1" title="Tutorial:PHP and MySQL Tutorial - Lesson 1"> Lesson 1</a> and <a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_2" title="Tutorial:PHP and MySQL Tutorial - Lesson 2"> Lesson 2</a>, you already know the essentials for installing and writing useful scripts with MySQL and PHP. We&#8217;re going to look at some useful PHP functions that should make your life a lot easier. First, let&#8217;s look at include files.

</p><p>We all know the basics of includes, right? Contents of an external file are referenced and imported into the main file. It&#8217;s pretty easy:You call a file and it&#8217;s included. When we do this in PHP there are two functions we need to talk about:<tt>include()</tt> and <tt>require()</tt>. The difference between these two functions is subtle but important, so let&#8217;s take a closer look. The <tt>require()</tt> function works in a XSSI-like way; files are included as part of the original document as soon as that file is parsed, regardless of its location in the script. So if you decide to place a <tt>require()</tt> function inside a conditional loop, the external file will be included even if that part of the conditional loop is false.</p>
<br />
<span id="more-737"></span>

<p><b>A Place for Everything</b>
</p><p>The <tt>include()</tt> function imports the referenced file each time it is encountered. If it&#8217;s not encountered, PHP won&#8217;t bother with it. This means that you can use <tt>include</tt> in loops and conditional statements, and they&#8217;ll work exactly as planned.

</p><p>Finally, if you use <tt>require()</tt> and the file you&#8217;re including does not exist, your script will halt and produce an error. If you use <tt>include()</tt>, your script will generate a warning, but carry on. You can test this yourself by trying the following script. Run the script, then replace <tt>include()</tt> with <tt>require()</tt> and compare the results.



</p>

<pre class="brush: js">&lt;html&gt;



&lt;body&gt;

&lt;?php

include("emptyfile.inc");

echo "Hello World";

?&gt;

&lt;/body&gt;

&lt;/html&gt;
</pre>

<p>I like to use the suffix .inc with my include files so I can separate them from normal PHP scripts. If you do this, make sure that you set your Web server configuration file to parse .inc files as PHP files. Otherwise, hackers might be able to guess the name of your include files and display them through the browser as text files. This could be bad if you&#8217;ve got sensitive information &#8211; such as database passwords &#8211; contained in the includes.

</p><p>So what are you going to do with include files? Simple! Place information common to all pages inside them. Things like HTML headers, footers, database connection code, and user-defined functions are all good candidates. Paste this text into a file called header.inc.

</p>

<pre class="brush: js">&lt;?php

$db = mysql_connect("localhost", "root");

mysql_select_db("mydb",$db);

?&gt;

&lt;html&gt;

&lt;head&gt;

&lt;title&gt;

&lt;?php echo $title&nbsp;?&gt;

&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;center&gt;&lt;h2&gt;&lt;?php echo $title&nbsp;?&gt;&lt;/h2&gt;&lt;/center&gt;
</pre>

<p>Then create another file called footer.txt that contains some appropriate closing text and tags.

</p><p>Now let&#8217;s create a third file containing the actual PHP script. Try the following code, making sure that your MySQL server is running.

</p>

<pre class="brush: js">&lt;?php

$title = "Hello World";

include("header.inc");

$result = mysql_query("SELECT * FROM employees",$db);

echo "&lt;table border=1&gt;n";

echo "&lt;tr&gt;&lt;td&gt;Name&lt;/td&gt;&lt;td&gt;Position&lt;/tr&gt;n";

while ($myrow = mysql_fetch_row($result)) {

  printf("&lt;tr&gt;&lt;td&gt;%s&nbsp;%s&lt;/td&gt;&lt;td&gt;%s&lt;/tr&gt;n", $myrow[1], $myrow[2], $myrow[3]);

}

echo "&lt;/table&gt;n";

include("footer.inc");

?&gt;
</pre>

<p>See what happens? The include files are tossed into the main file and then the whole thing is executed by PHP. Notice how the variable <tt>$title</tt> was defined before header.inc is referenced. Its value is made available to the code in header.inc; hence, the title of the page is changed. You can now use header.inc across all your PHP pages, and all you&#8217;ll have to do is change the value of <tt>$title</tt> from page to page.

</p><p>Using a combination of includes, HTML, conditional statements, and loops, you can create complex variations from page to page with an absolute minimum of code. Includes become especially useful when used with functions, as we&#8217;ll see down the road.On to the exciting world of data validation.


<a name="Simple_Validation"></a><h4> <span class="mw-headline">Simple Validation</span></h4>

<p>Imagine for a moment that we&#8217;ve got our database nicely laid out and we&#8217;re now requesting information from users that will be inserted into the database. Further, let&#8217;s imagine that you have a field in your database waiting for some numeric input, such as a price. Finally, imagine your application falling over in a screaming heap because some smart aleck put text in that field. MySQL doesn&#8217;t want to see text in that portion of your SQL statement &#8211; and it complains bitterly.

</p><p>What to do? Time to validate.

</p><p>Validation simply means that we&#8217;ll examine a piece of data, usually from an HTML form, and check to make sure that it fits a certain model. This can range from ensuring that a element is not blank to validating that an element meets certain criteria (for example, that a numeric value is stipulated or that an email address contains an @ for an email address).

</p><p>Validation can be done on the server side or on the client side. PHP is used for server-side validation, while JavaScript or another client-based scripting language can provide client-side validation. This article is about PHP, so we&#8217;re going to concentrate on the server end of things.

</p><p>Let&#8217;s ignore our database for the moment and concentrate on PHP validation. If you wish, you can add additional fields to our employee database quite simply by using the MySQL <a href="http://www.mysql.com/Manual_chapter/manual_Reference.html#ALTER_TABLE" class="external text" title="http://www.mysql.com/Manual_chapter/manual_Reference.html#ALTER_TABLE" rel="nofollow">ALTER statement</a> &#8211; that is, if you want to commit to the values that we&#8217;ll validate.

</p><p>There are several useful PHP functions we can use to validate our data, and they range from simple to highly complex. A simple function we could use might be <tt>strlen()</tt>, which tells us the length of the variable.

</p><p>A more complex function would be <tt>ereg()</tt>, which uses full regular expression handling for complex queries. I won&#8217;t delve into the complexities of regex here, as entire books have been written on the subject, but I will provide some examples on the next page.



</p><p>Let&#8217;s start with a simple example. We&#8217;ll check to see whether a variable does or does not exist.

</p>

<pre class="brush: js"> &lt;html&gt;

 &lt;body&gt;

 &lt;?php

 if ($submit) {

      if (!$first ||&nbsp;!$last) {

 	$error = "Sorry! You didn't fill in all the fields!";

 	} else {

 		// process form

 		echo "Thank You!";
 	}
 }

 if (!$submit || $error) {

      echo $error;

     &nbsp;?&gt;

      &lt;P&gt;

      &lt;form method="post" action="&lt;?php echo $PHP_SELF&nbsp;?&gt;"&gt;

      FIELD 1:&lt;input type="text" name="first" value="&lt;?php echo $first&nbsp;?&gt;"&gt;

      &lt;br&gt;

      FIELD 2:&lt;input type="text" name="last" value="&lt;?php echo $last&nbsp;?&gt;"&gt;

      &lt;br&gt;

      &lt;input type="Submit" name="submit" value="Enter Information"&gt;

      &lt;/form&gt;

      &lt;?php

 } // end if

 ?&gt;

 &lt;/body&gt;

 &lt;/html&gt;

</pre>

<p>The keys to this script are the nested conditional statements. The first checks to see whether the Submit button has been pressed. If it has, it goes on to check that both the variables <tt>$first</tt> and <tt>$last</tt> exist. The || symbol means &#8220;or&#8221; and the&nbsp;! symbol means &#8220;not.&#8221; We could also rewrite the statement to say, &#8220;If $first does not exist or $last does not exist, then set $error to the following.&#8221;

</p><p>Next, let&#8217;s extend things a little by checking to see whether a string is a certain length. This would be ideal for passwords, since you don&#8217;t want some lazy user entering a password of only one or two letters. You&#8217;d rather it be, say, six or more characters.

</p><p>The function for this is, as you already know, <tt>strlen()</tt>. It simply returns a number equal to the number of characters in the variable being tested. Here, I modified the script above to check the length of <tt>$first</tt> and <tt>$last</tt>.

</p>

<pre class="brush: js"> &lt;html&gt;

 &lt;body&gt;

 &lt;?php

 if ($submit) {

      if (strlen($first) &lt; 6 || strlen($last) &lt; 6) {

 	$error = "Sorry! You didn't fill in all the fields!";

 	} else {

 		// process form

 		echo "Thank You!";

 	}

 }

 if (!$submit || $error) {

      echo $error;

     &nbsp;?&gt;

      &lt;P&gt;

      &lt;form method="post" action="&lt;?php echo $PHP_SELF&nbsp;?&gt;"&gt;

      FIELD 1:&lt;input type="text" name="first" value="&lt;?php echo $first&nbsp;?&gt;"&gt;

      &lt;br&gt;

      FIELD 2:&lt;input type="text" name="last" value="&lt;?php echo $last&nbsp;?&gt;"&gt;

      &lt;br&gt;

      &lt;input type="Submit" name="submit" value="Enter Information"&gt;

      &lt;/form&gt;

      &lt;?php

 } // end if

 ?&gt;

 &lt;/body&gt;

 &lt;/html&gt;

</pre>

<p>Run this script and try entering six or fewer letters to see what happens. It&#8217;s simple yet quite effective.

</p>

<a name="Not-So-Simple_Validation"></a><h4> <span class="mw-headline">Not-So-Simple Validation</span></h4>

<p>Let&#8217;s talk a bit about using regular expressions with the <tt>ereg()</tt> and <tt>eregi()</tt> functions. As I said earlier, these can be either quite complex or very simple, depending on what you need.

</p><p>Using regular expressions, you can examine a string and intelligently search for patterns and variations to see whether they match the criteria you set. The most common of these involves checking whether an email address is valid (although, of course, there&#8217;s no fail-safe way of doing this).

</p><p>Rather than delve into the mysteries of regular expressions, I&#8217;ll provide some examples. You can use the same form we created on the previous page &#8211; just paste in the lines below to see how they work.

</p><p>First, let&#8217;s make sure that text only has been entered into a form element. This regular expression tests true if the user has entered one or more lowercase characters, from a to z. No numbers are allowed:

</p>

<pre class="brush: js"> if (!ereg("[a-Z]", $first) ||&nbsp;!ereg("[a-Z]", $last)) { </pre>

<p>Now, let&#8217;s extend this expression to check whether the string is four to six characters in length. Using <tt><a href="/special?title=Alpha:&amp;action=edit" class="new" title="Alpha:">alpha:</a></tt> is an easy way to check for valid alphabetic characters. The numbers in the braces check for the number of occurrences. And note that the ^ and $ indicate the beginning and end of the string.

</p>

<pre class="brush: js"> if (!ereg("^[[:alpha:]]{4,6}$", $first) ||&nbsp;!ereg("^[[:alpha:]]{4,6}$", $last)) { </pre>

<p>Finally, let&#8217;s build a regular expression that will check an email address&#8217; validity. There&#8217;s been plenty of discussion about the effectiveness of checking for email addresses in this way. Nothing&#8217;s completely foolproof, but what I have below works pretty well.

</p><p>I took this gem from the PHP <a href="http://www.progressive-comp.com/Lists/?l=php3-general#php3-general" class="external text" title="http://www.progressive-comp.com/Lists/?l=php3-general#php3-general" rel="nofollow">mailing list</a>. It&#8217;s a great resource &#8211; use it. And yes, this is as scary as it looks.

</p>

<pre class="brush: js">	if (!ereg('^[-!#$%&amp;'*+./0-9=?A-Z^_`a-z{|}~]+'.

'@'.

'[-!#$%&amp;'*+/0-9=?A-Z^_`a-z{|}~]+.'.

'[-!#$%&amp;'*+./0-9=?A-Z^_`a-z{|}~]+$', $last)) {

</pre>

<p>Don&#8217;t spend too much time looking at this. Just move on to the next bit.

</p>

<a name="Functions"></a><h4> <span class="mw-headline">Functions</span></h4>

<p>Enjoy that last regex expression? Fun, wasn&#8217;t it? Wouldn&#8217;t it be even more fun to enter that chunk on a dozen different pages that need to process email addresses?! Think about the joy of finding a typo in that mess &#8211; and doing it a dozen times no less. But of course, there&#8217;s a better way.

</p><p>Remember when we talked about include files earlier in this lesson? They&#8217;ll allow us to create a piece of code like the email checker and include it multiple times across several pages. This way, when we want to change the code, we need edit only one file, not many.

</p><p>But if we want to get this done, we&#8217;ll have to use functions.

</p><p>We&#8217;ve already used functions plenty of times. Every time we query the database or check the length of a string we&#8217;re using functions. These functions are built into PHP. If you&#8217;re a keen coder, you can extend PHP with your own customized functions. But that&#8217;s a bit advanced for this tutorial. Instead we&#8217;ll create functions that will reside within our PHP script.

</p><p>A function is simply a block of code that we pass one or more values to. The function then processes the information and returns a value. The function can be as simple or complex as we like, but as long as we can pass a value in and get one out, we don&#8217;t really care how complex it is. That&#8217;s the beauty of functions.

</p><p>Functions in PHP behave similarly to functions in C. When we define the functions, we must specify what values the function can expect to receive. It&#8217;s tricky to get a handle on at first, but it prevents weird things from happening down the road. This is done because the variables inside a function are known as private variables. That is, they exist only inside the function. You may, for instance, have a variable in your script called <tt>$myname</tt>. If you created a function and expected to use the same <tt>$myname</tt> variable (with the same value), it wouldn&#8217;t work. Alternatively, you could have the variable <tt>$myname</tt> in your script and also create another variable called <tt>$myname</tt> in your function, and the two would co-exist quite happily with separate values. I do not recommend doing this, however! When you come back and edit it six months later, you&#8217;ll be breaking things left and right. There are exceptions to this rule as with all things, but that&#8217;s outside the scope of this article.



</p><p>So let&#8217;s create a function. We&#8217;ll start simply. We need to give the function a name and tell it what variables to expect. We also need to define the function before we call it.

</p>

<pre class="brush: js"> &lt;html&gt;
 &lt;body&gt;

 &lt;?php

 function  addnum($first, $second) {

 	$newnum = $first + $second;

	return $newnum;

 }

 echo addnum(4,5);

 ?&gt;

 &lt;/body&gt;

 &lt;/html&gt;

</pre>

<p>That&#8217;s it! First, we created our function. Notice how we defined two new variables, called <tt>$first</tt> and <tt>$second</tt>. When we call the function, each variable is assigned a value based on the order in which it appears in the list &#8211; 4 goes to <tt>$first</tt>, 5 to <tt>$second</tt>. Then we simply added the two numbers together and returned the result. &#8220;Return&#8221; here simply means to send the result back. At the end of the script we print the number 9.

</p><p>Let&#8217;s create something that&#8217;s more useful to our database application. How about something that gracefully handles errors? Try this:

</p>

<pre class="brush: js"> &lt;html&gt;
 &lt;body&gt;

 &lt;?php

 function  do_error($error) {

 	echo  "Hmm, looks like there was a problem here...&lt;br&gt;";

 	echo "The reported error was $error.n&lt;br&gt;";

 	echo "Best you get hold of the site admin and let her know.";

 	die;
 }

 if (!$db = @mysql_connect("localhost","user", "password")) {

 	$db_error = "Could not connect to MySQL Server";

 	do_error($db_error);

 }

 ?&gt;

 &lt;/body&gt;
 &lt;/html&gt;
</pre>

<p>Before running this, try shutting down MySQL or using a bogus username or password. You&#8217;ll get a nice, useful error message. Observant readers will notice the @ symbol in front of <tt>mysql_connect()</tt>. This suppresses error messages so that you get the information only from the function. You&#8217;ll also see we were able to pass a variable into the function, which was defined elsewhere.

</p><p>Remember that I said functions use their own private variables? That was a little white lie. In fact, you can make variables outside of a function accessible to the function. You might create a function to query a database and display a set of results over several pages. You don&#8217;t want to have to pass the database connection identifier into the function every time. So in this situation, you can make connection code available as a global variable. For example:

</p>

<pre class="brush: js">

 &lt;html&gt;

 &lt;body&gt;

 &lt;?php

 function  db_query($sql) {

 	global $db;

 	$result = mysql_query($sql,$db);

 	return $result;

 }

 $sql = "SELECT * FROM mytable";

 $result = db_query($sql);

 ?&gt;

 &lt;/body&gt;

 &lt;/html&gt;
 </pre>

<p>This is a basic function, but the point is that you don&#8217;t need to send <tt>$db</tt> through when you call the function &#8211; you can make it available using the word global. You can define other variables as global in this statement, just separate the variable names by a comma.

</p><p>Finally, you can look like a real pro by using optional function variables. Here, the key is to define the variable to some default in the function, then when you call the function without specifying a value for the variable, the default will be adopted. But if you do specify a value, it will take precedence.

</p><p>Confused? For example, when you connect to a database, you nearly always connect to the same server and you&#8217;ll likely use the same username and password. But sometimes you&#8217;ll need to connect to a different database. Let&#8217;s take a look.

</p>

 <pre class="brush: js"> &lt;html&gt;
 &lt;body&gt;
 &lt;?php

 function  db_connect($host = "localhost", $user="username", $pass="graeme") {

 	$db = mysql_connect($host, $username, $password);

 	return $db;

 }

 $old_db = db_connect();

 $new_host = "site.com";

 $new_db = db_connect($new_host);

 ?&gt;

 &lt;/body&gt;

 &lt;/html&gt;
 </pre>

<p>Isn&#8217;t that cool? The variables used inside the function were defined when the function was defined. The first time the function is called, the defaults are used. The second time, we connect to a new host, but with the same username and password. Great stuff!

</p><p>Think about where you could use other functions in your code. You could use them for data checking, performing routine tasks, and so on. I use them a lot when processing text for display on a Web page. I can check, parse, and modify the text to add new lines and escape HTML characters in one fell swoop.

</p><p>Now all that&#8217;s left to do is to impart some words of wisdom.

</p>

<a name="Closing_Advice"></a><h4> <span class="mw-headline">Closing Advice</span></h4>

<p>When it comes to databasing, there&#8217;s a lot to learn. If you haven&#8217;t done it already, find a good book about database design and learn to put together a solid database &#8211; on any platform. It&#8217;s an invaluable skill and it will save you plenty of time and headache in the long run. Also, learn about MySQL. It&#8217;s a complex but interesting database with a wealth of useful documentation. Learn about table structure, data types, and SQL. You can actually achieve some pretty impressive stuff if you know enough SQL.

</p><p>Finally, there&#8217;s PHP. The PHP Web site has nearly everything you need, from a comprehensive manual to mailing-list archives to code repositories. An excellent way to learn about PHP is to study the examples used in the manual and to check out the code archives. Many of the posted scripts consist of functions or classes that you can use for free in your own scripts without having to reinvent the wheel. Additionally, the mailing list is an excellent spot to check out if you get stuck. The developers themselves read the list and there are plenty of knowledgeable people there who can help you along the way.

</p><p>Good luck and good coding!

</p>

<ul><li><a href="/2010/02/PHP_and_MySQL_Tutorial" title="Tutorial:PHP and MySQL Tutorial"> PHP and MySQL Tutorial</a>

</li><li><a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_1" title="Tutorial:PHP and MySQL Tutorial - Lesson 1"> PHP and MySQL Tutorial &#8211; Lesson 1</a>

</li><li><a href="/2010/02/PHP_and_MySQL_Tutorial_-_Lesson_2" title="Tutorial:PHP and MySQL Tutorial - Lesson 2"> PHP and MySQL Tutorial &#8211; Lesson 2</a>

</li><li><strong class="selflink"> PHP and MySQL Tutorial &#8211; Lesson 3</strong>

</li></ul>

<p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/php_and_mysql_tutorial_-_lesson_3/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Cake and Trax for Beginners</title>
        <link>http://www.webmonkey.com/2010/02/cake_and_trax_for_beginners/</link>
        <comments>http://www.webmonkey.com/2010/02/cake_and_trax_for_beginners/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=767</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[In my last article, Building With Ajax and Rails I made a faintly disparaging joke about some new web frameworks that have been created in fond imitation of Rails. I got a lot of feedback about that joke. I&#8217;m not allowed to comment here about the pending lawsuits, but I would ask that the drive-by [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>In my last article, <a href="/2010/02/Building_With_Ajax_and_Rails" title="Tutorial:Building With Ajax and Rails"> Building With Ajax and Rails</a> I made a faintly disparaging joke about some new web frameworks that have been created in fond imitation of Rails. I got a lot of feedback about that joke. I&#8217;m not allowed to comment here about the pending lawsuits, but I would ask that the drive-by eggings of my house and threats to my family please cease. (They&#8217;ve been relocated to a secret Webmonkey farm anyway.)

</p><p>Today we&#8217;re going to take a look at a couple of those frameworks for PHP:<a href="http://phpontrax.com/" class="external text" title="http://phpontrax.com/" rel="nofollow">Trax</a> and <a href="http://cakephp.com/" class="external text" title="http://cakephp.com/" rel="nofollow">Cake</a>. Both attempt to bring the quick, easy, helpful tools and easily understood, easily maintained structure of Rails to PHP &#8212; a boon to web developers who know PHP and perhaps have some keeper code in that language, but can&#8217;t resist the Rails buzz. Both Trax and Cake use the same model-view-controller pattern and Active Record ways of addressing data that Rails does. Makes one curious, no? I don&#8217;t have time to get deeply into them today, but both stress &#8220;rapid development,&#8221; so let&#8217;s see if I, your average not-too-bright web developer, can get a little app off the ground before the end of this article.

</p><span id="more-767"></span><p><br />

</p>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#Cutting_into_Cake">Cutting into Cake</a></li>

<li><a href="#Makin.27_Trax">Makin&#8217; Trax</a></li>



<li><a href="#Hardly_the_End_of_the_Story">Hardly the End of the Story</a></li>

<li><a href="#Helpful_Links">Helpful Links</span></a></li>

</ol>

</td></tr></tbody></table>



<p><br />

</p><p><br />

</p>

<a name="Cutting_into_Cake"></a><h3> <span class="mw-headline">Cutting into Cake</span></h3>



<p>This is 100 percent true:At lunch yesterday, my fortune cookie said &#8220;A nice cake is waiting for you.&#8221; So, I am going to start with Cake first and try Trax later.

</p><p>I go to the <a href="http://cakephp.org/downloads/index/release" class="external text" title="http://cakephp.org/downloads/index/release" rel="nofollow">Cake site</a> and download the latest stable release (discouragingly called 1.1.19.6305) onto my Debian web server running Apache and PHP 5. Unzipping the tarchive, I immediately see some names that look familiar from Rails:<tt>app</tt>, <tt>config</tt> and something called <tt>dispatcher.php</tt>. The <tt>app</tt> directory looks even friendlier. It contains <tt>views</tt>, <tt>controllers</tt>, <tt>model</tt> &#8211; just like Rails!



</p><p>There&#8217;s also a <tt>webroot</tt> directory, which I assume is going to be the root of my application. Indeed, look at that! If I browse to <tt><a href="http://my.web.server/trax_and_cake_playground/cake/app/webroot" class="external free" title="http://my.web.server/trax_and_cake_playground/cake/app/webroot" rel="nofollow">http://my.web.server/trax_and_cake_playground/cake/app/webroot</a></tt>, I see a friendly boilerplate intro page. Later, if I decide I want to use Cake full time, I&#8217;ll add a line to my Apache configuration to set that directory as the whole server&#8217;s root directory. At the moment, the page is extolling Cake&#8217;s coolness and warning me, &#8220;Your database configuration file is not present.&#8221;

</p><p>Correct, it&#8217;s not. I find a sample database configuration in <tt>app/config/database.php.default</tt>. I&#8217;ll copy that sample to an actual working file, database.php, in the same directory. The file includes an array of settings, which I change to suit my own environment:

</p><p><br />

</p>

 <pre class="brush: js">var $default = array('driver'   =&gt; 'mysql',



                  'connect'  =&gt; 'mysql_pconnect',



                  'host'     =&gt; 'localhost',



                  'login'    =&gt; 'paul',



                  'password' =&gt; 'passw0rd',



                  'database' =&gt; 'bookmarker' );



</pre>

<p><br />

Now, when I reload the intro page, it tells me, &#8220;Your database configuration file is present. Cake is able to connect to the database.&#8221; Yay!

</p><p>Now, I&#8217;ve told it I have a MySQL database called &#8220;bookmarker,&#8221; but that&#8217;s not true yet. I still have to create it. I&#8217;m eager to get rolling, so I&#8217;ll just recycle the code from Webmonkey&#8217;s <a href="/2010/02/Ruby_on_Rails_for_Beginners" title="Tutorial:Ruby on Rails for Beginners"> Ruby on Rails for Beginners</a> article in which I built a bookmarking app. This time I also want to populate the table with a little starter data, to give us something to work with. So I type:

</p>

<pre class="brush: js"> $mysql



 mysql&gt; CREATE DATABASE bookmarker;



 mysql&gt; USE bookmarker;



 mysql&gt; CREATE TABLE bookmarks (



    -&gt;  id SMALLINT (5) NOT NULL auto_increment,



    -&gt;  url VARCHAR (255),



    -&gt;  name VARCHAR (100),



    -&gt;  description VARCHAR (255),



    -&gt;  PRIMARY KEY (id)



    -&gt; );



 mysql&gt; INSERT INTO bookmarks (url, name, description) VALUES



 ('http://webmonkey.com/', 'Webmonkey', 'Not the only monkey that makes



 websites, but the best!');



 mysql&gt; INSERT INTO bookmarks (url, name, description) VALUES



 ('http://ubuntu.com/', 'Ubuntu', 'Linux for human beings (no monkeys



 please!)');



 mysql&gt; exit;



</pre>

<p>At this point in developing a Rails app, I&#8217;d run the built-in scaffold-generating tool. Here in Cakeland, I see a file called <tt>bake.php</tt> in <tt>cake/scripts</tt>, and instantly I pick up on the metaphor &#8211; bake a cake, get it? Turns out that&#8217;s a false start, as <tt>bake.php</tt> doesn&#8217;t seem to work in the pre-beta. It&#8217;s giving me all sorts of fatal errors and files not found. I&#8217;m going to have to create my model, view and controller by hand-editing code.

</p><p>The <tt>app/models</tt> directory contains an empty file called <tt>put_models_here</tt>. So, I do just that, creating a file in that directory called <tt>bookmark.php</tt>:



</p>

<pre class="brush: js"> &lt;?php



 class Bookmark extends AppModel



 {



     var $name = 'Bookmarks';



    function display()



     {



         $this-&gt;set('data',$this-&gt;Bookmark-&gt;findAll());



     }



 }



 ?&gt;

</pre>

<p>That puts the data from the table in <tt>$data</tt>, using the built-in <tt>set</tt> method. You might want to read along in the Cake <a href="http://api.cakephp.org/" class="external text" title="http://api.cakephp.org/" rel="nofollow">API documentation</a> &#8211; I certainly am!



</p><p>Then I create a controller, <tt>app/controllers/bookmarks_controller.php</tt>:

</p>

<pre class="brush: js"> &lt;?php



 class BookmarksController extends AppController



 {



     var $name = 'Bookmarks';



 }



 ?&gt;

</pre>

<p>I will also need to create a view. In the <tt>app/views</tt> directory, I create a subdirectory called <tt>bookmarks</tt> and a file called <tt>index.thtml</tt> inside of the subdirectory. The &#8220;t&#8221; in the file extension is for template, I assume. Note that I have had to scratch around in some slightly opaque documentation to glean all this &#8211; not as polished as Rails, not yet at least! In <tt>index.thtml</tt> I just put together a little <tt>foreach</tt> loop to display my content:



</p>

 <pre class="brush: js">&lt;?php



 echo "&lt;p&gt;&lt;table&gt;";



 foreach ($data as $bookmark):



      echo "&lt;tr&gt;&lt;td&gt;";



      echo $html-&gt;link($bookmark['Bookmark']['name'],



 $bookmark['Bookmark']['url']);



      echo "&lt;/td&gt;&lt;td&gt;&lt;b&gt;";



      echo $bookmark['Bookmark']['description'];



      echo "&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;";



 endforeach;



 echo "&lt;/table&gt;&lt;p&gt;";



 ?&gt;



</pre>

<p><br />

Finally, I need to add routing in order to tell Cake where my little app is and what to do with it. In <tt>app/config/routes.php</tt> I add a line:

</p>

<pre class="brush: js"> $Route-&gt;connect ('/bookmarks/*', array('controller'=&gt;'bookmarks',



 'action'=&gt;'display'));

</pre>

<p>Note that the action, &#8220;display&#8221;, corresponds to the method I defined in my controller.

</p><p>Now all the pieces are in place at last. I browse to <tt><a href="http://my.web.server/trax_and_cake_playground/cake/index.php/" class="external free" title="http://my.web.server/trax_and_cake_playground/cake/index.php/" rel="nofollow">http://my.web.server/trax_and_cake_playground/cake/index.php/</a> bookmarks </tt> (I can clean up that ugly URL later) and lo! The boilerplate page is now displaying the preliminary bookmarks I put in my table! I am up and running. In Rails, at this point, I would have some nice auto-generated methods to add and delete bookmarks. Hopefully Cake&#8217;s auto-bake feature will come together soon.



</p><p>Next, let&#8217;s take a look at Trax.

</p><p><br />

</p>

<a name="Makin.27_Trax"></a><h3> <span class="mw-headline">Makin&#8217; Trax</span></h3>

<p>Quick now, we know the drill. Go to the <a href="http://www.phpontrax.com/downloads/?downloads.html" class="external text" title="http://www.phpontrax.com/downloads/?downloads.html" rel="nofollow">Trax site</a>, download the archive, untar it. Like all of these prima-donna frameworks, Trax wants to be the top level of my web hierarchy, or rather it wants its <tt>public</tt> directory to be, and its <tt>trax</tt> directory to be parallel at the same level, out of sight of prying eyes. If my web server were publicly accessible, I&#8217;d put it up there, or find a way around that limitation. For now I&#8217;ll just unzip it in my playground (so to speak). Whoo!

</p><p>Already now, if I go to <tt><a href="http://my.web.server/trax_and_cake_playground/trax/public/" class="external free" title="http://my.web.server/trax_and_cake_playground/trax/public/" rel="nofollow">http://my.web.server/trax_and_cake_playground/trax/public/</a></tt>, I have a page telling me &#8220;Congratulations, you&#8217;ve put PHP on Trax!&#8221; I feel good.



</p><p>Trax <i>does</i> have a working auto-generate function, which is very nice, because I am getting tired of hand-editing all these files. If I wanted to do that, I&#8217;d be writing Perl or something. Still, there are a few more steps. I need to install the PEAR modules that Trax requires, which I do on the command-line:

</p>

<pre class="brush: js"> pear install Mail_Mime

</pre>

<p>I&#8217;ll use the same database and table I created back at the beginning, so long ago. I need to configure <tt>trax/config/database.ini</tt> to tell the application where they are:

</p>

<pre class="brush: js">    phptype = mysql



    database = bookmarker



    hostspec = localhost



    username = paul



    password = passw0rd



    persistent = 1

</pre>

<p>And then I need to edit <tt>public/.htaccess</tt> to tell the application where in my file system its own configuration is. The start of that file reads:



</p>

<pre class="brush: js"> # php include path for Trax ( Pear &amp; Trax config dir )



 php_value include_path



 .:/usr/local/lib/php:/home/&lt;username&gt;/trax/config

</pre>

<p>I change it to suit my Debian setup:

</p>

<pre class="brush: js"> # php include path for Trax ( Pear &amp; Trax config dir )



 php_value include_path .:/usr/share/php:/var/www/html/trax/trax/config

</pre>

<p>Now I am ready to &#8212; make Trax? Lay down Trax? There doesn&#8217;t seem to be a catchy verb for auto-generating models and controllers and views here. I, um, look both ways and prepare to cross the Trax.

</p><p>The script that does the work is <tt>trax/script/generate.php</tt>. First, I need to edit the first line of that file to point to where my PHP executable actually is. Not <tt>/usr/local/bin/php</tt>, as the default has it. Mine is at <tt>/usr/bin/php</tt>. Also, the script seems to be happiest if I add my path information there as well, so toward the beginning of the file I enter the following:



</p>

<pre class="brush: js"> ini_set("include_path", ".:/usr/share/php:/var/www/html/trax/trax/config"); </pre>

<p>While I&#8217;m at it, I&#8217;ll add the same line to <tt>public/dispatch.php</tt>.

</p><p>Then I need to make <tt>generate.php</tt> executable with a deft <tt>chmod a+x</tt>.

</p><p>Now I&#8217;m ready to run the generate script, which I do from the command line. If your server doesn&#8217;t like PHP scripts to be run from the command line, you&#8217;ll have to open the script in a browser. I type this:

</p>

<pre class="brush: js"> ./trax/script/generate.php model Bookmark </pre>



<p>and Trax replies:

</p>

<pre class="brush: js"> created /var/www/html/trax/trax/app/models/bookmark.php </pre>

<p>Then I type:

</p>

<pre class="brush: js"> ./trax/script/generate.php controller bookmark display add </pre>

<p>and Trax replies:

</p>

 <pre class="brush: js">created /var/www/html/trax/trax/app/controllers/bookmark_controller.php



 created /var/www/html/trax/trax/app/helpers/bookmark_helper.php



 created /var/www/html/trax/trax/app/views/bookmark/display.phtml



 created /var/www/html/trax/trax/app/views/bookmark/add.phtml

</pre>

<p><br />

&#8220;Display&#8221; and &#8220;add&#8221; are the initial views I want. Finally (I hope), I just need to add routing, so I can view my views in a browser. I add the following to <tt>trax/config/routes.php</tt>:



</p>

<pre class="brush: js"> $router-&gt;connect( "", array(":controller" =&gt; "bookmark") ); </pre>

<p>and <i>voila</i>! I can see a page! True, it&#8217;s blank, which means that I need to flesh out my actions and views. But it is a page! Let me just put in a couple of basics.

</p><p>In <tt>trax/app/controllers/bookmark_controller.php</tt>, there&#8217;s an empty definition of the view() method. I&#8217;ll put this in:

</p>

<pre class="brush: js"> function view() {



        $bookmark = new Bookmark();



        $this-&gt;bookmarks = $bookmark-&gt;find_all();



    }



</pre>

<p><br />

and in <tt>app/views/bookmark/display.phtml</tt> I put a PHP table similar to the one I used for Cake, to loop through the bookmarks table and display each one.

</p><p>Whew. Two starter semi-apps built in as many hours. Not too bad.

</p><p><br />

</p>

<a name="Hardly_the_End_of_the_Story"></a><h3> <span class="mw-headline">Hardly the End of the Story</span></h3>

<p>Would I do it again? Are either of the frameworks are 100 percent ready for prime time? Documentation is getting better every day, but neither framework has anything like the whopping user community of Rails.

</p><p>I was able to iron out my own snags &#8212; several had to do with permissions, Apache directory overrides, and stuff like that &#8211; but if I couldn&#8217;t, it would be nice to have more resources to turn to. Conversely, PHP has a considerably larger support community on the Web than Ruby does, although that tide may slowly be turning.

</p><p>Trax and Cake aren&#8217;t the end of the PHP dev framework story:there&#8217;s <a href="http://www.symfony-project.com/" class="external text" title="http://www.symfony-project.com/" rel="nofollow">Symfony</a>; Zend has a <a href="http://www.zend.com/collaboration/framework-overview.php" class="external text" title="http://www.zend.com/collaboration/framework-overview.php" rel="nofollow">framework</a> and a quick trawl of the web turns up things like <a href="http://www.php2go.com.br/" class="external text" title="http://www.php2go.com.br/" rel="nofollow">PHP2Go</a>, <a href="http://qcodo.com/" class="external text" title="http://qcodo.com/" rel="nofollow">Qcodo</a> and doubtless many more.



</p><p>Rails is a pleasure to use, while Trax and Cake combine pleasure with a bit of effort. If you&#8217;re a PHP wiz, though, the fact that they&#8217;re based in a language you know should more than outweigh any difficulties brought on by the frameworks&#8217; immaturity. It&#8217;s easier to debug a stuck app than to learn a whole new language, even one as perspicuous and enjoyable as Ruby.

</p><p>So tune in next time when we cover Brails, the new web programming framework for the visually impaired! That&#8217;s a joke. Don&#8217;t sue.

</p><p><br />

</p>

<a name="Helpful_Links"></a><h3> <span class="mw-headline">Helpful Links</span></h3>

<ul><li> Visit <a href="http://cakephp.org/" class="external text" title="http://cakephp.org/" rel="nofollow">CakePHP.org</a>

</li><li> Visit <a href="http://bakery.cakephp.org/" class="external text" title="http://bakery.cakephp.org/" rel="nofollow">The Bakery</a>

</li><li> Visit the <a href="http://www.nabble.com/CakePHP-f16511.html" class="external text" title="http://www.nabble.com/CakePHP-f16511.html" rel="nofollow">CakePHP forum</a> at Nabble



</li></ul>

<ul><li> Visit the <a href="http://forum.phpontrax.com/" class="external text" title="http://forum.phpontrax.com/" rel="nofollow">Trax forum</a>

</li></ul>

<p><br />

</p><p><br /><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/cake_and_trax_for_beginners/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    </channel>
</rss>