<?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>JeffreyBarke.net &#187; PHP</title>
	<atom:link href="http://jeffreybarke.net/category/programming/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeffreybarke.net</link>
	<description></description>
	<lastBuildDate>Thu, 26 Aug 2010 00:42:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Using the PHP Fileinfo extension</title>
		<link>http://jeffreybarke.net/2009/02/using-the-php-fileinfo-extension/</link>
		<comments>http://jeffreybarke.net/2009/02/using-the-php-fileinfo-extension/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 04:34:21 +0000</pubDate>
		<dc:creator>Jeffrey Barke</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[fileinfo]]></category>
		<category><![CDATA[php-extensions]]></category>

		<guid isPermaLink="false">http://jeffreybarke.net/?p=693</guid>
		<description><![CDATA[Jeffrey Barke addresses what the Fileinfo PHP module does, why one might want to install it and how to use it. This post includes a wrapper function that &#0034;fixes&#0034; some of the idiosyncrasies with the existing methods/functions.]]></description>
			<content:encoded><![CDATA[<p>In my last post, I described <a href="http://jeffreybarke.net/2009/02/installing-fileinfo-module-on-media-temple/">how to install the Fileinfo <abbr title="PHP Extension Community Library">PECL</abbr> module on a Media Temple (<abbr title="dedicated virtual">dv</abbr>) server</a>, but I didn&#0039;t really talk about what it does, why one might want to install it and how to use it.</p>
<p>The methods/functions in the <a href="http://us.php.net/manual/en/ref.fileinfo.php" rel="external">Fileinfo PHP extension</a> &#0034;try to guess the content type and encoding of a file by looking for certain <em>magic</em> byte sequences at specific positions within the file. While this is not a bullet proof approach, the heuristics used do a very good job.&#0034;<sup><a href="http://jeffreybarke.net/2009/02/using-the-php-fileinfo-extension/#fileinfonote1">1</a></sup> (Note that this module replaces the <a href="http://us.php.net/manual/en/book.mime-magic.php" rel="external">Mimetype</a> module.)</p>
<p><span id="more-693"></span></p>
<p>The primary use I see for Fileinfo (and the reason I installed it last weekend!) is to test the MIME types of uploaded files against an array of allowed MIME types. I intend to use Fileinfo to supplement the standard check against the file type specified in the <code>$_FILES</code> array, since this is known to be unreliable (more on this in a future post!).</p>
<p>The Fileinfo extension is extremely simple to use. It can be implemented in either the object oriented or procedural style of programming, though my code examples will only demonstrate the former. As an object, we only need to worry about the constructor and two methods to test the MIME type; in the procedural style there are three functions to be aware of.</p>
<p>Here is a quick example from the <a href="http://us.php.net/manual/en/function.finfo-open.php" rel="external">PHP manual</a> of how to use Fileinfo in the object oriented style:</p>
<p><code>&lt;?php<br />
$finfo = new finfo(FILEINFO_MIME, &#0039;/usr/share/misc/magic&#0039;); // return mime type ala mimetype extension<br />
if (!$finfo) {<br />
echo &#0039;Opening fileinfo database failed&#0039;;<br />
exit();<br />
}<br />
/* get mime-type for a specific file */<br />
$filename = &#0039;/usr/local/something.txt&#0039;;<br />
echo $finfo->file($filename);<br />
/* close connection */<br />
$finfo->close();<br />
?&gt;</code></p>
<p>The above example should output <code>text/plain</code>, however there are a few &#0034;gotchas&#0034; I&#0039;ll mention after I briefly discuss the various methods.</p>
<p>The Fileinfo constructor takes two optional parameters: a <a href="http://us.php.net/manual/en/fileinfo.constants.php" rel="external">Fileinfo constant</a> and the path to the &#0034;magic&#0034; database file. While the manual states that these are <em>optional</em>, I haven&#0039;t had any luck getting Fileinfo to work on Media Temple without specifying both! The code I use:</p>
<p><code>$finfo = new finfo(FILEINFO_MIME, &#0039;/usr/share/file/magic&#0039;);</code></p>
<p>The first method to know about is <code>file</code>, which is used to get the MIME type of a file. It takes one required and two optional parameters. The required parameter is a string file name:</p>
<p><code>$finfo->file('path/to/file.ext');</code></p>
<p>The second method is <code>close</code>, which supposedly closes the resource created by the constructor.</p>
<p>As you can see, quite simple. However, as I mentioned above, not everything works as the documentation states! I&#0039;m not sure if this is a general problem with the module or simply the version I&#0039;m using (1.0.4 under PHP 5.2.6), but there are two errors:</p>
<ol>
<li>The constructor is supposed to return &#0034;a magic database resource on success or <code>false</code> on failure.&#0034;<sup><a href="http://jeffreybarke.net/2009/02/using-the-php-fileinfo-extension/#fileinfonote2">2</a></sup> In the procedural style it does, but in the object oriented style it always returns an object, so the <code>if (!$finfo) { }</code> condition in the example above always returns <code>true</code>. This is a problem if the path to the magic database file is wrong, because calling the <code>file</code> method without a magic database resource will throw an error.</li>
<li>In both the object oriented and procedural styles, calling the <code>close</code> method triggers a fatal error. It seems the method/function simply isn&#0039;t defined, despite what the documentation claims!</li>
</ol>
<p>To solve these issues and to add a little functionality, I wrote a <a href="http://jeffreybarke.net/code/fileinformation/fileinformation.txt">Fileinfo wrapper class</a> that duplicates (some of) the native Fileinfo functionality. Unfortunately, the class is currently only available for PHP 5 and the documentation is poor (I intend to remedy both this weekend!).</p>
<p>To use this class, include it in your PHP file. The constructor, <code>file</code> and <code>close</code> methods all work similar to Fileinfo, only I provide a property to test for failure and my <code>close</code> method doesn&#0039;t throw a fatal error! I also add a new method, <code>test</code>, that allows one to test a given file against an array of allowable MIME types.</p>
<p>Here&#0039;s a sample of how to use it:</p>
<p><code>&lt;?php<br />
include_once(&#0039;fileinformation.php&#0039;);<br />
$finfo = new finformation(FILEINFO_MIME, &#0039;/usr/share/file/magic&#0039;);<br />
if ($finfo->ready) {<br />
echo &#0039;&lt;p&gt;&#0039; . $finfo->file(&#0039;themechanism-144x60.gif&#0039;) . &#0039;&lt;/p&gt;&#0039;;<br />
if ($finfo->test(&#0039;themechanism-144x60.gif&#0039;, array(&#0039;image/gif&#0039;))) {<br />
echo &#0039;&lt;p&gt;This is a valid file.&lt;/p&gt;&#0039;;<br />
} else {<br />
echo &#0039;&lt;p&gt;This is not a valid file.&lt;/p&gt;&#0039;;<br />
}<br />
}<br />
?&gt;</code></p>
<p>If you have a file named &#0034;themechanism-144&#215;60.gif&#0034; on your server and if it&#0039;s a gif, this should output <code>&lt;p&gt;image/gif&lt;/p&gt;&lt;p&gt;This is a valid file.&lt;/p&gt;</code>, otherwise it will output <code>&lt;p&gt;This is not a valid file&lt;/p&gt;</code>.</p>
<h3>References</h3>
<ol>
<li><a id="fileinfonote1" name="fileinfonote1" href="http://us.php.net/manual/en/intro.fileinfo.php" rel="external">http://us.php.net/manual/en/intro.fileinfo.php</a></li>
<li><a id="fileinfonote2" name="fileinfonote2" href="http://us.php.net/manual/en/function.finfo-open.php" rel="external">http://us.php.net/manual/en/function.finfo-open.php</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jeffreybarke.net/2009/02/using-the-php-fileinfo-extension/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Installing the Fileinfo PECL module on a Media Temple dedicated virtual (dv) server</title>
		<link>http://jeffreybarke.net/2009/02/installing-fileinfo-module-on-media-temple/</link>
		<comments>http://jeffreybarke.net/2009/02/installing-fileinfo-module-on-media-temple/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 21:22:04 +0000</pubDate>
		<dc:creator>Jeffrey Barke</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[fileinfo]]></category>
		<category><![CDATA[media-temple]]></category>
		<category><![CDATA[pecl]]></category>
		<category><![CDATA[php-extensions]]></category>
		<category><![CDATA[php-modules]]></category>

		<guid isPermaLink="false">http://jeffreybarke.net/?p=665</guid>
		<description><![CDATA[This post describes how to install the <a href="http://pecl.php.net/package/Fileinfo" rel="external"><abbr title="PHP Extension Community Library">PECL</abbr> Fileinfo extension</a> on a Media Temple dedicated virtual (dv) 3.5 server. A future post will describe what the Fileinfo extension does and why you might want to install it.]]></description>
			<content:encoded><![CDATA[<p>This post describes how to install the <a href="http://pecl.php.net/package/Fileinfo" rel="external"><abbr title="PHP Extension Community Library">PECL</abbr> Fileinfo extension</a> on a Media Temple dedicated virtual (dv) 3.5 server. A future post will describe what the Fileinfo extension does and why you might want to install it.</p>
<p><span id="more-665"></span></p>
<p>As of PHP 5.3.0, the Fileinfo extension has been enabled by default and is no longer maintained at PECL. However, the Media Temple (dv) 3.5 service only includes PHP 5.2.6, so we&#0039;ll need to manually install it.</p>
<p>Please note that prior to installing Fileinfo, you&#0039;ll need to make sure that root access has been enabled on your (dv) and that the developer tools have been installed. Both of these actions can be completed from the Media Temple AccountCenter. For more information on root access, please review the first two articles in the references/more info section below. The third link is to an article on the developer tools.</p>
<p>Once you&#0039;re sure that you have root access and that the developer tools are installed, <abbr title="secure shell">SSH</abbr> into your (dv). If Media Temple had the PECL binary installed, we could easily install Fileinfo by using the following statement from the command line: <code>pecl install fileinfo</code>.</p>
<p>Since we can&#0039;t, we&#0039;ll need to install Fileinfo from source. From the command line as root, enter the following statements:</p>
<p><code>mkdir /var/pecl-install<br />
cd /var/pecl-install<br />
wget http://pecl.php.net/get/Fileinfo-1.0.4.tgz<br />
tar -zxf Fileinfo-1.0.4.tgz<br />
cd Fileinfo-1.0.4<br />
phpize<br />
./configure<br />
make<br />
make install<br />
cd /var<br />
rm -f -r pecl-install</code></p>
<p>First we download and unpack the extension in our working directory, <code>/var/pecl-install</code>. Next we <code>phpize</code> the contents (ie prepare the build environment for a PHP extension). Once that&#0039;s done, we perform a standard configure and make routine to install the module. The final two commands remove our working directory from the server.</p>
<p>The outcome is that our extension, <code>fileinfo.so</code>, should be created and exist in <code>/usr/lib/php/modules</code>. However, PHP still doesn&#0039;t know about it. To activate the extension we need to add a line to our <code>php.ini</code> file.</p>
<p>From the command line, enter <code>vi /etc/php.ini</code>. Scroll down until you hit the extensions section of the file and then press <code>i</code> to enter vi&#0039;s insert mode. Add <code>extension=fileinfo.so</code> and then press <code>&lt;esc&gt;</code> to exit insert mode and return to command mode. Type <code>:wq&lt;return&gt;</code> to exit vi and save your changes.</p>
<p>The final step to activate the Fileinfo extension is to restart the web server. From the command line enter:</p>
<p><code>/etc/init.d/httpd stop<br />
/etc/init.d/httpd start</code></p>
<p>At this point, if you were to run <code>phpinfo()</code> on your server, you&#0039;d see that fileinfo is listed among the loaded modules, and if you tried to use any of the <a href="http://us.php.net/manual/en/ref.fileinfo.php" rel="external">Fileinfo functions</a>, you&#0039;d find they&#0039;d run without error.</p>
<p>However, if you actually try to use Fileinfo to determine the MIME type of a file, you&#0039;ll discover it still <em>doesn&#0039;t work</em>! The reason why is that Fileinfo depends on a &#0034;magic&#0034; file to determine the MIME type and, on a Media Temple (dv), it cannot access this file without our next (and final) step.</p>
<p>By default, Media Temple restricts PHP from accessing files outside of <code>httpdocs</code> using the <code>open_basedir</code> directive. However, to use Fileinfo, we have to let PHP access the directory that contains the &#0034;magic&#0034; file, in this case <code>/usr/share/file/</code>.</p>
<p>So, from the command line as root, enter (replacing <em>your-domain.com</em> with your actual domain!):</p>
<p><code>cd /var/www/vhosts/<em>your-domain.com</em>/conf/<br />
vi vhost.conf</code></p>
<p>Enter vi&#0039;s insert mode and add the following lines to the empty <code>vhost.conf</code> file:</p>
<p><code>&lt;Directory &#0034;/var/www/vhosts/<em>your-domain.com</em>/httpdocs&#0034;&gt;<br />
php_admin_value open_basedir &#0034;/var/www/vhosts/<em>your-domain.com</em>/httpdocs:/usr/share/file:/tmp&#0034;<br />
&lt;/Directory&gt;</code></p>
<p>Exit vi (saving your changes!) and reconfigure the server to look for the new <code>vhost.conf</code> file by entering:</p>
<p><code>/usr/local/psa/admin/sbin/websrvmng --reconfigure-vhost --vhost-name=<em>your-domain.com</em></code></p>
<p>Restart the web server once again:</p>
<p><code>/etc/init.d/httpd stop<br />
/etc/init.d/httpd start</code></p>
<p>And that&#0039;s it! Fileinfo should be now be successfully installed and activated! For more info on changing the <code>open_basedir</code> configuration, please see the last link in the resources/more info section below.</p>
<h3>References/More info</h3>
<ol>
<li>Media Temple <abbr title="knowledge base">KB</abbr>. <a href="http://kb.mediatemple.net/questions/792/(dv)+An+introduction+to+the+root+user" rel="external">(dv) An introduction to the root user</a></li>
<li>Media Temple KB. <a href="http://kb.mediatemple.net/questions/713/Disabling+SSH+Login+for+root+user" rel="external">Disabling SSH Login for root user</a></li>
<li>Media Temple KB. <a href="http://kb.mediatemple.net/questions/807/(dv)+3.5+Tech+Specs+-+Developer%27s+Tools+package+listing." rel="external">(dv) 3.5 Tech Specs &#8211; Developer&#8217;s Tools package listing.</a></li>
<li>Jelly and Custard. <a href="http://www.jellyandcustard.com/2006/01/19/installing-pecl-modules/" rel="external">Installing PECL Modules</a></li>
<li>Media Temple KB. <a href="http://kb.mediatemple.net/questions/664/How+can+I+edit+php.ini+on+the+(dv)+%26+(dpv)+Dedicated-Virtual+Servers%3F" rel="external">How can I edit php.ini on the (dv) &amp; (dpv) Dedicated-Virtual Servers?</a></li>
<li>Media Temple KB. <a href="http://kb.mediatemple.net/questions/514/(dv)+HOWTO%3A+Enable+PEAR%7B47%7DSet+open_basedir+and+include_path." rel="external">(dv) HOWTO: Enable PEAR/Set open_basedir and include_path.</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jeffreybarke.net/2009/02/installing-fileinfo-module-on-media-temple/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Serving XML and XHTML with PHP</title>
		<link>http://jeffreybarke.net/2007/01/serving-xml-and-xhtml-with-php/</link>
		<comments>http://jeffreybarke.net/2007/01/serving-xml-and-xhtml-with-php/#comments</comments>
		<pubDate>Sun, 21 Jan 2007 16:34:07 +0000</pubDate>
		<dc:creator>Jeffrey Barke</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[mime-type]]></category>
		<category><![CDATA[xhtml]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.schillerlabs.net/?p=149</guid>
		<description><![CDATA[How to serve <abbr title="Extensible Markup Language">XML</abbr> and <abbr title="Extensible Hypertext Markup Language">XHTML</abbr> with PHP.]]></description>
			<content:encoded><![CDATA[<p>In PHP, the <abbr title="Multipurpose Internet Mail Extensions">MIME</abbr> type is set through the <a href="http://us2.php.net/manual/en/function.header.php" rel="external" title="PHP manual: header function"><code>header</code> function</a> (note the header function must be called prior to outputting anything to the browser).</p>
<p>To correctly serve <abbr title="Extensible Markup Language">XML</abbr>, call the header function with the following arguments:</p>
<p><code>header(&#0039;Content-Type: text/xml; charset=utf-8&#0039;);</code></p>
<p>Correctly serving <abbr title="Extensible Hypertext Markup Language">XHTML</abbr> is a bit more complicated. The <code>$_SERVER</code> array contains the server variables, allowing us to interrogate the <code>Accept <abbr title="Hypertext Transfer Protocol">HTTP</abbr></code> header:</p>
<p><code>header(&#0039;Vary: Accept&#0039;);<br />
if (stristr($_SERVER[HTTP_ACCEPT], &#0039;application/xhtml+xml&#0039;)) {<br />
header(&#0039;Content-Type: application/xhtml+xml; charset=utf-8&#0039;);<br />
} else {<br />
header(&#0039;Content-Type: text/html; charset=utf-8&#0039;);<br />
}</code></p>
<p><a href="http://juicystudio.com/article/content-negotiation.php" rel="external" title="MIME Types and Content Negotiation">More information on correctly serving XHTML.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreybarke.net/2007/01/serving-xml-and-xhtml-with-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
