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

<channel>
	<title>Hendraktp's Weblog</title>
	<atom:link href="http://hendraktp.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://hendraktp.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Fri, 09 Jan 2009 07:23:19 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='hendraktp.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/c018a9bc8fb8bc5f75b5e7b586a49b46?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Hendraktp's Weblog</title>
		<link>http://hendraktp.wordpress.com</link>
	</image>
			<item>
		<title>Learn symfony: a Beginner&#8217;s Tutorial (3)</title>
		<link>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-3/</link>
		<comments>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-3/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 06:58:56 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=32</guid>
		<description><![CDATA[Modifying the Model
So far, there hasn&#8217;t been much PHP code in this tutorial. That&#8217;s one of the strengths of symfony: it doesn&#8217;t force you to write code that symfony can generate itself based on simple data. However, you will need to write a few lines of PHP for the tags in the model. First, let&#8217;s [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=32&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><h5>Modifying the Model</h5>
<p>So far, there hasn&#8217;t been much <a class="glossary" title="PHP, or Hypertext Preprocessor, is an open source, server-side programming language." href="http://www.sitepoint.com/glossary.php?q=P#term_1">PHP</a> code in this tutorial. That&#8217;s one of the strengths of symfony: it doesn&#8217;t force you to write code that symfony can generate itself based on simple data. However, you will need to write a few lines of PHP for the tags in the model. First, let&#8217;s explore the model&#8217;s structure.</p>
<p><span id="more-32"></span>The <code>propel-build-all</code> command generated two files for each table in the <code>lib/model/</code> directory. For instance, for the <code>photo</code> table, the generated model files are <code>Photo.php</code> and <code>PhotoPeer.php</code>. If you look at their code, they actually contain empty classes that inherit from other classes (<code>BasePhoto</code> and <code>BasePhotoPeer</code>) located in the <code>lib/model/om/</code> directory. For instance, the generated <code>lib/model/Photo.php</code> content is as follows:</p>
<p><code>&lt;?php<br />
/**<br />
* Subclass for representing a row from the 'photo' table.<br />
*<br />
*<br />
*<br />
* @package lib.model<br />
*/<br />
class Photo extends BasePhoto<br />
{<br />
}</code></p>
<p>When you build the model with the command line, only the classes in the <code>lib/model/om/</code> directory are modified. Have a look at them to see the amount of code that&#8217;s been generated. The classes in <code>lib/model/</code> are never altered by the code generator (which just creates their empty shell the first time); to extend the model, you should write your methods in these empty classes. This mechanism allows you to extend the model classes without risking the loss of your modifications should you decide to change the relational schema and build the model again. The model class system is both extensible and scalable.</p>
<p>We split the generated code into two classes (<code>Photo</code> and <code>PhotoPeer</code>) to differentiate between the methods linked to individual objects, and the methods linked to the class, but not its objects &#8212; or, if you prefer, to differentiate between object and static methods. The <code>PhotoPeer</code> class contains only static methods that are used to retrieve objects of class <code>Photo</code>. You will soon understand how it works.</p>
<p>We want to have the ability to add tags to, or delete tags from, a photo. The foreign key between the photo and tag tables (the <code>photo_id</code> column in the tag structure) is instantiated in the <code>Photo</code> object by a generated <code>getTags</code> method. Symfony generated this method automatically and placed it in the <code>BasePhoto</code> class so that the <code>Photo</code> class can use it as well. So, if you have a <code>Photo</code> object, you can get its related tags like this:</p>
<p><code>$tags = $photo-&gt;getTags();</code></p>
<p>That&#8217;s right, there&#8217;s no need to call an SQL query with a <code>WHERE</code> clause &#8212; the generated <code>Base</code> classes do it automatically. We&#8217;ll use the same principle to add new methods to the <code>Photo</code> class. Open the <code>Photo.php</code> file and add the following methods:</p>
<p><code>// in lib/model/Photo.php<br />
class Photo extends BasePhoto<br />
{<br />
public function getTagsString()<br />
{<br />
$tags = <a class="glossary" title="An array is a single variable with compartments, each of which can hold a value. " href="http://www.sitepoint.com/glossary.php?q=%23#term_72">array</a>();<br />
foreach ($this-&gt;getTags() as $tag)<br />
{<br />
$tags[] = $tag-&gt;__toString();<br />
}<br />
return implode(' ', $tags);<br />
}</code></p>
<p>public function setTagsString($tagPhrase)<br />
{<br />
// remove old tags<br />
$this-&gt;deleteTags();</p>
<p>// set new tags<br />
$tagNames = explode(&#8216; &#8216;, $tagPhrase);<br />
foreach($tagNames as $tagName)<br />
{<br />
$tag = new Tag();<br />
$tag-&gt;setPhoto($this);<br />
$tag-&gt;setName($tagName);<br />
$tag-&gt;save();<br />
}<br />
}</p>
<p>public function deleteTags()<br />
{<br />
$c = new Criteria();<br />
$c-&gt;add(TagPeer::PHOTO_ID, $this-&gt;getId());<br />
TagPeer::doDelete($c);<br />
}<br />
}</p>
<p>There&#8217;s a lot to explain in these three methods. First, as you saw previously, the generated <code>getTags</code> method returns an array of <code>Tag</code> objects. Returning the tags of a photo as a string is no harder than calling the <code>implode</code> function.</p>
<p>Second, the <code>setTagsString</code> method creates <code>Tag</code> objects from a string, and relates them to the current <code>Photo</code> object. This is a good illustration of how to manipulate the fields of a record in a related object using the dynamic setter methods, which were also generated by the <code>propel-build-all</code> command. The call to the <code>save</code> method triggers an <code>INSERT</code> query to the database to create a record based on the properties of the object. Last, the <code>deleteTags</code> method calls static constants and methods in the <code>TagPeer</code> class, as well as the <code>add</code> method in the <code>Criteria</code> object. We won&#8217;t describe these methods now &#8212; you just need to understand that the <code>doDelete</code> call triggers a <code>DELETE</code> query in the database to remove all tags related to the current <code>Photo</code>.</p>
<p>One last thing: for the <code>getTagsString</code> method to work, an object of class <code>Tag</code> must be able to be output as a string. We can achieve this by adding a magic <code>__toString</code> method to the <code>Tag</code> class, as follows:</p>
<p><code>// in lib/model/Tag.php<br />
class Tag extends BaseTag<br />
{<br />
public function __toString()<br />
{<br />
return $this-&gt;getName();<br />
}<br />
}</code></p>
<p>Adding a new getter and a new setter is enough to simulate a new column. This means that we can add the <code>tags_string</code> column in the display <a class="glossary" title="An array is a single variable with compartments, each of which can hold a value. " href="http://www.sitepoint.com/glossary.php?q=%23#term_72">arrays</a> of our <code>generator.yml</code> as if it were an actual field. That&#8217;s the beauty of an object model:</p>
<p><code>// in apps/frontend/modules/photo/config/generator.yml<br />
generator:<br />
class:              sfPropelAdminGenerator<br />
param:<br />
model_class:      Photo<br />
theme:            default<br />
list:<br />
display:        [_photo, description, <strong>tags_string</strong>, created_at]<br />
object_actions:<br />
_edit:<br />
name:       Edit picture properties<br />
edit:<br />
display:        [_photo, file_path, description, <strong>tags_string</strong>]<br />
fields:<br />
file_path:<br />
type:       admin_input_file_tag<br />
<strong>tags_string:<br />
name:       Tags<br />
type:       input_tag</strong></code></p>
<p>We need to define the type of input to use for the mock <code>tags_string</code> column because symfony does not have any data that it can use to determine what type of input it should use for tags (it was not defined in the <code>schema.yml</code>). The standard <code>input_tag</code> is used for this purpose. You can check that the photo module now handles tags properly by adding tags to the test photos. Just make sure you separate the tags with a blank space.</p>
<div style="overflow:hidden;"><a class="beatbox" href="http://i2.sitepoint.com/graphics/image008a.png"><em>1566_fig8 (click to view image)</em><img style="float:left;" src="http://i2.sitepoint.com/graphics/image008a.png" alt="" width="400" height="476" /></a></div>
<p>get From : http://www.sitepoint.com</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/32/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=32&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>

		<media:content url="http://i2.sitepoint.com/graphics/image008a.png" medium="image" />
	</item>
		<item>
		<title>Learn symfony: a Beginner&#8217;s Tutorial (2)</title>
		<link>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-2/</link>
		<comments>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-2/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 06:54:09 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[symfoni]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=30</guid>
		<description><![CDATA[Generating a Site Administration Panel
We&#8217;ll use a great feature of the symfony framework called the administration generator to create a site administration panel. The administration generator uses the relational schema as a guideline to create a data manipulation interface. Our site administrator will need to edit data from the Photo class, so let&#8217;s generate an [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=30&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><h5>Generating a Site Administration Panel</h5>
<p>We&#8217;ll use a great feature of the symfony framework called the administration generator to create a site administration panel. The administration generator uses the relational schema as a guideline to create a data manipulation interface. Our site administrator will need to edit data from the <code>Photo</code> class, so let&#8217;s generate an admin panel for this class:</p>
<p><code>$ <a class="glossary" title="PHP, or Hypertext Preprocessor, is an open source, server-side programming language." href="http://www.sitepoint.com/glossary.php?q=P#term_1">php</a> symfony propel-init-admin frontend photo Photo</code><br />
<span id="more-30"></span><br />
Symfony organizes the pages of a project within a hierarchy of applications and modules. Although this structure adds directories to a project&#8217;s structure, it makes maintenance easier, especially for large sites. So a module contains several pages, an application contains several modules, and a project can contain more than one application. The sandbox that you installed is a symfony project packaged with an empty application called frontend. This means that the command of the above listing reads as: &#8220;Create a site administration in the application frontend, in a module called photo, based on the model class Photo&#8221;. To see what the new module looks like, browse to <code>http://<a class="glossary" title="&quot;Localhost&quot; is an alias for the computer system the user is working on. It's also accessible through the 127.0.0.1 address." href="http://www.sitepoint.com/glossary.php?q=L#term_42">localhost</a>/sf_sandbox/web/frontend_dev.php/photo</code>.</p>
<div style="overflow:hidden;"><a class="beatbox" href="http://i2.sitepoint.com/graphics/image003a.png"><em>1566_fig3 (click to view image)</em><img style="float:left;" src="http://i2.sitepoint.com/graphics/image003a.png" alt="" width="394" height="271" /></a></div>
<p>One of the advantages of a generated administration is that it allows you to add data to your database early in the project &#8212; even before coding. A generated administration consists of two pages that we&#8217;ll call the list view and the edit view. Symfony uses the schema to build tables, forms, and form-handling scripts. Although all the code is generated, you can override it as you like. However, the best way to customize a generated administration is not to write PHP code, but to use the <code>generator.yml</code> file. That&#8217;s a configuration file that controls the generated module, and adding parameters in this file transforms the list and edit views accordingly. Let&#8217;s see an example.</p>
<p>By default, the columns of the list view correspond to the columns defined in the schema. The column that corresponds to the primary key (<code class="ref-term"><a title="Look up the id attribute in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/core-attributes/id">id</a></code> in this example) bears the hyperlink to the Edit view. But the <code class="ref-term"><a title="Look up the id attribute in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/core-attributes/id">id</a></code> column is of no use for an administrator, so we should remove it from the list view. To do so, open the <code>generator.yml</code> file located in <code>apps/frontend/modules/photo/config/</code> and add at the end the following code:</p>
<p><code>generator:<br />
class:              sfPropelAdminGenerator<br />
param:<br />
model_class:      Photo<br />
theme:            default<br />
<strong>list:<br />
display:        [file_path, description, created_at]<br />
object_actions:<br />
_edit:<br />
name:       Edit picture properties</strong></code></p>
<p>Be aware that indentation is meaningful in YAML files, so try to respect the indentation shown here. One important piece of advice is to never use tab characters in YAML files &#8212; always use a double space to indent lines. The display line tells symfony which columns to show in the list, in which order. As for the <code>object_actions</code> key, it manages the buttons that will be shown for each line. The <code>_edit</code> button is predefined, so you don&#8217;t need to worry about the script it calls. We just customized the button&#8217;s name here. To see the result, browse to the <code>photo</code> module again and see how the list view changed.</p>
<div style="overflow:hidden;"><a class="beatbox" href="http://i2.sitepoint.com/graphics/image005.png"><em>1566_fig5 (click to view image)</em><img style="float:left;" src="http://i2.sitepoint.com/graphics/image005.png" alt="" width="400" height="209" /></a></div>
<p>Entering a file path to upload photos is not very useful. The ideal for this photo administration module would be that users would be able to browse their file system to point to a picture file. This is quite easy to do, and requires no code. Modify your <code>generator.yml</code> as follows:</p>
<p><code>generator:<br />
class:              sfPropelAdminGenerator<br />
param:<br />
model_class:      Photo<br />
theme:            default<br />
list:<br />
display:        [file_path, description, created_at]<br />
object_actions:<br />
_edit:<br />
name:       Edit picture properties<br />
<strong>edit:<br />
display:        [file_path, description]<br />
fields:<br />
file_path:<br />
type:       admin_input_file_tag</strong></code></p>
<p>You already know the <code class="ref-term"><a title="Look up the display property in the SitePoint CSS Reference." href="http://reference.sitepoint.com/css/display">display</a></code> key: it controls which fields are displayed in the view. In the Edit view, it controls which fields appear in the form. We got rid of the <code>created_at</code> column in this view for a good reason: symfony handles it on its own. Because of its name, symfony will give to this field the value of the record creation date. If you were to add an <code>updated_at</code> column, symfony would also handle it on its own, updating it every time you change a record.</p>
<p>The second thing to notice in this listing is the <code>fields</code> key, and the fact that the <code>file_path</code> column is set to show an input of type <code>admin_input_file_tag</code>. This tells symfony to use a file input for this column, but also to upload the related file to its <code>web/uploads/</code> directory. Try using the Edit view to add a few pictures to the photo album.</p>
<div style="overflow:hidden;"><a class="beatbox" href="http://i2.sitepoint.com/graphics/image006a.png"><em>1566_fig6 (click to view image)</em><img style="float:left;" src="http://i2.sitepoint.com/graphics/image006a.png" alt="" width="400" height="219" /></a></div>
<p>It would be nice if the module could display the uploaded photos, so you can check whether your uploads succeeded. To do so, we&#8217;ll use a partial column. A partial column is a piece of PHP code that can be used as a column in a generated administration. Here&#8217;s how it works. First, edit the <code>generator.yml</code> to add the <code>_photo</code> column to the display key in both views:</p>
<p><code>generator:<br />
class:              sfPropelAdminGenerator<br />
param:<br />
model_class:      Photo<br />
theme:            default<br />
list:<br />
display:        [_<strong>photo</strong>, description, created_at]<br />
object_actions:<br />
_edit:<br />
name:       Edit picture properties<br />
edit:<br />
display:        [_<strong>photo</strong>, file_path, description]<br />
fields:<br />
file_path:<br />
type:       admin_input_file_tag</code></p>
<p>Symfony recognizes the underscore and, instead of using the methods of the <code>Photo</code> object to get the column value, it tries to include a file called <code>_photo.php</code> in the column. <code>Create _photo.php</code> in the <code>/apps/frontend/modules/photo/templates</code> directory, and within the file place only the following line:</p>
<p><code>&lt;?php echo image_tag('/uploads/'.$photo-&gt;getFilePath()) ?&gt;</code></p>
<p>Before loading this file, symfony puts the current <code>Photo</code> object into the <code>$photo</code> variable. The <code>getFilePath</code> method is among the methods that were automatically generated by symfony based on the <code>schema.yml</code> when you called the <code>propel-build-model</code> command. As you might have guessed, it returns the value of the <code>file_path</code> column that corresponds to the <code>$photo</code> object. Every other column has a corresponding getter and setter method in the generated <code>Photo</code> class. The <code>image_tag</code> function is a symfony helper &#8212; a function that returns <a class="glossary" title="HTML stands for HyperText Markup Language." href="http://www.sitepoint.com/glossary.php?q=H#term_75">HTML</a> code and is meant to be used in templates. This one returns an <code class="ref-term"><a title="Look up the &lt;img&gt; tag in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/img">&lt;img&gt;</a></code> tag, which is just what we want. Its first parameter must be a file path that&#8217;s relative to the <code>web/</code> directory. Check that the images now show up properly by browsing the photo module again.</p>
<div style="overflow:hidden;"><a class="beatbox" href="http://i2.sitepoint.com/graphics/image007.png"><em>1566_fig7 (click to view image)</em><img style="float:left;" src="http://i2.sitepoint.com/graphics/image007.png" alt="" width="400" height="313" /></a></div>
<p>get from : http://www.sitepoint.com</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/30/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=30&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>

		<media:content url="http://i2.sitepoint.com/graphics/image003a.png" medium="image" />

		<media:content url="http://i2.sitepoint.com/graphics/image005.png" medium="image" />

		<media:content url="http://i2.sitepoint.com/graphics/image006a.png" medium="image" />

		<media:content url="http://i2.sitepoint.com/graphics/image007.png" medium="image" />
	</item>
		<item>
		<title>Learn symfony: a Beginner&#8217;s Tutorial (1)</title>
		<link>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-1/</link>
		<comments>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-1/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 06:51:10 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=28</guid>
		<description><![CDATA[With the release of symfony 1.0, it&#8217;s time for those who haven&#8217;t tried it yet to see what&#8217;s inside this beautiful framework. Stable, fully documented, and released under the open-source MIT license, symfony is used by hundreds of web sites, including some very large ones (Yahoo! Bookmarks, with its 20 million-strong user base, is built [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=28&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>With the release of <a href="http://www.symfony-project.com/">symfony</a> 1.0, it&#8217;s time for those who haven&#8217;t tried it yet to see what&#8217;s inside this beautiful framework. Stable, fully documented, and released under the open-source MIT license, symfony is used by hundreds of web sites, including some very large ones (Yahoo! Bookmarks, with its 20 million-strong user base, is built with symfony). If you haven&#8217;t taken the time to look at the introductory screencasts on the symfony project website, this simple tutorial will lead you through the basics. </strong><br />
<span id="more-28"></span><br />
The best way to learn and understand symfony is to use it, so this article will lead you through the creation of a photo album application with this framework. You already know the basic features such an application should offer: the ability to upload photos, to describe and tag them, and the ability for visitors to browse and comment on your photos.</p>
<p>Symfony is a Model-View-Controller (MVC) framework written in <a class="glossary" title="PHP, or Hypertext Preprocessor, is an open source, server-side programming language." href="http://www.sitepoint.com/glossary.php?q=P#term_1">PHP</a> that&#8217;s aimed at building web applications. If you&#8217;re already familiar with the MVC paradigm, you won&#8217;t be surprised by the way symfony organizes scripts. If you aren&#8217;t familiar with MVC, you just need to understand that separating the code into three parts &#8212; the logic code (called the Model), the presentation code (the View), and the request handling code (the Controller) &#8212; is a good way to ensure the maintainability and reusability of code.</p>
<p>Not only is Symfony an MVC implementation in PHP, it also integrates a lot of objects that facilitate the development of web applications &#8212; and integrates them all with a coherent syntax. Smart URLs, code generation, easy templating, internationalization, <a class="glossary" title="Cache, pronounced &quot;cash&quot;, refes to a stored copy of (or pointers to) previously accessed data. " href="http://www.sitepoint.com/glossary.php?q=C#term_21">caching</a>, automated form validation, and <a class="glossary" title="AJAX stands for Asynchronous JavaScript and XML." href="http://www.sitepoint.com/glossary.php?q=A#term_73">Ajax</a>, are among the most appreciated symfony features. Developing an application with symfony is slightly different than building it with any other framework, or without any framework at all. It&#8217;s faster, more productive, and just plain fun. But enough talk, let&#8217;s see some code.</p>
<h5>Initializing an Application</h5>
<p>First, you need to get the symfony files. Fortunately, one of the distributions of the framework comes packaged with an empty application and an SQLite database already configured and working straight out of the box. A working web server with PHP5, and shell access, is all that symfony requires to work.</p>
<p>To install symfony, simply download the <a class="sublink" href="http://www.symfony-project.com/get/sf_sandbox.tgz">sf_sandbox.tgz file</a>.</p>
<p>Unpack it under the web root of your server directory. You can check for yourself that the installation went smoothly by browsing to this URL (note that it may vary depending on your individual setup): <code>http://<a class="glossary" title="&quot;Localhost&quot; is an alias for the computer system the user is working on. It's also accessible through the 127.0.0.1 address." href="http://www.sitepoint.com/glossary.php?q=L#term_42">localhost</a>/sf_sandbox/web/frontend_dev.php</code>.</p>
<div style="overflow:hidden;"><a class="beatbox" href="http://i2.sitepoint.com/graphics/image001.png"><em>1566_fig1 (click to view image)</em><img style="float:left;" src="http://i2.sitepoint.com/graphics/image001.png" alt="" width="400" height="297" /></a></div>
<p>The directory structure of this new project is quite easy to understand:</p>
<p><code>sf_sandbox/  // project directory<br />
apps/      // application files<br />
batch/     // batch process scripts<br />
cache/     // cache files<br />
config/    // configuration files<br />
data/      // data files and scripts<br />
doc/       // documentation files<br />
lib/       // vendor libraries and general purpose scripts<br />
log/       // log files<br />
plugins/   // plugins<br />
test/      // unit and functional tests<br />
web/       // public web directory</code></p>
<p>Many of these directories are empty for a new application; this directory structure can be regarded as a guideline to organize the files of a project effectively. The good news is that as soon as you understand how this directory structure works, you&#8217;ll be able to understand any symfony project: they&#8217;re all structured in the same way.</p>
<p>In most situations, web applications store data in relational databases, so the data structure has to be described as a set of columns grouped in tables that are linked via foreign keys. For the photo album application, the data schema consists of three tables: <code>photo</code>, <code>tag</code>, and <code class="ref-term"><a title="Look up the comment element in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/comment">comment</a></code>. To describe their columns and relationships, we use a simple format called YAML (pronounced &#8220;yamel&#8221;), which looks like this:</p>
<p><code>propel:<br />
photo:<br />
id:          ~<br />
file_path:   varchar(50)<br />
description: longvarchar<br />
created_at:  ~<br />
tag:<br />
photo_id:    ~<br />
name:        varchar(50)<br />
comment:<br />
photo_id:    ~<br />
author:      varchar(50)<br />
body:        varchar(50)<br />
created_at:  ~</code></p>
<p>YAML is an alternative to <a class="glossary" title="eXtensible Markup Language, or XML, is a text markup language designed for the easy sharing of data." href="http://www.sitepoint.com/glossary.php?q=X#term_3">XML</a> for representing data structures. The syntax is pretty simple: structure is shown through indentation, and key/value pairs are separated by colons. The first line represents the name of the database connection for this schema. Propel is the default name in this sandbox &#8212; it refers to the included SQLite database. Propel may sound like a strange name to use as a default, but in fact, the name comes from a third-party component that&#8217;s integrated into symfony.</p>
<p>In this schema, tildes (<code>~</code>) are used instead of the explicit declaration of a data type, because symfony can induce the data type from the name of the key. For instance, the <code class="ref-term"><a title="Look up the id attribute in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/core-attributes/id">id</a></code> column of the <code>photo</code> table is most obviously a primary key, so its type should be integer, and it should be auto-incremented. The <code>created_at</code> name obviously refers to a date, so it should be typed as a timestamp. And the two <code>photo_id</code> columns look very much like foreign keys to the <code class="ref-term"><a title="Look up the id attribute in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/core-attributes/id">id</a></code> column of the photo table.</p>
<p>Symfony knows YAML, and understands this schema exactly as we described it. Open the <code>schema.yml</code> file under the main <code>config/</code> directory of the <code>sf_sandbox directory</code> (<code>sf_sandbox/config/schema.yml</code>), and place the above YAML code in that file. Symfony is now ready to generate the Object-Relational Mapping (ORM) for that schema.</p>
<p>What is Object-Relational Mapping? Well-designed web applications don&#8217;t access data directly using SQL; instead, they use objects to interact with the database. Symfony uses an internal code generator to create the objects that correspond to the photo, tag, and comment tables, based on the object-relational mapping defined in the <code>schema.yml</code> file. To generate those objects, you just need to call one command from the shell. And that&#8217;s our cue to meet the symfony command line interface (CLI)!</p>
<p>Here&#8217;s the symfony script that lies at the root of your project:</p>
<p><code>$ cd sf_sandbox<br />
$ php symfony propel-build-all</code></p>
<p>The <code>propel-build-all</code> command (there&#8217;s that propel name again) generates the model classes under the <code>lib/model/</code> directory (and creates the related tables in the SQLite database of the project). The classes are named <code>Photo</code>, <code>Tag</code>, and <code>Comment</code>, because symfony&#8217;s convention for class names is CamelCase. Like most classes in symfony, the model classes are autoloaded, which means that you can use them without manually &#8220;requiring&#8221; their files in the code (with include or require statements). Just remember to call the clear-cache symfony script each time you add a new class so that the symfony autoloading system can take it into account. Since you just created some classes, go ahead and call that script now:</p>
<p><code>$ php symfony clear-cache</code></p>
<p>We&#8217;ll get back to these classes later, but first let&#8217;s look at the photo publishing interface.</p>
<p>get from : http://www.sitepoint.com</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=28&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2009/01/09/learn-symfony-a-beginners-tutorial-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>

		<media:content url="http://i2.sitepoint.com/graphics/image001.png" medium="image" />
	</item>
		<item>
		<title>Busy</title>
		<link>http://hendraktp.wordpress.com/2008/07/12/busy/</link>
		<comments>http://hendraktp.wordpress.com/2008/07/12/busy/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 16:38:16 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[buzy]]></category>
		<category><![CDATA[Motivation]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=26</guid>
		<description><![CDATA[Author: Stephen Covey
From: 7 Habits of Highly Effective People
Once upon a time a very strong woodcutter ask for a job in a timber merchant, and he got it. The paid was really good and so were the work conditions. For that reason, the woodcutter was determined to do his best.
His boss gave him an axe [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=26&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Author: Stephen Covey<br />
From: 7 Habits of Highly Effective People</p>
<p>Once upon a time a very strong woodcutter ask for a job in a timber merchant, and he got it. The paid was really good and so were the work conditions. For that reason, the woodcutter was determined to do his best.</p>
<p>His boss gave him an axe and showed him the area where he was supposed to work.<span id="more-26"></span></p>
<p>The first day, the woodcutter brought 18 trees</p>
<p>&#8220;Congratulations,&#8221; the boss said. &#8220;Go on that way!&#8221;</p>
<p>Very motivated for the boss words, the woodcutter try harder the next day, but he only could bring 15 trees. The third day he try even harder, but he only could bring 10 trees.Day after day he was bringing less and less trees.</p>
<p>&#8220;I must be losing my strength&#8221;, the woodcutter thought. He went to the boss and apologized, saying that he could not understand what was going on.</p>
<p>&#8220;When was the last time you sharpened your axe?&#8221; the boss asked.</p>
<p>&#8220;Sharpen? I had no time to sharpen my axe. I have been very busy trying to cut trees&#8230;&#8221;</p>
<p>Our lives are like that. We sometimes get so busy that we don&#8217;t take time to sharpen the &#8220;axe&#8221;. In today&#8217;s world, it seems that everyone is busier than ever, but less happy that ever. Why is that ? Could it be that we have forgotten how to stay &#8220;sharp&#8221; ? There&#8217;s nothing wrong with activity and hard work. But we should not get so busy that we neglect the truly important things in life, like our personal life, taking time to get close to our Creator, giving more time for our family, taking time to read etc. We all need time to relax, to think and meditate, to learn and grow. If we don&#8217;t take time to sharpen the &#8220;axe&#8221;, we will become dull and lose our effectiveness. So start from today, think about the ways by which you could do your job more effectively and add a lot of values to it.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/hendraktp.wordpress.com/26/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/hendraktp.wordpress.com/26/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/26/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=26&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2008/07/12/busy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>
	</item>
		<item>
		<title>Flying</title>
		<link>http://hendraktp.wordpress.com/2008/07/12/flying/</link>
		<comments>http://hendraktp.wordpress.com/2008/07/12/flying/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 16:36:14 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[Friendship]]></category>
		<category><![CDATA[flying]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=25</guid>
		<description><![CDATA[Author: Roger Dean Kiser, Sr
Once upon a time there was a little boy who was raised in a orphanage.
The little boy had always wished that he could fly like a bird. It was very difficult for him to understand why he could not fly. There were birds at the zoo that were much bigger than [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=25&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Author: Roger Dean Kiser, Sr<br />
Once upon a time there was a little boy who was raised in a orphanage.</p>
<p>The little boy had always wished that he could fly like a bird. It was very difficult for him to understand why he could not fly. There were birds at the zoo that were much bigger than he, and they could fly.</p>
<p>&#8220;Why can&#8217;t I?&#8221; he thought. &#8220;Is there something wrong with me?&#8221; he wondered.<span id="more-25"></span></p>
<p>There was another little boy who was crippled. He had always wished that he could walk and run like other little boys and girls.</p>
<p>&#8220;Why can&#8217;t I be like them?&#8221; he thought.</p>
<p>One day the little orphan boy who had wanted to fly like a bird ran away from the orphanage. He came upon a park where he saw the little boy who could not walk or run playing in the sandbox.</p>
<p>He ran over to the little boy and asked him if he had ever wanted to fly like a bird.</p>
<p>&#8220;No,&#8221; said the little boy who could not walk or run. &#8220;But I have wondered what it would be like to walk and run like other boys and girls.&#8221;</p>
<p>&#8220;That is very sad.&#8221; said the little boy who wanted to fly. &#8220;Do you think we could be friends?&#8221; he said to the little boy in the sandbox.</p>
<p>&#8220;Sure.&#8221; said the little boy.</p>
<p>The two little boys played for hours. They made sand castles and made really funny sounds with their mouths. Sounds which made them laugh real hard. Then the little boy&#8217;s father came with a wheelchair to pick up his son. The little boy who had always wanted to fly ran over to the boy&#8217;s father and whispered something into his ear.</p>
<p>&#8220;That would be OK,&#8221; said the man.</p>
<p>The little boy who had always wanted to fly like a bird ran over to his new friend and said, &#8220;You are my only friend and I wish that there was something that I could do to make you walk and run like other little boys and girls. But I can&#8217;t. But there is something that I can do for you.&#8221;</p>
<p>The little orphan boy turned around and told his new friend to slide up onto his back. He then began to run across the grass. Faster and faster he ran, carrying the little crippled boy on his back. Faster and harder he ran across the park. Harder and harder he made his legs travel. Soon the wind just whistled across the two little boys&#8217; faces.</p>
<p>The little boy&#8217;s father began to cry as he watched his beautiful little crippled son flapping his arms up and down in the wind, all the while yelling at the top of his voice,</p>
<p>&#8220;I&#8217;M FLYING, DADDY. I&#8217;M FLYING!&#8221;</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/hendraktp.wordpress.com/25/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/hendraktp.wordpress.com/25/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/25/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=25&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2008/07/12/flying/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>
	</item>
		<item>
		<title>Introduction to Image Manipulation in php + GD</title>
		<link>http://hendraktp.wordpress.com/2008/07/09/introduction-to-image-manipulation-in-php-gd/</link>
		<comments>http://hendraktp.wordpress.com/2008/07/09/introduction-to-image-manipulation-in-php-gd/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 15:06:29 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[image manipulation]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=23</guid>
		<description><![CDATA[Introduction
Have you ever been to a website that has some sort of gallery set up which seems to take forever to load? Maybe the server is just slow, or maybe the hapless web designer just used browser tags to resize the image rather than actually sending a smaller image. This is, of course, very stupid, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=23&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><h2>Introduction</h2>
<p>Have you ever been to a website that has some sort of gallery set up which seems to take <em>forever</em> to load? Maybe the server is just slow, or maybe the hapless web designer just used browser tags to resize the image rather than actually sending a smaller image. This is, of course, very stupid, and I will show you how to avoid this stupidity through the power of php.</p>
<p>php (which Word keeps wanting to auto capitalize) is a language designed around what its developer, Rasmus Lerdorf, calls &#8216;the web problem&#8217;. Although it can be run as an interpreted script like other scripting languages, it is designed first and foremost around dynamically generating HTML pages. Combined with a robust set of libraries and one of the best, most comprehensive programming manuals on the web, you can do some totally sweet stuff with it.<span id="more-23"></span></p>
<p>One thing you will need to note is that this tutorial requires php to have been compiled with GD. Most standard distributions of php are, but if you built it yourself then you might want to read up in the php manual to see how to rebuild it with GD support.</p>
<p>Also, I am assuming that you are familiar with the basics of php. You don&#8217;t have to be an expert, but you need to understand at least enough to get by writing simple scripts that pass variables through HTTP get or post. Understanding the basic syntax of the language is also a plus, though I will explain any of the more confusing or advanced features as I go.</p>
<h2>Mise en scène</h2>
<p>In case you&#8217;re curious, the phrase &#8216;mise en scène&#8217; means &#8216;putting in scene&#8217;, and refers to the art of properly setting the stage (and thus the mood) in theater. Not that I would expect <em>you</em> to know that.</p>
<p>ANYway, let&#8217;s go through a high-level overview of what we&#8217;re going to do. I know you&#8217;re itching to get to the actual code, but this is my tutorial, so you have to get through all this pesky text first.</p>
<p>What we&#8217;re going to do is called dynamic image scaling. Let&#8217;s say you&#8217;ve taken a photo of yourself with your fancy new 1.5-terapixel digital camera, and you want to put it on your website to share with your aunt Matilda. But when Tilly (who was always your favorite aunt, even though she&#8217;s getting a bit senile with age) tries to open it, she complains, saying the image is so huge that all she can see is one of your hair follicles, and it takes all day to download. Also, you want to put <em>more</em> pictures on your website, and then show thumbnails to the user for browsing. Thus, you will need three sizes of pictures: thumbnail size, web-viewing size, and download size. Thumbnail-size pictures are designed to be very small and quick to transfer, at the expense of the ability to see details. Web-viewing-size pictures are a good size to fit in a standard browser window and show more detail without going overboard. And download size is the actual file with its true dimensions, suitable for getting professionally printed and mounted on aunt Matilda&#8217;s wall.</p>
<p>You could, of course, manually scale the photo to each of these three sizes. But this leads to several problems. For example:</p>
<ul>
<li>What if you change the size of the thumbnail or the web display picture? You will have to reprocess all the images.</li>
<li>What if you add a new image? You will have to scale it, too.</li>
<li>OK, so really that&#8217;s only two problems, but they&#8217;re still worth paying attention to.</li>
</ul>
<p>But what if there were some way to tell the webpage &#8220;I want an image that&#8217;s x pixels wide and y pixels high, so scale it if you have to&#8221;? Wouldn&#8217;t that be handy? But wait! The HTML image tag does have that ability! So let&#8217;s try this:</p>
<div class="code">
<pre><span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;img</span> <span style="color:#000066;">src</span>=<span style="color:#ff0000;">'/img/myimage.jpg'</span> <span style="color:#000066;">height</span>=<span style="color:#ff0000;">'64'</span> <span style="color:#000066;">width</span>=<span style="color:#ff0000;">'48'</span> /<span style="font-weight:bold;color:#000000;">&gt;</span></span></pre>
</div>
<p>Alright! Now the image is a fraction of its normal size! But it seems to take remarkably long to load for such a small image. Hmm&#8230;the file size looks exactly the same as the original image! How come the original image is three gigabytes and the 3072-pixel version is <em>still</em> three gigabytes? Inconceivable!</p>
<p>The problem with using in-browser scaling is that the server transfers the entire image and the browser alters the dimensions to be whatever the tag says they should be. Thus, while it fixes your scale problem, your size problem still remains. So unless your users want the most detailed thumbnails known to man, it&#8217;s time to ditch pure-HTML scaling and move to the next level: php.</p>
<h2>php: HTML++</h2>
<p>What we want is a php function that will take the name of an image file on your server and some dimensions, and return that image scaled to those dimensions. There are a couple ways to do this, but the way I prefer is to have the php code generate the image directly and send it straight to the browser. Thus, instead of referencing your image in the HTML tag, you will reference a php file and pass your image as a parameter.</p>
<p>If you want to pass parameters in to a php script, there are three ways: get, post, and cookies. Setting a cookie doesn&#8217;t make much sense in this context and you can&#8217;t use post in a url, so let&#8217;s go with get. In php, get values are stored in a special global variable called $_GET, and are referenced using array notation ($_GET['myunnecessarilylongparametername'] will, for example, get the value of myunnecessarilylongparametername, which was passed in via the url). So let&#8217;s go ahead and create a skeleton php file that will take the necessary parameters and process them:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#000000;">&lt;?php</span>
	<span style="color:#0600ff;">$img</span> = <span style="color:#0600ff;">$_GET</span><span style="color:#000000;">[</span><span style="color:#ff0000;">'img'</span><span style="color:#000000;">]</span>;
	<span style="color:#0600ff;">$mult</span> = <span style="color:#0600ff;">$_GET</span><span style="color:#000000;">[</span><span style="color:#ff0000;">'scale'</span><span style="color:#000000;">]</span>;

	<span style="color:#0600ff;">if</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$img</span><span style="color:#000000;">[</span><span style="color:#ff0000;">0</span><span style="color:#000000;">]</span>!=<span style="color:#ff0000;">'/'</span><span style="color:#000000;">)</span><span style="color:#000000;">{</span>
		<span style="color:#0600ff;">$img</span> = <span style="color:#ff0000;">"/$img"</span>;
	<span style="color:#000000;">}</span>
	<span style="color:#0600ff;">$fname</span> = <span style="color:#0600ff;">$_SERVER</span><span style="color:#000000;">[</span><span style="color:#ff0000;">'DOCUMENT_ROOT'</span><span style="color:#000000;">]</span>. <span style="color:#0600ff;">$img</span>;
	<span style="color:#0600ff;">if</span><span style="color:#000000;">(</span><span style="color:#0600ff;">file_exists</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$fname</span><span style="color:#000000;">)</span><span style="color:#000000;">)</span><span style="color:#000000;">{</span>
     	<span style="color:#0600ff;">$pi</span> = <span style="color:#0600ff;">pathinfo</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$fname</span><span style="color:#000000;">)</span>;
     	<span style="color:#0600ff;">$ext</span> = <span style="color:#0600ff;">$pi</span><span style="color:#000000;">[</span><span style="color:#ff0000;">'extension'</span><span style="color:#000000;">]</span>;
		getImage<span style="color:#000000;">(</span><span style="color:#0600ff;">$mult</span>, <span style="color:#0600ff;">$fname</span>, <span style="color:#0600ff;">$ext</span><span style="color:#000000;">)</span>;
	<span style="color:#000000;">}</span>
<span style="font-weight:bold;color:#000000;">?&gt;</span></pre>
</div>
<p>&#8220;But wait a minute!&#8221; you cry. &#8220;There are only two parameters! Don&#8217;t we need three?&#8221; Well, maybe.</p>
<p>The first parameter, img, is of course the image file. The second parameter, which I have confusingly named scale in the url but mult in the code, is not so obvious. I call it the <em>scaling coefficient</em>, because I like to sound smart, but really it&#8217;s just a number that you multiply the width and height by to get the new width and height.</p>
<p>I personally like this method a lot. If you have a lot of images that are different sizes, this will maintain the native aspect ratio for each image while still scaling each one down. It can be a problem if your images are of significantly differing sizes, however; if you want, you can replace the single parameter scale with two parameters that explicitly specify the width and height. I won&#8217;t mind.</p>
<p>Unfortunately, several of the functions we must call&#8211;starting with file_exists&#8211;do not accept relative web paths. This is what the %_SERVER reference is for. This still feels a little like a kludge, but at least it&#8217;s better than hard-coding the path in. If anyone has a suggestion on how to do it better, post in the forums and I&#8217;ll be glad to hear you out! Note that this will work on Windows as well as UNIX-like systems, but that we need to prepend a slash if one does not already exist.</p>
<p>Once we have resolved those crises, the next big question in your mind is undoubtedly the getImage function: what is it? You may have even searched through the php manual looking for it (if so then sorry, since it&#8217;s not there). The answer, of course, is that I am going to tell you how to write that function yourself. Be excited!</p>
<h2>OK, I&#8217;m excited! Let&#8217;s write the getImage function!</h2>
<p>Great! Let&#8217;s go.</p>
<div class="code">
<pre><span style="font-weight:bold;color:#000000;">function</span> getImage<span style="color:#000000;">(</span><span style="color:#0600ff;">$mult</span>, <span style="color:#0600ff;">$name</span>, <span style="color:#0600ff;">$ext</span><span style="color:#000000;">)</span>
<span style="color:#000000;">{</span>
	<span style="color:#0600ff;">$oldSize</span> = <span style="color:#0600ff;">getimagesize</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"$name"</span><span style="color:#000000;">)</span>;
	<span style="color:#0600ff;">$oldx</span>  = <span style="color:#0600ff;">$oldSize</span><span style="color:#000000;">[</span><span style="color:#ff0000;">0</span><span style="color:#000000;">]</span>;
	<span style="color:#0600ff;">$oldy</span>  = <span style="color:#0600ff;">$oldSize</span><span style="color:#000000;">[</span><span style="color:#ff0000;">1</span><span style="color:#000000;">]</span>;
	<span style="color:#0600ff;">$x</span> = <span style="color:#0600ff;">$oldx</span> * <span style="color:#0600ff;">$mult</span>;
	<span style="color:#0600ff;">$y</span> = <span style="color:#0600ff;">$oldy</span> * <span style="color:#0600ff;">$mult</span>;

	<span style="font-style:italic;color:#006600;">//Make sure we're not too insanely huge</span>
	<span style="color:#0600ff;">while</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$x</span> * <span style="color:#0600ff;">$y</span> &lt; <span style="color:#ff0000;">2097152</span><span style="color:#000000;">)</span><span style="color:#000000;">{</span>
		<span style="color:#0600ff;">$mult</span> -= .<span style="color:#ff0000;">25</span>;
		<span style="color:#0600ff;">$x</span> = <span style="color:#0600ff;">$oldx</span> * <span style="color:#0600ff;">$mult</span>;
		<span style="color:#0600ff;">$y</span> = <span style="color:#0600ff;">$oldy</span> * <span style="color:#0600ff;">$mult</span>;
	<span style="color:#000000;">}</span>
<span style="color:#000000;">}</span></pre>
</div>
<p><em>&#8220;WHAT?&#8221;</em>, you scream, flecks of spittle flying from your mouth like debris from an explosion, &#8220;<em>THIS</em> is what I was supposed to be excited about?&#8221; Just calm down and take a few deep breaths. And maybe see a psychiatrist about that anger problem. This isn&#8217;t the whole function, but it&#8217;s a good start.</p>
<p>Let&#8217;s look at that first code block to start off with, shall we? The only thing particularly fancy there is the call to getimagesize. That call gets a two-element array containing the width as element 0 and the height as element 1. It takes a string as a parameter, so I use a double-quoted string and embed the $name variable right inside, which is a handy thing that php lets you do. Then I multiply the original values by the multiplier to get the new values.</p>
<p>Next, as the comment indicates, I make sure that the image is not too large. If you&#8217;re wondering where that number came from, it&#8217;s two megapixels (well, it&#8217;s 1024 * 1024 * 2, which is close enough). This is because the parameters are passed through HTTP get. Thus, someone could just pass in a gigantic value for scale, and all of a sudden all your CPU power and RAM are eaten up generating two-gigabyte images. This is not a substitute for good access control, but it does help close an avenue of attack, which is something all web developers should keep in mind at all times.</p>
<p>Anyway, that was boring. On to the next part of the function; this should go after the above code but before the closing brace for the getImage function:</p>
<div class="code">
<pre><span style="color:#0600ff;">switch</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$ext</span><span style="color:#000000;">)</span><span style="color:#000000;">{</span>
   	<span style="color:#0600ff;">case</span> <span style="color:#ff0000;">'jpg'</span>:
   	<span style="color:#0600ff;">case</span> <span style="color:#ff0000;">'jpeg'</span>:
   		<span style="color:#0600ff;">$src</span> = imageCreateFromJPEG<span style="color:#000000;">(</span><span style="color:#ff0000;">"$name"</span><span style="color:#000000;">)</span>;
   		<span style="color:#0600ff;">header</span><span style="color:#000000;">(</span><span style="color:#ff0000;">'Content-type: image/jpeg'</span><span style="color:#000000;">)</span>;
   		<span style="color:#0600ff;">break</span>;
   	<span style="color:#0600ff;">case</span> <span style="color:#ff0000;">'png'</span>:
   		<span style="color:#0600ff;">$src</span> = imageCreateFromPNG<span style="color:#000000;">(</span><span style="color:#ff0000;">"$name"</span><span style="color:#000000;">)</span>;
   		<span style="color:#0600ff;">header</span><span style="color:#000000;">(</span><span style="color:#ff0000;">'Content-type: image/png'</span><span style="color:#000000;">)</span>;
   		<span style="color:#0600ff;">break</span>;
   	<span style="color:#0600ff;">case</span> <span style="color:#ff0000;">'gif'</span>:
   		<span style="color:#0600ff;">$src</span> = imageCreateFromGIF<span style="color:#000000;">(</span><span style="color:#ff0000;">"$name"</span><span style="color:#000000;">)</span>;
   		<span style="color:#0600ff;">header</span><span style="color:#000000;">(</span><span style="color:#ff0000;">'Content-type: image/gif'</span><span style="color:#000000;">)</span>;
   		<span style="color:#0600ff;">break</span>;
   	<span style="font-weight:bold;color:#000000;">default</span>:
   		<span style="font-style:italic;color:#006600;">//We don't know what it is, so die</span>
		<span style="color:#0600ff;">die</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"Unrecognized file type: $ext"</span><span style="color:#000000;">)</span>;
<span style="color:#000000;">}</span>
<span style="color:#0600ff;">if</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$src</span>===<span style="font-weight:bold;color:#000000;">false</span><span style="color:#000000;">)</span><span style="color:#000000;">{</span>
	<span style="color:#0600ff;">return</span> <span style="font-weight:bold;color:#000000;">null</span>;
<span style="color:#000000;">}</span></pre>
</div>
<p>First, the header function. As you hopefully know, HTTP messages contain header information that tells the browser information about what it&#8217;s getting. Those of you on Windows are no doubt so used to the system using the file extension to determine file type that this might be a little shocking, but it&#8217;s what allows us to have a file with a .php extension that generates an image. The header command sends header information to the browser, and in this case it is sending metadata about the file which will subsequently arrive. Note that <em>we</em> still depend on the file type, so make sure you get it right.</p>
<p>The second item is the imageCreateFrom* functions. It takes an image on disk, reads it in, and stores a pointer to it in memory. That&#8217;s what the $src variable holds. If this were a statically-typed language then we would have to screw around with polymorphism and other big words, or maybe byte arrays, but php is content to let us assign any old thing to a variable. Yay for php!</p>
<p>Finally, I use not one, not two, but <em>three</em> equals signs in the trailing if statement. A single equal sign (a = b) means &#8220;set a equal to b&#8221;. A double equal sign (a == b) means &#8220;the contents of a are equivalent to the contents of b&#8221;. This is tricky. Due to the aforementioned dynamic typing of php, you never really know what type a variable has. Thus, php is pretty liberal about what is equal to what. For example, &#8216;4&#8242; (a string) is equal to 4 (a number). Try it out! Also, false is equal to 0. This means that if a function returns 0 and you compare it to false, you will get a, no pun intended, false positive. The triple-equals can be read as &#8220;a is identical to b&#8221;. One handy thing that php has over many other languages is that false and zero are different things. You just have to use the right comparison operator.</p>
<p>OK, assuming I haven&#8217;t bored you to death talking about operators and degrees of equality, let&#8217;s finish this baby up!</p>
<div class="code">
<pre><span style="color:#0600ff;">$dest</span> = imagecreatetruecolor<span style="color:#000000;">(</span><span style="color:#0600ff;">$x</span>, <span style="color:#0600ff;">$y</span><span style="color:#000000;">)</span>;

imagecopyresampled<span style="color:#000000;">(</span><span style="color:#0600ff;">$dest</span>, <span style="color:#0600ff;">$src</span>,
                   <span style="color:#ff0000;">0</span>, <span style="color:#ff0000;">0</span>, <span style="color:#ff0000;">0</span>, <span style="color:#ff0000;">0</span>,
                   <span style="color:#0600ff;">$x</span>, <span style="color:#0600ff;">$y</span>, <span style="color:#0600ff;">$oldx</span>, <span style="color:#0600ff;">$oldy</span><span style="color:#000000;">)</span>;

<span style="color:#0600ff;">switch</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$ext</span><span style="color:#000000;">)</span><span style="color:#000000;">{</span>
	<span style="color:#0600ff;">case</span> <span style="color:#ff0000;">'png'</span>:
	   	imagepng<span style="color:#000000;">(</span><span style="color:#0600ff;">$dest</span><span style="color:#000000;">)</span>;
	   	<span style="color:#0600ff;">break</span>;
	<span style="color:#0600ff;">case</span> <span style="color:#ff0000;">'gif'</span>:
	   	imagegif<span style="color:#000000;">(</span><span style="color:#0600ff;">$dest</span><span style="color:#000000;">)</span>;
	   	<span style="color:#0600ff;">break</span>;
	<span style="color:#0600ff;">case</span> <span style="color:#ff0000;">'jpg'</span>:
	<span style="color:#0600ff;">case</span> <span style="color:#ff0000;">'jpeg'</span>:
	   	imagejpeg<span style="color:#000000;">(</span><span style="color:#0600ff;">$dest</span><span style="color:#000000;">)</span>;
	   	<span style="color:#0600ff;">break</span>;
<span style="color:#000000;">}</span></pre>
</div>
<p>All of this still belongs in front of the closing function brace (if you&#8217;ve lost track of your braces then see your dentist, or check out the full source, which is available as a download). There are, again, three things going on here, so we shall examine them:</p>
<p>First is imagecreatetruecolor. Besides being in all lower case and somewhat difficult to read, it also creates a new image of the given dimensions. We are starting with a blank canvas the exact length and width of our resized image.</p>
<p>Next, we say imagecopyresampled. This particular function, which takes a zillion parameters, copies an image to another image, resampling/resizing as necessary. I guess you could have figured that out from the name. Anyway, the parameters let you copy just parts of the image, but of course we want them all.</p>
<p>Finally, we use the image* commands. imagepng, for example, sends a png image to the browser. We don&#8217;t want any extra stuff being sent, so the function (and thus the script) ends right after this.</p>
<h2>That&#8217;s it!</h2>
<p>What, you thought there was something else coming? Well, nope, this one was pretty easy. What, you want to know how to <em>use</em> this script? Man, do I have to do everything for you? Well, in this case it&#8217;s pretty easy.</p>
<div class="code">
<pre><span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;img</span> <span style="color:#000066;">src</span>=<span style="color:#ff0000;">'/display.php?img=/img/myimage.jpg&amp;scale=.5'</span> /<span style="font-weight:bold;color:#000000;">&gt;</span></span></pre>
</div>
<p>And there you go. If you want to know why the &amp; instead of just a straight-up ampersand, well, ask the W3C. Apparently they like that kind of thing.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/hendraktp.wordpress.com/23/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/hendraktp.wordpress.com/23/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/23/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=23&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2008/07/09/introduction-to-image-manipulation-in-php-gd/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>
	</item>
		<item>
		<title>Using Ajax Agent and PHP for Auto-Complete (3)</title>
		<link>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-3/</link>
		<comments>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-3/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 14:44:32 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=21</guid>
		<description><![CDATA[Your last task is to use the OnClick() event in the Albums list to return a list of Tracks on an Album.
Remeber this is a 2 part process.
Part 1: Define a a PHP function that search for an Array of Tracks using the Album Name.
Part 2: On the client side:
A: define a JS function that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=21&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Your last task is to use the OnClick() event in the Albums list to return a list of Tracks on an Album.</p>
<p>Remeber this is a 2 part process.</p>
<p>Part 1: Define a a PHP function that search for an Array of Tracks using the Album Name.</p>
<p>Part 2: On the client side:<br />
A: define a JS function that invokes the agent.call function and passes it the Album Name.<br />
B: Define an Callback function that handles the response from the server-side PHP function and then binds it to an html control.</p>
<p>It&#8217;s very easy to do so you should give it a shot before peaking at the source code.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/hendraktp.wordpress.com/21/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/hendraktp.wordpress.com/21/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/21/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=21&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>
	</item>
		<item>
		<title>Using Ajax Agent and PHP for Auto-Complete (2)</title>
		<link>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-2/</link>
		<comments>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-2/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 14:42:46 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=20</guid>
		<description><![CDATA[This next part is some very cool stuff. What we are going to do is select an item from the SelectBox which will return a list of Albums by the selected Artist. Since the list of Albums is being held in a server-side PHP Array getting the data back requires a round-trip to the server. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=20&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This next part is some very cool stuff. What we are going to do is select an item from the SelectBox which will return a list of Albums by the selected Artist. Since the list of Albums is being held in a server-side PHP Array getting the data back requires a round-trip to the server. In any normal case this is done in a Form Post which casues a page refresh but we are going to use Ajax to fire-off the server-side request for the data and avoid refreshing the page all together. The Get Albums task is made up of 2 parts: a server-side PHP function that searchs for the Albums and a client-side Ajax function that invokes the server-side function and hadles the response.The PHP function GetAlbumByArtist works like the GetArtist PHP function but instead of a regex we&#8217;ll just use a string comparison usiug the Artist Name.<span id="more-20"></span></p>
<p>PHP:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#000000;">function</span> GetAlbumByArtist<span style="color:#000000;">(</span> <span style="color:#0600ff;">$text</span> <span style="color:#000000;">)</span>
<span style="color:#000000;">{</span>
<span style="color:#0600ff;">include</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"dbconn.inc.php"</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$strSQL</span> = <span style="color:#ff0000;">"SELECT albums.album_name FROM albums INNER JOIN artists ON
albums.artist_id = artists.artist_id where artists.artist_name = '$text'"</span>;
<span style="color:#0600ff;">$db</span> = <span style="color:#0600ff;">mysql_connect</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$dbHost</span>, <span style="color:#0600ff;">$dbUser</span>,<span style="color:#0600ff;">$dbPwd</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">mysql_select_db</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$dbName</span>,<span style="color:#0600ff;">$db</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$result</span> = <span style="color:#0600ff;">mysql_query</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$strSQL</span>,<span style="color:#0600ff;">$db</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$num</span> = <span style="color:#0600ff;">mysql_num_rows</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$result</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$listArray</span> = <span style="color:#0600ff;">array</span><span style="color:#000000;">(</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$i</span>=<span style="color:#ff0000;">0</span>;
<span style="color:#0600ff;">while</span> <span style="color:#000000;">(</span><span style="color:#0600ff;">$i</span>&lt;<span style="color:#0600ff;">$num</span><span style="color:#000000;">)</span>
<span style="color:#000000;">{</span>
<span style="color:#0600ff;">$listArray</span><span style="color:#000000;">[</span><span style="color:#0600ff;">$i</span><span style="color:#000000;">]</span> = <span style="color:#0600ff;">mysql_result</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$result</span>,<span style="color:#0600ff;">$i</span>,<span style="color:#ff0000;">"album_name"</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$i</span>++;
<span style="color:#000000;">}</span>
<span style="color:#0600ff;">asort</span><span style="color:#000000;">(</span> <span style="color:#0600ff;">$listArray</span> <span style="color:#000000;">)</span>;
<span style="color:#0600ff;">mysql_close</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$db</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">return</span> <span style="color:#0600ff;">array_values</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$listArray</span><span style="color:#000000;">)</span>;
<span style="color:#000000;">}</span></pre>
</div>
<p>In the FORM we created a SelectBox that has an OnClick(&#8220;MatchSelected(this)&#8221;) function defined. The MatchSelected function calls the GetAlbumByArtist and passes it the selected Artist Name. GetAlbumByArtist then invokes the agent.call method which has the Server-side PHP function defined, the client-side callback handler and the parameters we want to send to the PHP function. The agent.call has an optional first parameter of URL which can be used if your PHP code in in a seprate file.</p>
<p>For example:</p>
<p>Javascript:</p>
<div class="code">
<pre>agent.<span style="color:#0600ff;">call</span><span style="color:#000000;">(</span><span style="color:#ff0000;">'musicSearch.php'</span>,<span style="color:#ff0000;">'GetAlbumByArtist'</span>,<span style="color:#ff0000;">'GetAlbumByArtist_Callback'</span>,val<span style="color:#000000;">)</span>;</pre>
</div>
<p>If you use a seperate PHP file you&#8217;ll need to be sure to add the following lines to the end of the file:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#000000;">&lt;?php</span>
<span style="color:#0600ff;">include_once</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"agent.php"</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$agent</span>-&gt;<span style="color:#0600ff;">init</span><span style="color:#000000;">(</span><span style="color:#000000;">)</span>;
<span style="font-weight:bold;color:#000000;">?&gt;</span></pre>
</div>
<p>First we add the GetAlbumByArtist:</p>
<p>Javascript:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#0600ff;">function</span> GetAlbumByArtist<span style="color:#000000;">(</span>val<span style="color:#000000;">)</span> <span style="color:#000000;">{</span>
agent.<span style="color:#0600ff;">call</span><span style="color:#000000;">(</span><span style="color:#ff0000;">''</span>,<span style="color:#ff0000;">'GetAlbumByArtist'</span>,<span style="color:#ff0000;">'GetAlbumByArtist_Callback'</span>,val<span style="color:#000000;">)</span>;
<span style="color:#000000;">}</span></pre>
</div>
<p>The we add the the call back function but this time instead of placing our results in a Select Box we will be creating an Unordered list and placing the list inside a DIV.</p>
<p>Javascript:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#0600ff;">function</span> GetAlbumByArtist_Callback<span style="color:#000000;">(</span>obj<span style="color:#000000;">)</span> <span style="color:#000000;">{</span>

<span style="font-weight:bold;color:#0600ff;">var</span> htmlOutput = document.<span style="color:#0600ff;">getElementById</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"htmlOutput"</span><span style="color:#000000;">)</span>;
<span style="font-weight:bold;color:#0600ff;">var</span> html = <span style="color:#000000;">[</span><span style="color:#000000;">]</span>;
<span style="font-weight:bold;color:#0600ff;">for</span> <span style="color:#000000;">(</span><span style="font-weight:bold;color:#0600ff;">var</span> i <span style="font-weight:bold;color:#0600ff;">in</span> obj<span style="color:#000000;">)</span><span style="color:#000000;">{</span>
html<span style="color:#000000;">[</span>html.<span style="color:#0600ff;">length</span><span style="color:#000000;">]</span> = <span style="color:#ff0000;">'&lt;li&gt;&lt;a href=<span style="font-weight:bold;color:#000099;">\"</span>#<span style="font-weight:bold;color:#000099;">\"</span>
onclick="GetTracksByAlbum(<span style="font-weight:bold;color:#000099;">\'</span>'</span>+obj<span style="color:#000000;">[</span>i<span style="color:#000000;">]</span>+<span style="color:#ff0000;">'<span style="font-weight:bold;color:#000099;">\'</span>)<span style="font-weight:bold;color:#000099;">\"</span>&gt;'</span> + obj<span style="color:#000000;">[</span>i<span style="color:#000000;">]</span> + <span style="color:#ff0000;">'&lt;/a&gt;&lt;/li&gt;'</span>;
<span style="color:#000000;">}</span>
document.<span style="color:#0600ff;">getElementById</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"htmlOutput"</span><span style="color:#000000;">)</span>.<span style="color:#0600ff;">innerHTML</span> = <span style="color:#ff0000;">'&lt;ul&gt;'</span>
+html.<span style="color:#0600ff;">join</span><span style="color:#000000;">(</span><span style="color:#ff0000;">''</span><span style="color:#000000;">)</span>+<span style="color:#ff0000;">'&lt;/ul&gt;'</span>;
document.<span style="color:#0600ff;">getElementById</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"htmlOutputTracks"</span><span style="color:#000000;">)</span>.<span style="color:#0600ff;">innerHTML</span> =<span style="color:#ff0000;">''</span>;
<span style="color:#000000;">}</span></pre>
</div>
<p>You can see that in the link that we create has an OnClick() event defined. This will fire off another Ajax function that returns a list of Tracks for a selected Album.</p>
<p>What you should have now is a search box that has an Ajax Auto-Complete function which return a list of Artist and a SelectBox that has a no-post back function which returns a list of Albums.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/hendraktp.wordpress.com/20/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/hendraktp.wordpress.com/20/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/20/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=20&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>
	</item>
		<item>
		<title>Using Ajax Agent and PHP for Auto-Complete (1)</title>
		<link>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-1/</link>
		<comments>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-1/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 14:41:25 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=19</guid>
		<description><![CDATA[Start by creating a new PHP page and placing the agent.php (Ajax Agent) file in the same directory. Open your new PHP page in an editor and start hacking away.
First create the HTML Form controls we will be using:

txtArtists = TextBox to type the ArtistName in.
matches = A SelectBox with an onclick event which will [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=19&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Start by creating a new PHP page and placing the agent.php (<a href="http://www.hemmady.com/ajaxagent">Ajax Agent</a>) file in the same directory. Open your new PHP page in an editor and start hacking away.</p>
<p>First create the HTML Form controls we will be using:</p>
<ol>
<li>txtArtists = TextBox to type the ArtistName in.</li>
<li>matches = A SelectBox with an onclick event which will be used to send the ArtistName to the AlbumSearch method we will be creating.</li>
<li>txtArtistID = Hidden to hold the selected ArtistName (js cannot see the select box because it is hidden?)</li>
<li>htmlOutput = An empty DIV when we will be creating a list of Albums</li>
<li>htmlOutputTracks = An empty DIV when we will be creating a list of Tracks</li>
</ol>
<p><span id="more-19"></span>HTML:</p>
<div class="code">
<pre><span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;form&gt;</span></span>
<span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;input</span> <span style="color:#000066;">name</span>=<span style="color:#ff0000;">"artistName"</span> <span style="color:#000066;">id</span>=<span style="color:#ff0000;">"artistName"</span> <span style="color:#000066;">size</span>=<span style="color:#ff0000;">"20"</span> <span style="color:#000066;">type</span>=<span style="color:#ff0000;">"text"</span>
<span style="color:#000066;">onkeyup</span>=<span style="color:#ff0000;">"GetArtist();return false;"</span> autocomplete=<span style="color:#ff0000;">"off"</span><span style="font-weight:bold;color:#000000;">&gt;</span></span>
<span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;br&gt;</span></span>
<span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;select</span> <span style="color:#000066;">id</span>=<span style="color:#ff0000;">"matches"</span> <span style="color:#000066;">style</span>=<span style="color:#ff0000;">"VISIBILITY: hidden"</span>
<span style="color:#000066;">onclick</span>=<span style="color:#ff0000;">"MatchSelected(this);"</span> <span style="font-weight:bold;color:#000000;">&gt;</span></span><span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;/select&gt;</span></span>

<span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;hr&gt;</span></span>
<span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;div</span> <span style="color:#000066;">id</span>=<span style="color:#ff0000;">"htmlOutput"</span><span style="font-weight:bold;color:#000000;">&gt;</span></span><span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;/div&gt;</span></span>
<span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;hr&gt;</span></span>
<span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;div</span> <span style="color:#000066;">id</span>=<span style="color:#ff0000;">"htmlOutputTracks"</span><span style="font-weight:bold;color:#000000;">&gt;</span></span><span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;/div&gt;</span></span>
<span style="color:#009900;"><span style="font-weight:bold;color:#000000;">&lt;/form&gt;</span></span></pre>
</div>
<p>Now at the top of the page add a new PHP script tag with an include for agent.php and a new $agent object. Any other PHP code that we must be placed before (above) this code.</p>
<p>PHP:</p>
<div class="code">
<pre><span style="font-style:italic;color:#006600;">/* my functions go here
and
here
*/</span>

<span style="color:#0600ff;">include_once</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"agent.php"</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$agent</span>-&gt;<span style="color:#0600ff;"><span style="color:#000000;">(</span></span><span style="color:#000000;">)</span>;</pre>
</div>
<p>Next we&#8217;ll add the first function that search for Artists by name.</p>
<p>GetArtist function works by taking a string parameter and uses it to search for Artists who&#8217;s name begin with it using a Regular Expression. The list of Artists are stored in an Array array and we will use a foreach loop to search the Artis Name. If we find a match we add it to a second $results array and them move on to the next item in the array. Once we have reached the end of the $Artist Array we re-sort the $results Array. Lastly we only want to return a list of Artist Name so we&#8217;ll use the array_values($results) function.</p>
<p>PHP:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#000000;">function</span> GetArtist<span style="color:#000000;">(</span> <span style="color:#0600ff;">$text</span> <span style="color:#000000;">)</span><span style="color:#000000;">{</span>
<span style="color:#0600ff;">include</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"dbconn.inc.php"</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$strSQL</span> = <span style="color:#ff0000;">"SELECT * FROM artists WHERE artist_name LIKE '$text%'"</span>;

<span style="color:#0600ff;">$db</span>= <span style="color:#0600ff;">mysql_connect</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$dbHost</span>, <span style="color:#0600ff;">$dbUser</span>,<span style="color:#0600ff;">$dbPwd</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">mysql_select_db</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$dbName</span>,<span style="color:#0600ff;">$db</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$result</span> = <span style="color:#0600ff;">mysql_query</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$strSQL</span>,<span style="color:#0600ff;">$db</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$num</span> = <span style="color:#0600ff;">mysql_num_rows</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$result</span><span style="color:#000000;">)</span>;

<span style="color:#0600ff;">$listArray</span> = <span style="color:#0600ff;">array</span><span style="color:#000000;">(</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$i</span>=<span style="color:#ff0000;">0</span>;
<span style="color:#0600ff;">while</span> <span style="color:#000000;">(</span><span style="color:#0600ff;">$i</span>&lt;<span style="color:#0600ff;">$num</span><span style="color:#000000;">)</span>
<span style="color:#000000;">{</span>
<span style="color:#0600ff;">$artist_name</span> = <span style="color:#0600ff;">mysql_result</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$result</span>,<span style="color:#0600ff;">$i</span>,<span style="color:#ff0000;">"artist_name"</span><span style="color:#000000;">)</span>;
<span style="color:#0600ff;">$listArray</span><span style="color:#000000;">[</span><span style="color:#0600ff;">$i</span><span style="color:#000000;">]</span> = <span style="color:#0600ff;">$artist_name</span>;
<span style="color:#0600ff;">$i</span>++;

<span style="color:#000000;">}</span>

<span style="color:#0600ff;">asort</span><span style="color:#000000;">(</span> <span style="color:#0600ff;">$listArray</span> <span style="color:#000000;">)</span>;
<span style="color:#0600ff;">mysql_close</span><span style="color:#000000;">(</span><span style="color:#0600ff;">$db</span><span style="color:#000000;">)</span>;

<span style="color:#0600ff;">return</span> <span style="color:#0600ff;">$listArray</span>;

<span style="color:#000000;">}</span></pre>
</div>
<p>So far we have a form and a PHP function now we need to wire up some ajax to make this work.</p>
<p>*There are some visibility issues with JS and the HTML Controls so the &lt;SCRIPT&gt; block needs to be below the form elements.*</p>
<p>We need to create 2 JS functions to get this to work.The first function GetArtist is what we will call from our OnKey Event iun the search text box and the second function is the Callback method we will send our search results to.</p>
<p>In the GetArtist function we are creating a temp variable to get the letters from the search box and then we are using the agent.call function do define the PHP function, the JS Callback and the parameters we are sending.</p>
<p>Javascript:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#0600ff;">var</span> matchList = document.<span style="color:#0600ff;">getElementById</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"matches"</span><span style="color:#000000;">)</span>;

<span style="font-weight:bold;color:#0600ff;">function</span> GetArtist<span style="color:#000000;">(</span><span style="color:#000000;">)</span> <span style="color:#000000;">{</span>
<span style="font-weight:bold;color:#0600ff;">var</span> artistName = document.<span style="color:#0600ff;">getElementById</span><span style="color:#000000;">(</span><span style="color:#ff0000;">'artistName'</span><span style="color:#000000;">)</span>.<span style="color:#0600ff;">value</span>;
agent.<span style="color:#0600ff;">call</span><span style="color:#000000;">(</span><span style="color:#ff0000;">''</span>,<span style="color:#ff0000;">'GetArtist'</span>,<span style="color:#ff0000;">'GetArtist_Callback'</span>,artistName<span style="color:#000000;">)</span>;
<span style="color:#000000;">}</span></pre>
</div>
<p>In the GetArtist_Callback we are setting the Select Box to visible and then giving it a display size which is equal to the number of items returned from the search. Then we loop over the items and add them to the select box.</p>
<p>Javascript:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#0600ff;">function</span> GetArtist_Callback<span style="color:#000000;">(</span>obj<span style="color:#000000;">)</span> <span style="color:#000000;">{</span>
matchList.<span style="color:#0600ff;">style</span>.<span style="color:#0600ff;">visibility</span> = <span style="color:#ff0000;">"visible"</span>;
matchList.<span style="color:#0600ff;">options</span>.<span style="color:#0600ff;">length</span> = <span style="color:#ff0000;">0</span>; <span style="font-style:italic;color:#008800;">//reset the states dropdown</span>
matchList.<span style="color:#0600ff;">size</span> = obj.<span style="color:#0600ff;">length</span>;

<span style="font-weight:bold;color:#0600ff;">for</span> <span style="color:#000000;">(</span><span style="font-weight:bold;color:#0600ff;">var</span> i = <span style="color:#ff0000;">0</span>; i &lt; obj.<span style="color:#0600ff;">length</span>; i++<span style="color:#000000;">)</span>
<span style="color:#000000;">{</span>
matchList.<span style="color:#0600ff;">options</span><span style="color:#000000;">[</span>matchList.<span style="color:#0600ff;">options</span>.<span style="color:#0600ff;">length</span><span style="color:#000000;">]</span> =<span style="font-weight:bold;color:#0600ff;">new</span> Option<span style="color:#000000;">(</span>obj<span style="color:#000000;">[</span>i<span style="color:#000000;">]</span><span style="color:#000000;">)</span>;
<span style="color:#000000;">}</span>
<span style="color:#000000;">}</span></pre>
</div>
<p>And lastly we have the MatchSelected JS function which is called by the OnClick event of the SelectBox:</p>
<p>Javascript:</p>
<div class="code">
<pre><span style="font-weight:bold;color:#0600ff;">function</span> MatchSelected<span style="color:#000000;">(</span>matches<span style="color:#000000;">)</span> <span style="color:#000000;">{</span>
<span style="font-weight:bold;color:#0600ff;">var</span> artistName = document.<span style="color:#0600ff;">getElementById</span><span style="color:#000000;">(</span><span style="color:#ff0000;">"artistName"</span><span style="color:#000000;">)</span>;
artistName.<span style="color:#0600ff;">value</span> = matches.<span style="color:#0600ff;">options</span><span style="color:#000000;">[</span>matches.<span style="color:#0600ff;">selectedIndex</span><span style="color:#000000;">]</span>.<span style="color:#0600ff;">text</span>;
GetAlbumByArtist<span style="color:#000000;">(</span>artistName.<span style="color:#0600ff;">value</span><span style="color:#000000;">)</span>;
<span style="color:#000000;">}</span></pre>
</div>
<p>We will cover this function in the next section but for now just know that it invokes the Ajax function that gets a list of Albums by the selected Artist.</p>
<p>If all has gone well you should be able to start typing in a name and some results should show as a select box. Once you have this part working we will move on to the second function of GetAlbumsByArtist.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/hendraktp.wordpress.com/19/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/hendraktp.wordpress.com/19/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/19/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=19&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2008/07/09/using-ajax-agent-and-php-for-auto-complete-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>
	</item>
		<item>
		<title>A Soldier Story</title>
		<link>http://hendraktp.wordpress.com/2008/07/01/a-soldier-story/</link>
		<comments>http://hendraktp.wordpress.com/2008/07/01/a-soldier-story/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 00:52:26 +0000</pubDate>
		<dc:creator>hendraktp</dc:creator>
				<category><![CDATA[Attitude]]></category>

		<guid isPermaLink="false">http://hendraktp.wordpress.com/?p=18</guid>
		<description><![CDATA[A story is told about a soldier who was finally coming home after having fought in Vietnam. He called his parents from San Francisco.
&#8216;Mom and Dad, I&#8217;m coming home, but I&#8217;ve a favor to ask. I have a friend I&#8217;d like to bring home with me.&#8217;
&#8216;Sure,&#8217; they replied, &#8216;we&#8217;d love to meet him.&#8217;
&#8216;There&#8217;s something you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=18&subd=hendraktp&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><span style="font-family:Verdana,Arial;font-size:xx-small;">A story is told about a soldier who was finally coming home after having fought in Vietnam. He called his parents from San Francisco.</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">&#8216;Mom and Dad, I&#8217;m coming home, but I&#8217;ve a favor to ask. I have a friend I&#8217;d like to bring home with me.&#8217;</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">&#8216;Sure,&#8217; they replied, &#8216;we&#8217;d love to meet him.&#8217;</span></p>
<p><span id="more-18"></span><span style="font-family:Verdana,Arial;font-size:xx-small;">&#8216;There&#8217;s something you should know&#8217; the son continued, &#8216;he was hurt pretty badly in the fighting. He stepped on a land mind and lost an arm and a leg. He has nowhere else to go, and I want him to come live with us.&#8217;</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">&#8216;I&#8217;m sorry to hear that, son. Maybe we can help him find somewhere to live.&#8217;</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">&#8216;No, Mom and Dad, I want him to live with us.&#8217;</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">&#8216;Son,&#8217; said the father, &#8216;you don&#8217;t know what you&#8217;re asking. Someone with such a handicap would be a terrible burden on us. We have our own lives to live, and we can&#8217;t let something like this interfere with our lives. I think you should just come home and forget about this guy. He&#8217;ll find a way to live on his own.&#8217;</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">At that point, the son hung up the phone. The parents heard nothing more from him. A few days later, however, they received a call from the San Francisco police. Their son had died after falling from a building, they were told. The police believed it was suicide.</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">The grief-stricken parents flew to San Francisco and were taken to the city morgue to identify the body of their son. They recognized him, but to their horror they also discovered something they didn&#8217;t know, their son had only one arm and one leg.</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">The parents in this story are like many of us. We find it easy to love those who are good-looking or fun to have around, but we don&#8217;t like people who inconvenience us or make us feel uncomfortable. We would rather stay away from people who aren&#8217;t as healthy, beautiful, or smart as we are.</span></p>
<p><span style="font-family:Verdana,Arial;font-size:xx-small;">Thankfully, there&#8217;s someone who won&#8217;t treat us that way. Someone who loves us with an unconditional love that welcomes us into the forever family, regardless of how messed up we are.</span></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/hendraktp.wordpress.com/18/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/hendraktp.wordpress.com/18/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hendraktp.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hendraktp.wordpress.com/18/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hendraktp.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hendraktp.wordpress.com/18/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hendraktp.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hendraktp.wordpress.com/18/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hendraktp.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hendraktp.wordpress.com/18/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hendraktp.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hendraktp.wordpress.com/18/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hendraktp.wordpress.com&blog=2785732&post=18&subd=hendraktp&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hendraktp.wordpress.com/2008/07/01/a-soldier-story/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">hendraktp</media:title>
		</media:content>
	</item>
	</channel>
</rss>