<?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>v-nessa.net &#187; code</title>
	<atom:link href="http://www.v-nessa.net/tag/code/feed" rel="self" type="application/rss+xml" />
	<link>http://www.v-nessa.net</link>
	<description>pink is the new black</description>
	<lastBuildDate>Thu, 31 Mar 2011 21:13:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Using POST Variables Outside the Loop</title>
		<link>http://www.v-nessa.net/2011/02/24/using-post-variables-outside-the-loop</link>
		<comments>http://www.v-nessa.net/2011/02/24/using-post-variables-outside-the-loop#comments</comments>
		<pubDate>Thu, 24 Feb 2011 16:58:35 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=401</guid>
		<description><![CDATA[I was working on this mini contact form the other day where a user basically enters in a bunch of info, the form submits to itself via PHP_SELF, and sends out an email. Oddly enough, once I transferred the form to its permanent home and spent a decent chunk of time trying to figure out [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2011%2F02%2F24%2Fusing-post-variables-outside-the-loop"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2011%2F02%2F24%2Fusing-post-variables-outside-the-loop&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I was working on this mini contact form the other day where a user basically enters in a bunch of info, the form submits to itself via PHP_SELF, and sends out an email. Oddly enough, once I transferred the form to its permanent home and spent a decent chunk of time trying to figure out why it wasn&#8217;t working anymore, I discovered that my developement box still had register_globals enabled from a previous project I was working on.  Doh!</p>
<p>This is part of my loop, which basically just grabs all the $_POST variables and their values to compare them with a previous array ($required) that specifies what values should be present in order for the mailer to determine how much of the form was completed:</p>
<p><code><br />
// Values passed: domain,email<br />
</code><code><br />
foreach($_POST as $name =&gt; $value) {<br />
<code>if(in_array($name,$required)){<br />
if(empty($value) &amp;&amp; value != 0 ){<br />
$complete=0;<br />
}else{<br />
$complete=1;<br />
}<br />
}<br />
}</code></code></p>
<p>(Ignore the fact that WordPress reformats my coding)</p>
<p>The problem is, when I went to use the names of the variables or their values later in the script, I got nothing. This of course would work with register_globals enabled, but since I prefer to work in a more secure environment, a small adjustment was needed in to make those variables available outside the loop:</p>
<p><code><br />
// Values passed: domain,email<br />
</code></p>
<p><code>foreach($_POST as $name =&gt; $value) {<br />
<strong> $$name = trim($value);</strong><br />
if(in_array($name,$required)){<br />
if(empty($value) &amp;&amp; value != 0 ){<br />
$complete=0;<br />
}else{<br />
$complete=1;<br />
}<br />
}<br />
}</code></p>
<p>Pretty simple stuff, eh? All I did here was tell the loop to actually create a variable and value for each $_POST value that was part of the foreach loop. From there, all I had to do was use these values are normal ($domain,$email,etc)</p>
<p><map name='google_ad_map_401_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/401?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_401_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=401&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2011%2F02%2F24%2Fusing-post-variables-outside-the-loop' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=401&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2011/02/24/using-post-variables-outside-the-loop/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Catching SoapClient Errors</title>
		<link>http://www.v-nessa.net/2011/02/01/catching-soapclient-errors</link>
		<comments>http://www.v-nessa.net/2011/02/01/catching-soapclient-errors#comments</comments>
		<pubDate>Tue, 01 Feb 2011 18:03:36 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=393</guid>
		<description><![CDATA[I recently wrote a PHP script that uses SoapClient to connect to a SOAP server to verify username/password credentials for a monitoring system.  The script basically returns the result as a yes or no &#8211; however, as we all know with SOAP, when you hit an error you get a mess of crap that comes [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2011%2F02%2F01%2Fcatching-soapclient-errors"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2011%2F02%2F01%2Fcatching-soapclient-errors&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I recently wrote a PHP script that uses SoapClient to connect to a SOAP server to verify username/password credentials for a monitoring system.  The script basically returns the result as a yes or no &#8211; however, as we all know with SOAP, when you hit an error you get a mess of crap that comes back like this:</p>
<blockquote><p>Uncaught SoapFault exception: [ERROR_BAD_LOGIN] Bad login or password. in /path/to/stuff.php:20</p></blockquote>
<p><code>Stack trace:<br />
#0 [internal function]: SoapClient-&amp;gt;__call('GetAccountByNam...', Array)<br />
#1 /path/to/stuff(20): Utils_SoapClient-&amp;gt;GetAccountByName(Object(SoapVar))<br />
#2 {main}</code></p>
<p>All I need is an error code, and when the SOAP function fails (which is expected if the login credentials are invalid), the script halts and I don&#8217;t get anything.  Luckily, PHP has pretty good exception handling that can tell SOAP to treat output like a test.   For example, the following line of code in the above example passes a username string ($struct) to a SOAP object, and is the line of code that is failing:</p>
<p><code><strong>$result=$accountService-&gt;GetAccountByName(new SoapVar($struct, SOAP_ENC_OBJECT));</strong><br />
$result_username = $result-&gt;UserAccount-&gt;AccountId;<br />
</code></p>
<p>In my case, if the login credentials being tested are incorrect, the value of the $result variable should be empty.  To suppress the ugly SOAP error and only return what I want, I use exceptions:</p>
<p><code>try {<br />
$result=$accountService-&gt;GetAccountByName(new SoapVar($struct, SOAP_ENC_OBJECT));<br />
}<br />
catch(SoapFault $result){<br />
}<br />
catch(Exception $result){<br />
}<br />
</code><br />
Therefore, I can now use the value of $result as intended:</p>
<p><code>if(!empty($result_username)){</code></p>
<p><code>echo "Login OK";<br />
exit(0);<br />
}else{<br />
</code><br />
<code>echo "Login failed";<br />
exit(1);<br />
}</code></p>
<p><map name='google_ad_map_393_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/393?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_393_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=393&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2011%2F02%2F01%2Fcatching-soapclient-errors' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=393&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2011/02/01/catching-soapclient-errors/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using PHP to Extract Image Exif Data</title>
		<link>http://www.v-nessa.net/2010/08/02/using-php-to-extract-image-exif-data</link>
		<comments>http://www.v-nessa.net/2010/08/02/using-php-to-extract-image-exif-data#comments</comments>
		<pubDate>Mon, 02 Aug 2010 12:24:03 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=370</guid>
		<description><![CDATA[Those of us fluent in digital photography have come across the term &#8220;Exif data&#8221; numerous times when it comes to software we use to digitally manipulate photographs. Exif (Exchangeable image file format) data is generally used to identify the properties of the camera that snapped a picture, and usually the software that altered it afterwards. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F08%2F02%2Fusing-php-to-extract-image-exif-data"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F08%2F02%2Fusing-php-to-extract-image-exif-data&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Those of us fluent in digital photography have come across the term &#8220;Exif data&#8221; numerous times when it comes to software we use to digitally manipulate photographs. Exif (Exchangeable image file format) data is generally used to identify the properties of the camera that snapped a picture, and usually the software that altered it afterwards. It can tell you when a picture was taken, what kind of camera took it, as well as the camera&#8217;s model, shutter speed, focal length, and even provide a thumbnail of the image on the camera&#8217;s LCD screen.</p>
<p>Why would you need to extract this information?  If you&#8217;re ever uploaded images to stock photography sites and wonder how they know so much about your pictures, it&#8217;s because they extract the Exif data from your pictures to provide more information on how they were taken. This quick tutorial will demonstrate how to extract Exif data from an image using PHP.</p>
<h2>Enabling the Exif Extension</h2>
<p>The Exif functions for PHP may not be native to your installation, so you can check by viewing your phpinfo file or running &#8220;php -m&#8221; via command line to see a list of modules compiled in. If you don&#8217;t see Exif listed, there are three ways you can enable it depending on how you installed PHP:</p>
<ul>
<li>If you compiled PHP manually, you can re-compile while adding &#8211;enable-exif to the configure line</li>
<li>If PHP is installed via package (rpm/deb), it should already have Exif enabled. If not, you can <a href="http://www.rpmfind.net/linux/rpm2html/search.php?query=exif.so" target="_blank">install an RPM</a> for the extension manually</li>
<li>If you use cPanel, run EasyApache and select the Exif extension from the PHP module list, and recompile</li>
</ul>
<h2>Determining the Image Type</h2>
<p>The <a href="http://www.php.net/manual/en/function.exif-imagetype.php" target="_blank">exif_imagetype</a> function identifies the format of an image, but returns the result as a code.  The <a href="http://www.php.net/manual/en/function.exif-imagetype.php" target="_blank">PHP function reference</a> provides a full list of these return codes, but 1-8 are the most common out of the 16:</p>
<blockquote><p>1: GIF<br />
2: JPEG<br />
3: PNG<br />
4: SWF<br />
5: PSD<br />
6: BMP<br />
7/8: TIFF</p></blockquote>
<p>Here&#8217;s a code example that lists all the desired valid image types in an array and detects the type of image from the specified file, returning the result in &#8220;human readable&#8221; format:</p>
<p><code>&lt;?php<br />
$image = "/path/to/myimage";</code></p>
<p><code>$types = array(<br />
1 =&gt; "GIF",<br />
2 =&gt; "JPEG",<br />
3 =&gt; "PNG",<br />
4 =&gt; "SWF",<br />
5 =&gt; "PSD",<br />
6 =&gt; "BMP",<br />
7 =&gt; "TIFF",<br />
8 =&gt; "TIFF"<br />
);</code></p>
<p><code>$imagetype = exif_imagetype($image);</code></p>
<p><code>if (array_key_exists($imagetype, $types)) {<br />
echo "Image type is: " . $types[$imagetype];<br />
} else {<br />
echo "Not a valid image type";<br />
}<br />
?&gt;</code></p>
<h2>Reading Exif Header Data</h2>
<p>The <a href="http://php.net/exif_read_data" target="_blank">exif_read_data</a> function can be used to extract header data from JPEG and TIFF files:<br />
<code><br />
&lt;?php<br />
$image = "/path/to/myimage";<br />
$exif = exif_read_data($image, 0, true);<br />
foreach ($exif as $key =&gt; $section) {<br />
foreach ($section as $name =&gt; $val) {<br />
echo "$key.$name: $val\n";<br />
}<br />
}<br />
?&gt;<br />
</code></p>
<p>This will return the elements of the array from exif_read_data, which can be very long depending on what information is available for the image. There are seven sections (arrays) of data types:</p>
<ul>
<li>FILE:  Contains the file&#8217;s name, size, timestamp, and what other sections were found (as listed below)</li>
<li>COMPUTED: Contains the actual attributes of the image</li>
<li>ANY_TAG:  Any information that is tagged</li>
<li>IFD0:  Mostly contains information about the camera itself, the software used to edit the image, when it was last modified, etc</li>
<li>THUMBNAIL: Information about the embedded thumbnail for the image</li>
<li>COMMENT: Comment headers for JPEG images</li>
<li>EXIF: Contains more information supplementary to what is in IFD0, mostly related to the camera (includes focal length, zoom ratio, etc)</li>
</ul>
<p>Depending on the information available for the image, you&#8217;ll actually see a lot of data in the output. Say, for instance, you want to only output the IFD0 data to see the information of the camera that took the image:</p>
<p><code>&lt;?php<br />
$image = "image.jpg";<br />
$exif = exif_read_data($image, 0, true);</code><br />
<code>foreach ($exif as $key =&gt; $section) {<br />
foreach ($section as $name =&gt; $val) {<br />
if($key == "IFD0"){<br />
echo "$key.$name: $val\n";<br />
}<br />
}<br />
}<br />
?&gt;<br />
</code><br />
This will output:</p>
<pre>IFD0.ImageWidth: 2592
IFD0.ImageLength: 3872
IFD0.BitsPerSample: Array
IFD0.Compression: 1
IFD0.PhotometricInterpretation: 2
IFD0.Make: NIKON CORPORATION
IFD0.Model: NIKON D80
IFD0.Orientation: 1
IFD0.UndefinedTag:0x0000:
IFD0.XResolution: 72/10000
IFD0.YResolution: 72/1
IFD0.PlanarConfiguration: 1
IFD0.ResolutionUnit: 2
IFD0.Software: Adobe Photoshop CS4 Windows
IFD0.DateTime: 2010:02:06 22:24:09
IFD0.Exif_IFD_Pointer: 304</pre>
<p>Or, you can further narrow down the output by specifying specific values in the $exif multi-dimensional array:</p>
<p><code>&lt;?php<br />
$image = "image.jpg";<br />
$exif = exif_read_data($image, 0, true);<br />
echo "Software: " . $exif['IFD0']['Software'] . "\n";<br />
?&gt;</code></p>
<p>This will return:</p>
<pre>Software: Adobe Photoshop CS4 Windows</pre>
<h2>Using Exif to generate a thumbnail</h2>
<p>As touched on previously, many cameras and image manipulation software will include an embedded thumbnail for an image. You can extract this thumbnail using the <a href="http://php.net/exif_thumbnail" target="_blank">exif_thumbnail</a> function:</p>
<p><code>&lt;?php<br />
$image = "image.jpg";<br />
$thumbnail = exif_thumbnail($image, $width, $height, $type);<br />
echo "&lt;img  width='$width' height='$height' src='data:image;base64,".base64_encode($thumbnail)."'&gt;";<br />
?&gt;</code></p>
<p>Keep in mind that the thumbnail generated here is from the Exif data &#8211; there are other ways to create a thumbnails using many of the <a href="http://us.php.net/manual/en/book.image.php" target="_blank">PHP image</a> functions.</p>
<p><map name='google_ad_map_370_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/370?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_370_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=370&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F08%2F02%2Fusing-php-to-extract-image-exif-data' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=370&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/08/02/using-php-to-extract-image-exif-data/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Simple PHP Script for RBL Checking</title>
		<link>http://www.v-nessa.net/2010/07/16/simple-php-script-for-rbl-checking</link>
		<comments>http://www.v-nessa.net/2010/07/16/simple-php-script-for-rbl-checking#comments</comments>
		<pubDate>Fri, 16 Jul 2010 20:43:59 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=368</guid>
		<description><![CDATA[It&#8217;s useful for ISP&#8217;s and email service providers to run occasional RBL checks against their IPs to know when they are being blacklisted by populate CBL services. I&#8217;ve written a simple script that utilizes the DNSBL pear library to check against common blacklists, when given a list of IPs in a file. First, you need [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F07%2F16%2Fsimple-php-script-for-rbl-checking"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F07%2F16%2Fsimple-php-script-for-rbl-checking&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>It&#8217;s useful for ISP&#8217;s and email service providers to run occasional RBL checks against their IPs to know when they are being blacklisted by populate CBL services. I&#8217;ve written a simple script that utilizes the DNSBL pear library to check against common blacklists, when given a list of IPs in a file.</p>
<p>First, you need to download or install the <a href="http://pear.php.net/package/Net_DNSBL" target="_blank">NET_DNSBL</a> pear module. (Command: <strong>pear install NET_DNSBL</strong>)</p>
<p><code>&lt;?php<br />
require_once('Net/DNSBL.php');</code></p>
<p><code>$iplist = file("/path/to/iplist");</code></p>
<p><code>foreach ($iplist as $ip){</code></p>
<p><code>$dnsbl = new Net_DNSBL();</code></p>
<p><code>$dnsbl-&gt;setBlacklists(array(<br />
'sbl-xbl.spamhaus.org',<br />
'dnsbl.sorbs.net',<br />
'bl.spamcop.net',<br />
'dnsbl-1.uceprotect.net',<br />
'dnsbl-2.uceprotect.net',<br />
'dnsbl-3.uceprotect.net',<br />
'isps.spamblocked.com',<br />
'zen.spamhaus.org'<br />
));</code></p>
<p><code>if ($dnsbl-&gt;isListed($ip)) {</code></p>
<p><code>echo "IP $ip is blacklisted!\n";</code></p>
<p><code>}</code></p>
<p><code>else {<br />
echo "IP $ip not listed\n";<br />
}<br />
}</code></p>
<p><code>?&gt;</code></p>
<p>Of course, this script can be very easily modified to pull IPs from a database, or assign the $ip variable from a GET or POST request (like from a form or API).  Here&#8217;s an exclusive list of some RBL&#8217;s you can check against using this script, by adding them to the array shown:</p>
<blockquote><p>asiaspam.spamblocked.com<br />
bl.deadbeef.com<br />
bl.emailbasura.org<br />
bl.spamcop.net<br />
blackholes.five-ten-sg.com<br />
blacklist.woody.ch<br />
bogons.cymru.com<br />
cbl.abuseat.org    cdl.anti-spam.org.cn<br />
combined.abuse.ch<br />
combined.rbl.msrbl.net<br />
db.wpbl.info<br />
dnsbl-1.uceprotect.net<br />
dnsbl-2.uceprotect.net<br />
dnsbl-3.uceprotect.net<br />
dnsbl.abuse.ch<br />
dnsbl.ahbl.org<br />
dnsbl.cyberlogic.net<br />
dnsbl.inps.de<br />
dnsbl.njabl.org<br />
dnsbl.sorbs.net<br />
drone.abuse.ch<br />
duinv.aupads.org<br />
dul.dnsbl.sorbs.net<br />
dul.ru<br />
dyna.spamrats.com<br />
dynip.rothen.com<br />
eurospam.spamblocked.com<br />
fl.chickenboner.biz<br />
http.dnsbl.sorbs.net<br />
images.rbl.msrbl.net<br />
ips.backscatterer.org<br />
isps.spamblocked.com<br />
ix.dnsbl.manitu.net<br />
korea.services.net<br />
lacnic.spamblocked.com<br />
misc.dnsbl.sorbs.net<br />
noptr.spamrats.com<br />
ohps.dnsbl.net.au<br />
omrs.dnsbl.net.au<br />
orvedb.aupads.org<br />
osps.dnsbl.net.au<br />
osrs.dnsbl.net.au<br />
owfs.dnsbl.net.au<br />
owps.dnsbl.net.au<br />
pbl.spamhaus.org<br />
phishing.rbl.msrbl.net<br />
probes.dnsbl.net.au<br />
proxy.bl.gweep.ca<br />
proxy.block.transip.nl<br />
psbl.surriel.com<br />
rbl.interserver.net<br />
rdts.dnsbl.net.au<br />
relays.bl.gweep.ca<br />
relays.bl.kundenserver.de<br />
relays.nether.net<br />
residential.block.transip.nl<br />
ricn.dnsbl.net.au<br />
rmst.dnsbl.net.au<br />
sbl.spamhaus.org<br />
short.rbl.jp<br />
smtp.dnsbl.sorbs.net<br />
socks.dnsbl.sorbs.net<br />
spam.dnsbl.sorbs.net<br />
spam.rbl.msrbl.net<br />
spam.spamrats.com<br />
spamlist.or.kr<br />
spamrbl.imp.ch<br />
t3direct.dnsbl.net.au<br />
tor.ahbl.org<br />
tor.dnsbl.sectoor.de<br />
torserver.tor.dnsbl.sectoor.de<br />
ubl.lashback.com<br />
ubl.unsubscore.com<br />
virbl.bit.nl<br />
virus.rbl.jp<br />
virus.rbl.msrbl.net<br />
web.dnsbl.sorbs.net<br />
wormrbl.imp.ch<br />
xbl.spamhaus.org<br />
zen.spamhaus.org</p></blockquote>
<p><map name='google_ad_map_368_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/368?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_368_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=368&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F07%2F16%2Fsimple-php-script-for-rbl-checking' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=368&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/07/16/simple-php-script-for-rbl-checking/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Using PHP to Perform DNS Lookups</title>
		<link>http://www.v-nessa.net/2010/06/30/using-php-to-perform-dns-lookups</link>
		<comments>http://www.v-nessa.net/2010/06/30/using-php-to-perform-dns-lookups#comments</comments>
		<pubDate>Wed, 30 Jun 2010 16:29:44 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=365</guid>
		<description><![CDATA[PHP has a couple DNS functions you can use to perform record lookups. Most of us are familiar with the two basic ones &#8211; gethostbyname() and gethostbyaddr(), both of which perform a single function &#8211; returning a hostname or IP address. Here&#8217;s an example of both: &#60;?php $ip = gethostbyname("v-nessa.net"); $host = gethostbyaddr("69.174.114.71"); echo "v-nessa.net [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F06%2F30%2Fusing-php-to-perform-dns-lookups"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F06%2F30%2Fusing-php-to-perform-dns-lookups&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>PHP has a couple DNS functions you can use to perform record lookups.</p>
<p>Most of us are familiar with the two basic ones &#8211; <a href="http://us4.php.net/gethostbyname" target="_blank">gethostbyname()</a> and <a href="http://us4.php.net/gethostbyname" target="_blank">gethostbyaddr()</a>, both of which perform a single function &#8211; returning a hostname or IP address. Here&#8217;s an example of both:</p>
<p><code>&lt;?php</code></p>
<p><code>$ip = gethostbyname("v-nessa.net");<br />
$host = gethostbyaddr("69.174.114.71");</code></p>
<p><code>echo "v-nessa.net has the IP $ip, which reverses to $host";</code><br />
<code>?&gt;</code></p>
<p>The above will return:</p>
<blockquote><p>v-nessa.net has the IP 69.174.114.71, which has a PTR of server.v-nessa.net</p></blockquote>
<p>Similarly to gethostbyname, there&#8217;s <a href="http://us2.php.net/manual/en/function.gethostbynamel.php" target="_blank">gethostbynamel</a> which is useful for hostnames with multiple A records:</p>
<p><code>$ips = gethostbynamel("test.v-nessa.net");<br />
foreach ($ips as $ip =&gt; $value){<br />
echo $value . "\n";<br />
}</code></p>
<p>Will return:</p>
<blockquote><p>69.174.114.71<br />
69.174.115.243</p></blockquote>
<p>A more advanced function is <a href="http://us2.php.net/manual/en/function.dns-get-record.php" target="_blank">dns_get_record</a>, which can pull any valid record for a hostname or IP.  Think about the dig command you use in Unix to find DNS records:</p>
<blockquote><p>nessa@nessa-desktop:~$ dig +short v-nessa.net A<br />
69.174.114.71</p></blockquote>
<p>The dns_get_record function works in a similar way, and can obtain the following DNS record types:</p>
<p><strong><tt>DNS_A</tt></strong>, <strong><tt>DNS_CNAME</tt></strong>,        <strong><tt>DNS_HINFO</tt></strong>, <strong><tt>DNS_MX</tt></strong>,        <strong><tt>DNS_NS</tt></strong>, <strong><tt>DNS_PTR</tt></strong>,        <strong><tt>DNS_SOA</tt></strong>, <strong><tt>DNS_TXT</tt></strong>,        <strong><tt>DNS_AAAA</tt></strong>, <strong><tt>DNS_SRV</tt></strong>,        <strong><tt>DNS_NAPTR</tt></strong>, <strong><tt>DNS_A6</tt></strong>,        <strong><tt>DNS_ALL</tt></strong> or <strong><tt>DNS_ANY</tt></strong>.</p>
<p>The following will give you a similar result:</p>
<p><code>$recs = dns_get_record("v-nessa.net", DNS_A);<br />
print_r($recs);</code></p>
<p>Will return:</p>
<blockquote><p>Array<br />
(<br />
[0] =&gt; Array<br />
(<br />
[host] =&gt; v-nessa.net<br />
[type] =&gt; A<br />
[ip] =&gt; 69.174.114.71<br />
[class] =&gt; IN<br />
[ttl] =&gt; 13728<br />
)<br />
)</p></blockquote>
<p>If you want to obtain multiple DNS types, you can do so by separating the record types with a plus sign:</p>
<p><code>$recs = dns_get_record("v-nessa.net", DNS_A + DNS_MX);</code></p>
<p>Will return:</p>
<blockquote><p>Array<br />
(<br />
[0] =&gt; Array<br />
(<br />
[host] =&gt; v-nessa.net<br />
[type] =&gt; A<br />
[ip] =&gt; 69.174.114.71<br />
[class] =&gt; IN<br />
[ttl] =&gt; 13736<br />
)</p>
<p>[1] =&gt; Array<br />
(<br />
[host] =&gt; v-nessa.net<br />
[type] =&gt; MX<br />
[pri] =&gt; 0<br />
[target] =&gt; v-nessa.net<br />
[class] =&gt; IN<br />
[ttl] =&gt; 14145<br />
)</p>
<p>)</p></blockquote>
<p>You&#8217;ll notice that the output is a double array, so to call individual values you can do either of the following:</p>
<p><code>// will return the IP for array 0 ( A record)</code></p>
<p><code>echo $recs[0]['ip'];</code></p>
<p><code>// will return results for common records</code></p>
<p><code>foreach ($recs as $type =&gt; $value){<br />
echo $value[ip] . "\n";<br />
}</code></p>
<p>Similar to the example above, you can use the DNS_ALL type to show any records available for the hostname, and use a minus sign to exclude certain record types. For example, the below code will return all DNS results for v-nessa.net, but exclude NS records:</p>
<p><code>$recs = dns_get_record("v-nessa.net", DNS_ALL - DNS_NS );</code></p>
<p><code>foreach ($recs as $type =&gt; $value){<br />
echo $value[type] . "\n";<br />
}</code></p>
<p>The following records were returned:</p>
<blockquote><p>A<br />
SOA<br />
MX<br />
TXT</p></blockquote>
<p>Here&#8217;s a more practical example &#8211; a simple PHP DNS lookup script. Say you have a form on your site that allows a user to type in a hostname and select a type of record: A, MX, NS, and TXT. The passed form values are $host and $type, and the below script will accept the variables and output the results according to the record type:</p>
<p>HTML Form:</p>
<p><code>&lt;form action="dns.php" method="POST"&gt;<br />
Hostname: &lt;input type="text" name="host" /&gt;<br />
Type: &lt;select name="type"&gt;<br />
&lt;option value="a"&gt;A&lt;/option&gt;<br />
&lt;option value="mx"&gt;MX&lt;/option&gt;<br />
&lt;option value="ns"&gt;NS&lt;/option&gt;<br />
&lt;option value="txt"&gt;TXT&lt;/option&gt; &lt;/select&gt;<br />
&lt;/form&gt;</code></p>
<p>PHP Script (dns.php):</p>
<pre>&lt;?php

if(!empty($_POST['host']) &amp;&amp; !empty($_POST['type'])){

    // Grab variable from form and define valid types

    $host = $_POST['host'];
    $type = strtoupper($_POST['type');
    $validtypes=array("A","MX","NS","TXT");

    // Check that dns type is defined or allowed

    if(!defined("DNS_" . $type) or !in_array($type,$validtypes)){
       echo "Invalid DNS Type!";
    }else{

       $type = constant("DNS_" . $type);
       $rec = dns_get_record($host, $type);

       // Set result types - can be modified by using available elements from $rec array

       switch($type){
             case DNS_A:
                    $recvals=array("Hostname" =&gt; "host","Type" =&gt; "type", "IP" =&gt; "ip");
                    break;
             case DNS_MX:
                    $recvals=array("Hostname" =&gt; "host","Type" =&gt; "type", "Target" =&gt; "target", "Priority" =&gt; "pri");
                    break;
             case DNS_NS:
                    $recvals=array("Hostname" =&gt; "host","Type" =&gt; "type", "Target" =&gt; "target");
                    break;
             case DNS_TXT:
                    $recvals=array("Hostname" =&gt; "host","Type" =&gt; "type", "Record" =&gt; "txt");
                    break;
        }

      // Output results

      foreach ($rec as $arr =&gt; $num){
             foreach ($recvals as $title =&gt; $value){
                    echo $title . " : " . $num[$value] . "\n";
             }
      }

    }
} else {

     echo "Either hostname or record type is missing";
}</pre>
<p>It&#8217;s of course easy to modify the above code accordingly, and I&#8217;m sure there may be better ways to do this. Feel free to post your own code snippets or comments.</p>
<p><map name='google_ad_map_365_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/365?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_365_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=365&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F06%2F30%2Fusing-php-to-perform-dns-lookups' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=365&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/06/30/using-php-to-perform-dns-lookups/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Command Line PHP: Part 3</title>
		<link>http://www.v-nessa.net/2010/05/25/command-line-php-part-3</link>
		<comments>http://www.v-nessa.net/2010/05/25/command-line-php-part-3#comments</comments>
		<pubDate>Tue, 25 May 2010 14:38:49 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=331</guid>
		<description><![CDATA[This is part third and final part in my PHP command line tutorial series. If you didn&#8217;t see parts 1 and 2: Command Line PHP: Part 1 Command Line PHP: Part 2 More File and Disk Functions Getting Disk Space and Usage The disk_total_size and disk_free_space functions can tell you how much disk space you [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F25%2Fcommand-line-php-part-3"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F25%2Fcommand-line-php-part-3&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>This is part third and final part in my PHP command line tutorial series. If you didn&#8217;t see parts 1 and 2:</p>
<p><a href="http://www.v-nessa.net/2010/05/18/command-line-php-part-1" target="_blank">Command Line PHP: Part 1</a></p>
<p><a href="http://www.v-nessa.net/2010/05/21/command-line-php-part-2" target="_blank">Command Line PHP: Part 2</a></p>
<p><span id="more-331"></span></p>
<h2>More File and Disk Functions</h2>
<h3>Getting Disk Space and Usage</h3>
<p>The <a href="http://us2.php.net/manual/en/function.disk-total-space.php" target="_blank">disk_total_size</a> and <a href="http://us2.php.net/manual/en/function.disk-free-space.php" target="_blank">disk_free_space</a> functions can tell you how much disk space you have and how much is available, respectively:</p>
<p><code>$disksize = disk_total_space("/");<br />
$size = round(number_format($disksize / 1024 / 1024 / 1024, 2));</code></p>
<p><code>$diskfree = disk_free_space("/");<br />
$freesize = round(number_format($diskfree / 1024 / 1024 / 1024, 2));</code></p>
<p><code>echo "Total Disk Size: $size GB\n";<br />
echo "Free Disk Space: $freesize GB";</code></p>
<h3>Finding Files</h3>
<p>A little-known function called glob works sort of like the locate command, in that it will find files that match a certain string, but it only looks in the current folder and is not recursive. For example, the below code will search for all files in the current folder that end with .txt:</p>
<p><code>foreach (glob("*.txt") as $file) {<br />
echo "$file size " . filesize($file) . "\n";<br />
}</code></p>
<p>You can also use something like <a href="http://snippets.dzone.com/posts/show/4147" target="_blank">this example</a> to run as a loop and recursively search through folders.</p>
<h3>Getting File Path Information</h3>
<p>The famous <a href="http://php.net/pathinfo" target="_blank">pathinfo</a> function can give you information about a file on your system:</p>
<p><code>$file = "/etc/php5/cli/php.ini";<br />
if(file_exists($file)){<br />
$info = pathinfo($file);<br />
print_r($info);<br />
}</code></p>
<p>This will print out an array like below:</p>
<p><code>Array<br />
(<br />
[dirname] =&gt; /etc/php5/cli<br />
[basename] =&gt; php.ini<br />
[extension] =&gt; ini<br />
[filename] =&gt; php<br />
)</code></p>
<p>Which you can echo out values to and use in your scripts, for example:</p>
<p><code>$file = "/etc/php5/cli/php.ini";<br />
if(file_exists($file)){<br />
$info = pathinfo($file);<br />
$dir = $info[dirname];<br />
chdir($dir);<br />
echo "Changed directory to" . getcwd();<br />
}</code></p>
<p>There are also similar functions that will provide the same information, individually:</p>
<p><code>$file = "/etc/php5/cli/php.ini";</code><br />
<code><br />
echo "Absolute File Name: " . <strong>realpath</strong>($file) . "\n";<br />
echo "File Name: " . <strong>basename</strong>($file) . "\n";<br />
echo "File path: " . <strong>dirname</strong>($file) . "\n";</code></p>
<p>This will return:</p>
<p><code>Absolute File Name: /etc/php5/cli/php.ini<br />
File Name: php.ini<br />
File path: /etc/php5/cli</code></p>
<h2>Some Random Script Fragments and Functions</h2>
<p><strong>Prompt a user for input:</strong></p>
<p><code><strong>fwrite</strong>(<strong>STDOUT</strong>, "Hello...\nWhat is your name? ");<br />
$name = trim(<strong>fgets</strong>(<strong>STDIN</strong>));<br />
fwrite(STDOUT, "Hello, $name!\n");</code></p>
<p><strong>Print out your username and date:</strong></p>
<p><code>$me = exec('whoami');<br />
echo "Hello, " . $me . " The time is currently " .date("r") . "\n";</code></p>
<p><strong>Generate random strings and passwords:</strong></p>
<p><code>echo <strong>crypt</strong>("mypassword","randomsalt");<br />
echo <strong>md5</strong>("mypassword");</code></p>
<p><strong>Random password, variable length:</strong></p>
<p><code>function randomPass($length) {</code></p>
<p><code>$chars = "abcdefghijkmnopqrstuvwxyz023456789";<br />
srand((double)microtime()*1000000);<br />
$i = 0;<br />
$pass = '' ;</code></p>
<p><code>while ($i &lt;= $length) {<br />
$num = rand() % 33;<br />
$tmp = substr($chars, $num, 1);<br />
$pass = $pass . $tmp;<br />
$i++;<br />
}</code></p>
<p><code>return $pass;<br />
}</code></p>
<p><code>$password = randomPass(10);</code></p>
<p><code>echo "Your random password is: $password";</code></p>
<p><strong>List loaded PHP extensions, check is specific extension is loaded:</strong></p>
<p><code>$extensions = <strong>get_loaded_extensions</strong>();<br />
foreach ($extensions as &amp;$value) {<br />
echo $value . "\n";<br />
}</code></p>
<p><code>if (!<strong>extension_loaded</strong>('gd')) {<br />
echo "GD extension is not loaded";<br />
exit;<br />
}</code></p>
<p><strong>Get Server&#8217;s CPU Load:</strong></p>
<p><code>$load = <strong>sys_getloadavg</strong>();<br />
echo "Current: " . $load[0] . "\n";<br />
echo "5-min: " . $load[1] . "\n";<br />
echo "15-min: " . $load[2] . "\n";</code></p>
<p><strong>Get PHP memory limit and convert to human-readable format:</strong><br />
<code><br />
function convert($size)<br />
{<br />
$unit=array('b','kb','mb','gb','tb','pb');<br />
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];<br />
}<br />
echo convert(memory_get_usage(true));</code></p>
<h2>Some Useful Links/Tutorials</h2>
<p><a href="http://articles.sitepoint.com/article/php-command-line-1" target="_blank">Command Line PHP Tutorial</a><br />
<a title="Simple System Maintenance with PHP-CLI" href="http://www.developertutorials.com/tutorials/php/simple-system-maintenance-with-php-cli-8-01-17/" target="_blank">Simple System Maintenance with PHP-CLI &#8211; Simple System Maintenance with PHP-CLI</a><br />
<a href="http://www.ibm.com/developerworks/opensource/library/os-php-command/index.html" target="_blank">Command Line PHP (IBM)</a><br />
<a href="http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/" target="_blank">Running Daemons in PHP</a><br />
<a href="http://www.if-not-true-then-false.com/2010/php-class-for-coloring-php-command-line-cli-scripts-output-php-output-colorizing-using-bash-shell-colors/" target="_blank">PHP Class for Coloring Command Line Output</a><br />
<a href="http://brian.moonspot.net/php-progress-bar" target="_blank">PHP Command Line Progress Bar</a></p>
<p><map name='google_ad_map_331_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/331?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_331_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=331&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F25%2Fcommand-line-php-part-3' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=331&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/05/25/command-line-php-part-3/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Command Line PHP: Part 2</title>
		<link>http://www.v-nessa.net/2010/05/21/command-line-php-part-2</link>
		<comments>http://www.v-nessa.net/2010/05/21/command-line-php-part-2#comments</comments>
		<pubDate>Fri, 21 May 2010 19:51:25 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=315</guid>
		<description><![CDATA[This post is continuing on my three-part series on command line PHP programming. Missed part one? It&#8217;s right behind you. This part will go over command execution and processes. Command Execution Let&#8217;s start with the basics &#8211; you need to execute an arbitrary command from your PHP script. The exec, shell_exec, passthru, and system functions [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F21%2Fcommand-line-php-part-2"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F21%2Fcommand-line-php-part-2&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>This post is continuing on my three-part series on command line PHP programming. Missed part one? <a href="http://www.v-nessa.net/2010/05/18/command-line-php-part-1" target="_blank">It&#8217;s right behind you</a>. This part will go over command execution and processes.</p>
<p><span id="more-315"></span></p>
<h2>Command Execution</h2>
<p>Let&#8217;s start with the basics &#8211; you need to execute an arbitrary command from your PHP script. The <a href="http://php.net/exec" target="_blank">exec</a>, <a href="http://php.net/shell_exec" target="_blank">shell_exec</a>, <a href="http://php.net/passthru" target="_blank">passthru</a>, and <a href="http://php.net/system" target="_blank">system</a> functions will take care of this for you:</p>
<p><code>exec("/usr/bin/perl /scripts/myscript.pl");</code></p>
<p>will do about the same thing as:</p>
<p><code>system("/usr/bin/perl /scripts/myscript.pl");</code></p>
<p>and</p>
<p><code>shell_exec("/usr/bin/perl /scripts/myscript.pl");</code></p>
<p>So what&#8217;s the difference between the three? A little, but not much. The <a href="http://php.net/system" target="_blank">system</a> function will place the output of the command in an output stream, and display the results whether you tell it to or not. However, it&#8217;s mostly useful to return a yes or no output (in the form of 1, 0, or -1) based on the exit code of the command it was executing. For example, the below script views the /proc/cpuinfo file and outputs a boolean value on whether the command executed:</p>
<p><code>$cpuinfo = system("cat /proc/cpuinfo",$exitcode);<br />
echo $exitcode;<br />
</code><br />
I could then use the boolean value to write an if statement, which is more accurate because I&#8217;m basing the condition on the output of the command itself rather than PHP returning output based on the fact that the command ran, ignoring errors the command may have posted:</p>
<p><code>if($exitcode == 1){<br />
echo "Command executed, but finished with errors";<br />
}</code></p>
<p>The annoying part with the system function though is that it doesn&#8217;t suppress the output of the command itself, but rather sends it directly to the output stream. What if you want to format the output of the command? Then you would use <a href="http://php.net/exec" target="_blank">exec</a>. Below is an example of using the exec command to list the contents of a folder and only output .tar files (using <a href="http://us3.php.net/substr" target="_blank">substr</a> to split the string)</p>
<p><code>$dir = exec("ls .",$output);<br />
foreach ($output as $file)<br />
{<br />
if (strtolower(substr($file, -4)) == '.tar')<br />
echo "$file\n";<br />
}</code></p>
<p>The <a href="http://php.net/shell_exec" target="_blank">shell_exec</a> function allows you to emulate a shell environment. For example, in Linux you have a choice of shells like sh, bash, and ksh that, allow you to do things such as while loops. Using shell_exec is about the same as using the backtick operator, which is generally how you&#8217;re run commands within a Perl script:</p>
<p><code> $output = shell_exec('ls nonexistentfile  2&gt;&amp;1 1&gt; /dev/null');</code></p>
<p>// Does the same as</p>
<p><code>$output = `ls nonexistent file 2&gt;&amp;1 1&gt; /dev/null`l</code></p>
<p>Finally, there&#8217;s the <a href="http://php.net/passthru" target="_blank">passthru</a> function which, when invoked, immediately displays raw ouput of the command being executed. This is intended for browsers, to display binary data such as images, and not necessarily something you&#8217;re use on the command line:</p>
<p><code>header('Content-Type: image/jpg');<br />
passthru('cat /home/user/public_html/images/image.png');<br />
</code></p>
<h3>A Word on Security</h3>
<p>A lot of hosts block command execution functions with the disable_functions setting in php.ini or by using safe mode, and for good reason. A lot of malicious scripts contain code with executable functions, and especially when the value of command or argument is passed as a variable, the results can be destructive. Here&#8217;s an example of a simple script that lists files, that accepts a folder name as a argument:</p>
<p><code>$folder = $argv[1];<br />
exec("ls $folder");</code></p>
<p>We&#8217;d have a security problem if someone passed this as the first argument for $folder:</p>
<p><code>myfolder &amp;&amp; cat /etc/shadow</code></p>
<p>To prevent this, PHP has built-in functions to escape shell arguments and commands, in order to prevent things that could be dangerous:</p>
<p><a href="http://us3.php.net/manual/en/function.escapeshellarg.php" target="_blank">escapeshellarg</a>: Encloses command arguments in single quotes so the argument is passed as one string:</p>
<p><code>exec('ls '.escapeshellarg($folder));</code></p>
<p><a href="http://us3.php.net/manual/en/function.escapeshellcmd.php" target="_blank">escapeshellcmd</a>: Escapes characters that can be used to trick a shell command (like the &amp;&amp; I used to execute cat)</p>
<h2>Process Management &amp; POSIX</h2>
<p>PHP has internal  functions that allow you to manage processes, such as proc_open, proc_close, etc. However, I admit that these tend to be difficult to learn an understand, while posix functions tend to do the job with less hassle.  <a href="http://theserverpages.com/php/manual/en/ref.posix.php" target="_blank">Posix</a> functions are basically system-level functions. In the below script, I&#8217;m going to change the user that the script runs as, view simple information about the process, then start a counter to 1 million but kill it when it reaches 50:</p>
<p><code>$user = posix_getpwnam($vnessa5);<br />
<strong>posix_setuid</strong>($user['uid']);<br />
<strong>posix_setgid</strong>($user['gid']);<br />
$pid = getmypid();</code></p>
<p><code>print_r(<strong>posix_times</strong>());<br />
echo "Script owner: ". <strong>get_current_user</strong>() . "(" . <strong>getmyuid</strong>() . ")\n";<br />
$i=0;<br />
while( $i &lt; 10000000 ){<br />
$i++;<br />
if($i == 50){<br />
echo "Reached 50 - killing!";<br />
<strong>posix_kill</strong>($pid,1);<br />
}<br />
}</code></p>
<p>Similarly, <a href="http://php.net/posix_getpid" target="_blank">posix_getpid</a> and <a href="http://php.net/getmypid" target="_blank">getmypid</a> do the same thing. If the script is a child of another process, you can get the parent process&#8217;s ID with <a href="http://php.net/posix_getppid" target="_blank">posix_getppid</a>. The <a href="http://www.php.net/manual/en/function.getrusage.php" target="_blank">getrusage</a> function can also be used to get more informative information than <a href="http://php.net/posix_times" target="_blank">posix_times</a>. To kill a process, you can see I used <a href="http://php.net/posix_kill" target="_blank">posix_kill</a>, with the process ID and exit code as arguments. This is what happened when I ran the script:</p>
<p><code>Array<br />
(<br />
[ticks] =&gt; 1279790432<br />
[utime] =&gt; 0<br />
[stime] =&gt; 0<br />
[cutime] =&gt; 0<br />
[cstime] =&gt; 0<br />
)<br />
Script owner: root(0)<br />
Reached 50 - killing!Hangup</code></p>
<p>Keep in mind that in most situations, using die() to bail out of a script is more appropriate that using kill. I could rewrite that part of the code to say this instead:</p>
<p><code>die("Reached 50 - Bailing out!);</code></p>
<p>I also found a nice post on running background processes, that you might want to check out <a href="http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/" target="_blank">here</a>.</p>
<h2>Environmental Variables</h2>
<p>Environmental variables tend to be a major part of command line scripting, and is something that is part of PHP as well. Let&#8217;s start with defining an environmental variable with <a href="http://www.php.net/manual/en/function.putenv.php" target="_blank">putenv</a> and retrieving it with <a href="http://php.net/getenv" target="_blank">getenv</a>:</p>
<p><code>putenv("PATH=/fakebin");</code></p>
<p><code>if(!exec("test testdir")){<br />
echo "Could not execute test - path is " . getenv('PATH') ;<br />
}</code></p>
<p>In the above script, I set the $PATH environmental variable to /fakebin, so when I went to execute the &#8216;test&#8217; command (which is a valid Linux command located in /usr/bin/test), the scirpt could not find it since the command was not in /fakebin. This is about the same as setting the $PATH environment in a user&#8217;s .bashrc file. Keep in mind that the variable change lasts as long as the script does &#8211; after the script exits, the environmental variable is returned to its normal state. You can use getenv to pull any environmental variable, similar to the <a href="http://us.php.net/manual/en/reserved.variables.server.php" target="_blank">$_SERVER</a> superglobal.</p>
<p>A nice function for getting information about the current server is <a href="http://php.net/php_uname" target="_blank">php_uname</a>. You use it about the same way as the uname command in Linux:</p>
<p><code>echo php_uname();</code></p>
<p>Will return:</p>
<p><code>Linux server.v-nessa.net 2.6.18-028stab064.7 #1 SMP Wed Aug 26 13:11:07 MSD 2009 x86_64</code></p>
<p>You can further filter the output using the same arguments as uname, for instance, if I only need the server name:</p>
<p><code>echo php_uname(n);</code></p>
<p>PHP 5.3 also introduces a void function called <a href="http://php.net/gethostname" target="_blank">gethostname</a> which will get the hostname of your machine as well.</p>
<h3>The Server Superglobal</h3>
<p>The <a href="http://us.php.net/manual/en/reserved.variables.server.php" target="_blank">$_SERVER superglobal</a> is used to get environmental variables pursuant to the server and environment for the script you are running.  While it&#8217;s normally used in web applications, some of the values can be used for command line scripts as well:</p>
<p><code>echo "This file's name is " . $_SERVER['PHP_SELF'];</code></p>
<p>So you&#8217;ve made it part two of the series. Stay tuned for part three, which will go over specific system-level tasks and functions, with useful code snippets.</p>
<p>Next: <a href="http://www.v-nessa.net/2010/05/25/command-line-php-part-3" target="_blank">Command Line PHP: Part 3</a></p>
<p><map name='google_ad_map_315_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/315?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_315_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=315&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F21%2Fcommand-line-php-part-2' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=315&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/05/21/command-line-php-part-2/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Command Line PHP &#8211; Part 1</title>
		<link>http://www.v-nessa.net/2010/05/18/command-line-php-part-1</link>
		<comments>http://www.v-nessa.net/2010/05/18/command-line-php-part-1#comments</comments>
		<pubDate>Tue, 18 May 2010 18:10:26 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=310</guid>
		<description><![CDATA[PHP isn&#8217;t just for websites anymore. In fact, almost every script I&#8217;ve written to perform server-side functions is either written in bash or PHP, rather than Perl or Python as preferred by my colleagues. It&#8217;s a common belief that PHP isn&#8217;t suited for CLI programming since it&#8217;s mainly used in web applications, but PHP has [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F18%2Fcommand-line-php-part-1"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F18%2Fcommand-line-php-part-1&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>PHP isn&#8217;t just for websites anymore. In fact, almost every script I&#8217;ve written to perform server-side functions is either written in bash or PHP, rather than Perl or Python as preferred by my colleagues. It&#8217;s a common belief that PHP isn&#8217;t suited for CLI programming since it&#8217;s mainly used in web applications, but PHP has over a hundred functions specifically intended for system management.</p>
<p>These kinds of posts can be rather lengthy, so I&#8217;m making this into a series with three parts.  Part 1 will go over the basic filesystem functions. You can find a complete listing <a href="http://us.php.net/manual/en/ref.filesystem.php" target="_blank">here</a>, but I&#8217;ll just go over a few of the more important and common ones.</p>
<p><span id="more-310"></span></p>
<h2><strong>The hashbang</strong></h2>
<p>As with any CLI script, the first line of your PHP script should contain the executable binary for PHP. You can usually find this by running:</p>
<blockquote><p>which php</p></blockquote>
<p>On my server the location is /usr/bin/php, so here&#8217;s the first line of my script:</p>
<p><code>#!/usr/bin/php</code></p>
<p>If you installed PHP in a custom location, you&#8217;ll need to specify that binary instead. You can also specify <a href="http://www.php-cli.com/" target="_blank">command line options</a> like -f, -c, etc.  Then set the permissions of your script to 755 to allow it to execute.</p>
<h2><strong>Accepting arguments with PHP<br />
</strong></h2>
<p>A major part of CLI scripting is the ability to accept arguments. For this, we&#8217;ll write a simple script called asl.php which will parse my name, sex, and location as arguments:</p>
<blockquote><p>[nessa@server] ./test.php 23 female virginia</p></blockquote>
<p>Here&#8217;s the script:</p>
<p><code>#!/usr/bin/php<br />
&lt;?php</code></p>
<p><code>print_r($argv);</code></p>
<p><code>?&gt;</code></p>
<p>The $argv variable is native, and parses as an array. So running this script will produce the following output:</p>
<p><code>Array<br />
(<br />
[0] =&gt; ./asl.php<br />
[1] =&gt; 23<br />
[2] =&gt; female<br />
[3] =&gt; virginia<br />
)</code></p>
<p>So if I only wanted to echo out my age, I can use the following code:</p>
<p><code>echo $argv[1];</code></p>
<p>If you notice, there are four values instead of the three that I passed. As with most scripting languages, PHP considers the filename as the first (0) variable. To remove the first variable, use the <a href="http://us.php.net/array_shift" target="_blank">array_shift</a> function:</p>
<p><code>array_shift($argv);</code></p>
<p>This means now that using value #1 as shown in the example above will output &#8220;female&#8221; instead of 23, making the command line order more correct, but this tends to be confusing for some people since it makes the first value 0 instead of 1. I usually prefer NOT to shift the array unless having the file name in there is going to adversely affect the intended functionality of the script.</p>
<p>From here ( keeping in mind that I&#8217;m not shifting the array anymore), I can assign the arguments to variables and access them from the script:</p>
<p><code>$age = $argv[1];</code><br />
<code>$gender = $argv[2];</code><br />
<code>$location = $argv[3];</code><br />
<code>// echo out the values</code><br />
<code>echo "Hello, I am $age-year-old $gender from $location";</code></p>
<p>In some cases you may want to validate the number of arguments passed, or what they contain. For instance, the below example is requiring that all three variables are passed (however, the code says four, since you have to include the script name as the first &#8220;argument&#8221;, as mentioned before):</p>
<p><code>if ($argc != 4) {<br />
die("Usage: asl.php &lt;age&gt; &lt;gender&gt; &lt;location&gt;\n");<br />
}</code></p>
<p>You can of course specify <em>less than</em> (&lt;) or <em>greater than</em> (&gt;) values operators.  In the next example, I want to make sure that the &#8220;age&#8221; argument is a number:</p>
<p><code>if (!is_numeric($age)){<br />
die("$age is not a number");<br />
}</code></p>
<p>I&#8217;m sure by now you get the idea =)</p>
<h2><strong>PHP File and Folder Management</strong></h2>
<h3>Creating files and folders, and checking their accessibility</h3>
<p>Continuing my above example, I want to end up with a file in /opt/app/users called &#8220;users.txt&#8221; that contains a list of all the output of asl.php. I first need to see if  /opt/app/users exists using the <a href="http://us3.php.net/manual/en/function.is-dir.php" target="_blank">is_dir </a>function, and if it doesn&#8217;t, create it with <a href="http://us3.php.net/manual/en/function.mkdir.php" target="_blank">mkdir</a>, then enter into that directory with <a href="http://us.php.net/manual/en/function.chdir.php" target="_blank">chdir</a>:</p>
<p><code>$dirname = "/opt/app/users;<br />
if(!<strong>is_dir</strong>($dirname)){<br />
<strong>mkdir</strong>($dirname, 0755);<br />
}<br />
<strong>chdir</strong>($dirname);</code></p>
<p>What if /opt/app doesn&#8217;t exist and I need to create the entire structure? The mkdir function has a recursive flag that is set to false by default, but can be enabled as so:</p>
<p><code>$dirstructure = "/opt/app/users";</code></p>
<p><code>if (!mkdir($dirstructure, <strong>0</strong>, true)) {<br />
die('Failed to create folders!');<br />
}</code></p>
<p>Now that the folders are created and verified, I use <a href="http://www.php.net/manual/en/function.file-exists.php" target="_blank">file_exists</a> and <a href="http://www.php.net/manual/en/function.is-readable.php" target="_blank">is_readable</a> to make sure that my users.txt file is there and can be seen. If not, we&#8217;ll use one of the file functions to create it:</p>
<p><code>$cwd = <strong>getcwd</strong>();<br />
$filename = $cwd . "/users.txt;<br />
if(<strong>file_exists</strong>($filename) &amp;&amp; <strong>is_readable</strong>($filename)){<br />
echo "File Exists and is readable";<br />
}else{<br />
<em>echo "File does not exist or is not readable";</em></code><br />
<code>touch($filename);<br />
}</code></p>
<p>If you notice, I added the <a href="http://us.php.net/manual/en/function.getcwd.php" target="_blank">getcwd</a> function to look for a file called users.txt in my current directory. If you need to see whether a file is executable instead of readable, you can simply use the <a href="http://us.php.net/manual/en/function.is-executable.php" target="_blank">is_executable</a> function, or to see if it&#8217;s writable, use <a href="http://us.php.net/manual/en/function.is-writable.php" target="_blank">is_writable</a>:</p>
<p><code>$filename = '/opt/app/users/users.txt';</code></p>
<p><code>if (!is_executable($filename)) {<br />
echo $filename.' is not executable';<br />
}<br />
</code><code>if (!is_writable($filename)) {<br />
echo $filename.' is not writable';<br />
} </code></p>
<p>Note that the result of these commands is based on the user running them. For instance, if the file is owned by the user root and is set to 600 permissions (root read/write only), but the user &#8216;user1&#8242; is running the script, the tests in the above lines of code will fail since that user does not have permissions to the file in question.</p>
<h3>Creating and deleting files</h3>
<p>There are a few functions you can use to create files with PHP. Here are the most commonly used: <a href="http://us2.php.net/manual/en/function.fopen.php" target="_blank">fopen</a>, <a href="http://www.php.net/manual/en/function.file-put-contents.php" target="_blank">file_put_contents</a>, <a href="http://us2.php.net/manual/en/function.touch.php" target="_blank">touch,</a> If you want to delete a file, simply use <a href="http://us2.php.net/unlink" target="_blank">unlink</a>.  In the below example</p>
<p><code>$filename = "/opt/app/users/users.txt";<br />
unlink($filename);<br />
</code></p>
<p>Unlink is not to be confused with the opposite of <a href="http://us2.php.net/manual/en/function.symlink.php" target="_blank">symlink</a>, which creates a symbolic link  (shortbut) between files:</p>
<p><code>symlimk("/opt/app/users/users.txt", "/home/nessa/Desktop/users.txt-shortcut");</code></p>
<p>And <a href="http://php.net/rmdir" target="_blank">rmdir</a> will remove a folder:</p>
<p><code>if (!is_dir('temp')) {<br />
mkdir('temp');<br />
}<br />
rmdir('temp');</code></p>
<h3>Writing to files</h3>
<p>The most common way to write to files is using the fopen function. Using my original example, asl.php is going to write the values of the arguments to a file called users.txt:</p>
<p><code>$filename = "/opt/app/users/users.txt";<br />
$fh = fopen($filename, 'w') or die("can't open file");<br />
$data = $age . $gender . $location;<br />
fwrite($fh, $date);<br />
fclose($fh);</code></p>
<h3>Reading contents of a file</h3>
<p>If you want the script to read the file, you can use a number of function such as <a href="http://us3.php.net/manual/en/function.readfile.php" target="_blank">readfile</a>, <a href="http://us3.php.net/manual/en/function.file-get-contents.php" target="_blank">file_get_contents</a>, <a href="http://us3.php.net/manual/en/function.fopen.php" target="_blank">fopen</a>, <a href="http://us3.php.net/manual/en/function.fread.php" target="_blank">fread</a>, and <a href="http://us3.php.net/manual/en/function.file.php" target="_blank">file</a>. The actual function you would use depends on what you&#8217;re planning on doing with the data. If you simply want to display the contents of the file as a string:</p>
<p><code>$filename = "/opt/app/users/users.txt";<br />
$data = file_get_contents($filename);<br />
echo $data;</code></p>
<p>Will display:</p>
<p><code>23 female virginia</code></p>
<p>If you need a more programmatic way of displaying the data, such as reading each column as a set of values (like if you&#8217;re inserting all this into a database), you&#8217;d use the file() function which will load the contents of the file into an array. Here&#8217;s a simple loop that echoes out each line in the file:</p>
<p><code>$filename = "/opt/app/users/users.txt";<br />
$lines = file($filename);</code></p>
<p><code>foreach ($lines as $line_num =&gt; $line)</code><br />
<code>{<br />
print "{$line_num} : " . $line . "\n";<br />
}</code></p>
<h3>Reading contents of a folder</h3>
<p>You can use the <a href="http://us3.php.net/opendir" target="_blank">opendir</a> function to run a loop and read the contents of a folder:</p>
<p><code>// open the current directory by opendir</code></p>
<p><code>$dirname = "/opt/app";<br />
$handle=opendir($dirname);</code></p>
<p><code>while (($file = readdir($handle))!==false) {<br />
echo "$file \n";<br />
}</code></p>
<p><code>closedir($handle);</code></p>
<h3>Changing permissions and ownership:</h3>
<p>In the above example where I was checking to see if the file was readable, I didn&#8217;t actually specify anything to address permissions &#8211; instead, I just created the file. To change the permissions or ownership of files, you can use the <a href="http://us2.php.net/chmod" target="_blank">chmod</a> and <a href="http://us2.php.net/chown" target="_blank">chown</a> functions.</p>
<p><code>$filename = "/opt/appf/users/users.txt";<br />
$username = posix_getpwuid(fileowner($filename));</code></p>
<p><code>// Get the octal value of permissions<br />
$perms = substr(sprintf('%o', fileperms($filename')), -4);</code></p>
<p><code>if($username[name] != "nessa" &amp;&amp; $perms != "0755" ){<br />
chmod($filename, 0755);<br />
chown($filename, "nessa");<br />
echo "Permissions fixed";<br />
}else{<br />
echo "Permissions are correct";</code></p>
<p>If you want to change the umask (that is, the default permissions of files created by the script), you can use the <a href="http://us.php.net/manual/en/function.umask.php" target="_blank">umask</a> function &#8211; which actually revokes permissions instead of setting them.</p>
<h3>Copying, moving, and renaming</h3>
<p>Say I want to rename the /opt/app folder to /etc/app. I&#8217;d use the <a href="http://us.php.net/manual/en/function.rename.php" target="_blank">rename</a> function as so, validating on whether of not it was renamed successfully:</p>
<p><code>if(!rename("/opt/app","/etc/app")){<br />
echo "Rename failed";<br />
}</code></p>
<p>You can also use the <a href="http://us.php.net/manual/en/function.copy.php" target="_blank">copy</a> function to copy files, noting that if the &#8220;new&#8221; file or folder already exists, it will be overwritten.</p>
<p><code>if(!copy("/opt/app","/etc/app")){<br />
echo "Copy failed";<br />
}</code></p>
<h2>User and File information</h2>
<h3>Getting user and group data</h3>
<p>The <a href="http://us3.php.net/fileowner" target="_blank">fileowner</a> function as shown above will return the UID of the file, but I specified the username. You can use <a href="http://us3.php.net/manual/en/function.posix-getpwuid.php" target="_blank">posix_getpwuid</a> to return an array with the user&#8217;s information in a more usable format:</p>
<div>
<p><code>$filename = "/opt/app/users/users.txt";</code><code><br />
$username = posix_getpwuid(fileowner($filename));<code>print_r($username);</code></code></p>
</div>
<div>Will return:</div>
<p><code>Array<br />
(<br />
[name] =&gt; nessa<br />
[passwd] =&gt; x<br />
[uid] =&gt; 1000<br />
[gid] =&gt; 1000<br />
[gecos] =&gt; Vanessa V.,,,<br />
[dir] =&gt; /home/nessa<br />
[shell] =&gt; /bin/bash<br />
)</code></p>
<p>So you can simply echo out the array values of $username based on the keys. For example, to get the shell of the user in the above example, simply echo to the &#8216;shell&#8217; key from the $username array:</p>
<p><code>echo $username[shell];</code></p>
<p>If you want to get group information for a file, you can use the same method, but with <a href="http://us.php.net/manual/en/function.filegroup.php" target="_blank">filegroup</a> and <a href="http://us.php.net/manual/en/function.posix-getgrgid.php" target="_blank">posix_getgrgid</a>:</p>
<p><code>$filename = "/opt/app/users/users.txt";</code><br />
<code>print_r(posix_getgrgid(filegroup($filename)));</code></p>
<h3>Getting file information</h3>
<p>You can also get information about a file using the <a href="http://us.php.net/manual/en/function.stat.php" target="_blank">stat</a> or <a href="http://us.php.net/manual/en/function.fstat.php" target="_blank">fstat</a> functions, which return the results to an array:</p>
<p><code>$filename = "/opt/app/users/users.txt";</code><br />
<code>$stat = stat($filename);</code><br />
<code>print_r($stat);</code></p>
<p>Will return a giant array of information for the file. If you only want to return one value, say, the size, echo it out like you would a normal array:</p>
<p><code>echo $stat[size];</code></p>
<p>So here we&#8217;ve finished the first part of PHP command line scripting, which covered the use of files, folder, and users. The next parts will go over command execution and process management.</p>
<p>See: <a href="http://www.v-nessa.net/2010/05/21/command-line-php-part-2" target="_self">Command Line PHP: Part 2,</a> <a href="http://www.v-nessa.net/2010/05/25/command-line-php-part-3" target="_blank">Command Line PHP: Part 3<br />
</a></p>
<p><map name='google_ad_map_310_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/310?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_310_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=310&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F18%2Fcommand-line-php-part-1' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=310&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/05/18/command-line-php-part-1/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Sexifying WHM with XML API</title>
		<link>http://www.v-nessa.net/2008/06/07/sexifying-whm-with-xml-api</link>
		<comments>http://www.v-nessa.net/2008/06/07/sexifying-whm-with-xml-api#comments</comments>
		<pubDate>Sat, 07 Jun 2008 09:33:30 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[cpanel]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=155</guid>
		<description><![CDATA[.!. I don&#8217;t know about you other cPanel system admins out there, but I find WHM to be very useful for the more advanced and time-consuming tasks, such as installing SSL certificates. However, the easy stuff like changing an account&#8217;s package and resetting passwords is a royal pain in the ass as far as convenience [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F07%2Fsexifying-whm-with-xml-api"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F07%2Fsexifying-whm-with-xml-api&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<div style="display:none">.!.</div>
<p>I don&#8217;t know about you other cPanel system admins out there, but I find WHM to be very useful for the more advanced and time-consuming tasks, such as installing SSL certificates.  However, the easy stuff like changing an account&#8217;s package and resetting passwords is a royal pain in the ass as far as convenience is concerned when you have to log into WHM, list accounts, and make whatever change.</p>
<p>I recently became favorable towards the WHM XML API functionality which will let me do a majority of the everyday account-related tasks from command line without ever opening my browser, which is a lot easier when managing thousands of users across multiple servers.  Below are a couple scripts I&#8217;ve put together using the XML API from a base script in the cPanel forums:</p>
<p><a href="http://v-nessa.net/scripts/whmapi/chacctpass" target="_blank">Change account password</a></p>
<p><a href="http://v-nessa.net/scripts/whmapi/chpkg" target="_blank">Change account package</a></p>
<p>Both are run via command line, and the arguments passed to the PHP script as variables.  For example, to change an account&#8217;s password:</p>
<blockquote><p>./chacctpass myuser mypass1234</p>
</blockquote>
<p>Customizing these scripts to perform different functions is easy via the following steps:</p>
<p>- change<strong> if ($argc != 3)</strong> to the number of command line arguments you wish to pass to the script plus one.  In the above example there are two arguments and since the script name counts, add one and that makes 3.</p>
<p>- in the section where the arguments are assigned to variables (like $cpuser, etc), name your variables.  The first one should have an array value of 0, then 1, 2, etc.</p>
<p>- edit the usage example, which will come up if the required number of arguments is not provided&#8230;you can add any text you like</p>
<p>- if you&#8217;re using a hash (which is more secure than user/pass authentication), go fetch your remote access key from WHM and put it in the <strong>$hash</strong> value within quotes, format intact.  Otherwise, put in your WHM user&#8217;s username and password</p>
<p>- change the <strong>$server</strong> variable to your server&#8217;s hostname</p>
<p>- change <strong>$apipath</strong> to the WHM path for the function you are using.  You can find a whole list of them <a title="WHM API Functions" href="http://www.cpanel.net/plugins/xmlapi/" target="_self">here</a>, and most will give you the path to use in the examples sections.   In the API path, insert your variable names where the values are suppose to be.  For instance:</p>
<blockquote><p>$apiPath = &#8220;/xml-api/passwd?user=myuser&amp;pass=mypass1234&#8243;;</p>
</blockquote>
<p>Would be:</p>
<blockquote><p>$apiPath = &#8220;/xml-api/passwd?user=$cpuser&amp;pass=$newpass&#8221;;</p>
</blockquote>
<p>In the header section, uncomment whichever <strong>$header .= &#8220;Authorization:</strong> line that matches your authentication method (user/pass or hash)</p>
<p>Once you&#8217;ve configured your API script, chmod to 700 and run from the command line as show in my example.  It&#8217;s better to lock down the script by changing its ownership only to the user that will be using it, and not giving read, write, or execute permissions to anyone else.</p>
<p><strong>Note:</strong> for these scripts to work you have to have PHP compiled with OpenSSL support, otherwise change the socket variables to http over port 2086.</p>
<p><!--adsense#half--></p>
<p><map name='google_ad_map_155_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/155?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_155_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=155&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F07%2Fsexifying-whm-with-xml-api' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=155&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2008/06/07/sexifying-whm-with-xml-api/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Whitespace is Evil</title>
		<link>http://www.v-nessa.net/2007/12/19/whitespace-is-evil</link>
		<comments>http://www.v-nessa.net/2007/12/19/whitespace-is-evil#comments</comments>
		<pubDate>Wed, 19 Dec 2007 06:23:40 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/2007/12/19/whitespace-is-evil</guid>
		<description><![CDATA[I have this recurring nightmare of PHP apps that don&#8217;t trim whitespace when entering info. As a habitual copy and paster, it would be nice if some programmers could tend to my laziness and reluctance to type. Yes, Tony, I&#8217;m talking about you. Ever hear of the trim() function? Yea, it&#8217;s the Brazilian wax of [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2007%2F12%2F19%2Fwhitespace-is-evil"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2007%2F12%2F19%2Fwhitespace-is-evil&amp;source=nessa421&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I have this recurring nightmare of PHP apps that don&#8217;t trim whitespace when entering info.  As a habitual copy and paster, it would be nice if some programmers could tend to my laziness and reluctance to type.  Yes, Tony, I&#8217;m talking about you.  Ever hear of the trim() function?  Yea, it&#8217;s the Brazilian wax of PHP you inconsiderate bastard.</p>
<p><font color="#ff66cc"><code>$text = "some text with extra spaces        ";</code><br />
<code>$trimmed = trim($text);</code><br />
<code>echo $trimmed;</code></font></p>
<p><map name='google_ad_map_131_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/131?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_131_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=131&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2007%2F12%2F19%2Fwhitespace-is-evil' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=131&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2007/12/19/whitespace-is-evil/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

