<?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>Spice World! &#187; PHP</title>
	<atom:link href="http://www.cyberspice.org.uk/blog/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cyberspice.org.uk/blog</link>
	<description>The life and times of a jet setting software engineer!</description>
	<lastBuildDate>Fri, 02 Dec 2011 14:52:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Enumerating note data in Flickr using PHP</title>
		<link>http://www.cyberspice.org.uk/blog/2010/09/24/enumerating-note-data-in-flickr-using-php/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/09/24/enumerating-note-data-in-flickr-using-php/#comments</comments>
		<pubDate>Fri, 24 Sep 2010 12:44:38 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Flickr]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=466</guid>
		<description><![CDATA[Flickr provides a comprehensive API to access its data. It also has a very neat notes facility that allows you to add notes to a region of an image which pop-up when you mouse over the relevant area. Flickr provides API calls to add, edit and delete notes but not to enumerate notes associated with [...]]]></description>
			<content:encoded><![CDATA[<p>Flickr provides a comprehensive API to access its data.  It also has a very neat notes facility that allows you to add notes to a region of an image which pop-up when you mouse over the relevant area.  Flickr provides API calls to add, edit and delete notes but not to enumerate notes associated with an image.  To do that you have to do a little more work.</p>
<p><span id="more-466"></span></p>
<p>Flickr provides the following APIs to access notes:</p>
<ul>
<li><a href="http://www.flickr.com/services/api/flickr.photos.notes.add.html">flickr.photos.notes.add</a></li>
<li><a href="http://www.flickr.com/services/api/flickr.photos.notes.edit.html">flickr.photos.notes.edit</a></li>
<li><a href="http://www.flickr.com/services/api/flickr.photos.notes.delete.html">flickr.photos.notes.delete</a></li>
</ul>
<p>The first API takes the photo id, coordinates (appropriate for a 500 pixel wide image) and text of the note to add.  The second takes the note id, new coordinates and text to update the note with.  The third takes the note id of the note to delete.  As you can see there&#8217;s no way, using the API, of getting the ids of notes already associated with an image.  The API only allows you to edit and delete notes that you have created using the API.</p>
<p>However all is not completely lost.  Flickr outputs very nice HTML with HTML elements having sensible class names and so on.  The layout of a Flickr image page is basically as follows:</p>
<p><center></p>
<table>
<tr style="border: 1px solid white; margin: 5px; spacing: 5px; text-align: center;">
<td style="border: 1px solid white; margin: 5px; spacing: 5px;">
<div style="border: 1px solid white; margin: 5px; spacing: 5px;">
<div style="border: 1px solid white; margin: 5px; spacing: 5px;">
<p>
id=&#8221;notes&#8221;</p>
<p>
</div>
<p>id=&#8221;photo&#8221;
</p></div>
<div style="border: 1px solid white; margin: 5px; spacing: 5px;">
id=&#8221;meta&#8221;
</div>
<div style="border: 1px solid white; margin: 5px; spacing: 5px;">
id=&#8221;comments&#8221;
</div>
<p>id=&#8221;primary-column&#8221;
</td>
<td style="border: 1px solid white; margin: 5px; spacing: 5px;">
id=&#8221;sidebar&#8221;
</td>
<td style="border: 1px solid white; margin: 5px; spacing: 5px;">
id=&#8221;shortcuts&#8221;
</td>
</tr>
</table>
<p></center></p>
<p>All of the elements are <strong>&lt;div;&gt;</strong> elements except for &#8220;notes&#8221; which is an un-ordered list.  Each of the notes themselves is a list item.  Below is a typical note list item.  As you can see it looks some what complicated.  This is because it includes the code needed to render the border of the note&#8217;s active area together with re-size corners.  However we can ignore most of it.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;li class=&quot;box note note-byowner note-highlight&quot; data-note-user_id=&quot;38990160&quot; data-note-id=&quot;72157624923250854&quot; style=&quot;left: 253px; top: 56px; width: 94px; height: 120px; z-index: 2; &quot; id=&quot;yui_3_1_0_1_1285322792456209&quot;&gt;
&lt;span class=&quot;box-stroke box-stroke-outer&quot; id=&quot;yui_3_1_0_1_1285322792456803&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;box-stroke box-stroke-inner&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;box-stroke box-stroke-main&quot; id=&quot;yui_3_1_0_1_1285322792456784&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;note-content&quot; id=&quot;yui_3_1_0_1_1285322792456788&quot;&gt;
&lt;span class=&quot;note-text&quot; id=&quot;yui_3_1_0_1_1285322792456792&quot;&gt;
&lt;span class=&quot;note-wrap&quot; id=&quot;yui_3_1_0_1_1285322792456832&quot;&gt;WIZ810MJ ethernet module.&lt;/span&gt;
&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;resize resize-nw&quot;&gt;&lt;span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;resize resize-ne&quot;&gt;
&lt;span&gt;
&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;resize resize-se&quot;&gt;&lt;span&gt;
&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;resize resize-sw&quot;&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;</pre></div></div>

<p>The only elements of interest is the list item itself and the plain text it contains.  The list item includes meta data which is useful to us.  The <em>data-note-id</em> value is the note id value to use in the Flickr API, the <em>style</em> provides the coordinates and size of the note&#8217;s active area, and the plain text is the actual note description.  This makes it reasonably easy to extract using &#8220;screen scraping&#8221;.</p>
<p>The Simple HTML DOM parser is a couple of PHP objects that parses HTML and allows you to access the DOM in a way similar to JQuery.  It uses the MIT licence and is freely available from <a href="http://sourceforge.net/projects/simplehtmldom/files/">SourceForge</a>.  Using this parser we can extract the notes information from the Flickr web page for the image.</p>
<p>The URL for an image page on flickr is:</p>
<pre>
http://www.flickr.com/photos/&lt;user id&gt;/&lt;photo id&gt;/
</pre>
<p>The following example code displays the note information for notes related to an image in my Flickr stream.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Using the SimpleHTMLDOM parser.</span>
<span style="color: #b1b100;">include_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'simple_html_dom.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create a new parser</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> simple_html_dom<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Parse the web page for the image we want the notes for</span>
<span style="color: #000088;">$html</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load_file</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.flickr.com/photos/39013214@N03/4976074521/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Flickr keeps all the notes in a &lt;ul&gt; with a class id of 'notes'</span>
<span style="color: #000088;">$notes</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$html</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#notes'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Each note is a list item</span>
<span style="color: #000088;">$note_items</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$notes</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'li'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Iterate through the notes</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$note_items</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Get the id</span>
	<span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'data-note-id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Get the coordinates</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;;&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'style'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$style_item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;:&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$style_item</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'left'</span>  <span style="color: #339933;">:</span> <span style="color: #000088;">$left</span>   <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'top'</span>   <span style="color: #339933;">:</span> <span style="color: #000088;">$top</span>    <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'width'</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$width</span>  <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'height'</span><span style="color: #339933;">:</span> <span style="color: #000088;">$height</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Get the text</span>
	<span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Output info</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Id: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$id</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Coords:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;  Left  : &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$left</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;  Top   : &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$top</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;  Width : &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$width</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;  Height: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$height</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Text: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$text</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As you can see Simple HTML DOM parser makes things simple.  The page for the image is loaded and parsed.  Then the first element with the id of &#8220;notes&#8221; is found (there should be only one).  Then an array of the list item elements to the &#8220;notes&#8221; element is obtained and iterated over.  The <em>data-note-id</em> item is the note id; the <em>style</em> is parsed to extract the coordinates and size of the active area; and the plain text, i.e. the note text, is copied.</p>
<p>The output from the example code is as follows:</p>
<pre>
kring:simplehtmldom melanie$ php test.php
Id: 72157624923250854
Coords:
  Left  : 253px
  Top   : 56px
  Width : 94px
  Height: 120px
Text: WIZ810MJ ethernet module.

Id: 72157624798614851
Coords:
  Left  : 254px
  Top   : 177px
  Width : 95px
  Height: 77px
Text: Adapter to allow it to be plugged in to breadboard (the WIZ810MJ has 2mm pitch connectors)

Id: 72157624923256462
Coords:
  Left  : 205px
  Top   : 204px
  Width : 49px
  Height: 67px
Text: 3.3V regulation.

Id: 72157624798617733
Coords:
  Left  : 354px
  Top   : 233px
  Width : 91px
  Height: 72px
Text: From BBC micro 8 bit &quot;User&quot; parallel port.

Id: 72157624923259400
Coords:
  Left  : 103px
  Top   : 299px
  Width : 242px
  Height: 64px
Text: Boarduino to provide 5V power.
</pre>
<p>Using this information you can update the note using the Flickr API or display the image complete with notes on your own page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/09/24/enumerating-note-data-in-flickr-using-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capturing still images from video devices in PHP using Framegrab</title>
		<link>http://www.cyberspice.org.uk/blog/2010/02/28/capturing-still-images-from-video-devices-in-php-using-framegrab/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/02/28/capturing-still-images-from-video-devices-in-php-using-framegrab/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 16:10:34 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Framegrab]]></category>
		<category><![CDATA[PECL]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=433</guid>
		<description><![CDATA[I found I had a need to capture and process still video images from video devices using PHP so I wrote the Framegrab PECL extension. This post introduces the basics of Framegrab. The framegrab extension is currently only available for Linux although Windows and OS X support will be coming soon. On Linux the extension [...]]]></description>
			<content:encoded><![CDATA[<p>I found I had a need to capture and process still video images from video devices using PHP so I wrote the Framegrab PECL extension.  This post introduces the basics of Framegrab.<br />
<span id="more-433"></span><br />
The framegrab extension is currently only available for Linux although Windows and OS X support will be coming soon.  On Linux the extension uses the Video For Linux API version 2.</p>
<p>Framegrab adds two classes to PHP.  <em>FrameGrabDevice</em> represents a video capture device and <em>FrameGrabImage</em> an image captured with a FrameGrabDevice.     </p>
<p>You can create a new <em>FrameGrabDevice</em> for the default video capture device as follows:</p>
<pre>
	$device = new FrameGrabDevice();
</pre>
<p>The extension will iterate through available video devices until it finds one that supports video capture.  A <em>FrameGrabDeviceException</em> will be thrown either if no video devices are available or if the available video devices do not support video capture.</p>
<p>You can supply an argument to the constructor (see below) if you want to initialise a specific video device.  In this case the <em>FrameGrabDeviceException</em> will be thrown if that specific device does not exist or does not support video capture.</p>
<pre>
	$device = new FrameGrabDevice('/dev/video1');
</pre>
<p>Once you have a device you can then grab an image using the <em>grab()</em> method.  The method takes no arguments and returns a <em>FrameGrabImage</em> object or false on error.  As the <em>FrameGrabImage</em> constructor is a protected method you cannot create objects directly using new.</p>
<p>Once you have the image you can either save the image to the file in PNG format or have it returned as a string in PNG format using the writeAsPNG() and toStringAsPNG() methods respectively.  The former takes a filename as the sole argument and returns false on error.  The latter takes no arguments and returns either the PNG data as a string or false on error.</p>
<p>The two objects also support a number of properties.  The code below demonstrates the extension in use.  It returns an image captured from the default video device as a PNG.  The image has capture device and image meta data embedded in it visible in the top left corner of the image.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
try <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Get the default frame grabber device.  Throws an exception if a device</span>
	<span style="color: #666666; font-style: italic;">// cannot be found.</span>
	<span style="color: #000088;">$device</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FrameGrabDevice<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Grab am image.</span>
	<span style="color: #000088;">$fgimage</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$device</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">grab</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$fgimage</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Create a GD image from a frame grab image</span>
		<span style="color: #000088;">$gdimage</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imagecreatefromstring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toStringAsPNG</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Output data about the image on to the image</span>
		<span style="color: #000088;">$font</span>  <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$black</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imagecolorallocate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$fh</span>    <span style="color: #339933;">=</span> <span style="color: #990000;">imagefontheight</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$font</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$x</span>     <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span>     <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Device: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$device</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">device</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Card: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$device</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">card</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Width: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">width</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Height: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">height</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Format: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">format</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Bytes per line: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bytes_per_line</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Output the image</span>
		<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Type: image/png'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagepng</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagedestroy</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Handle the FrameGrabDevice exception here.</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>The extension is available <a href="http://pecl.php.net/package/framegrab">at the PECL site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/02/28/capturing-still-images-from-video-devices-in-php-using-framegrab/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Serial IO in PHP using the DIO extension</title>
		<link>http://www.cyberspice.org.uk/blog/2010/02/15/serial-io-in-php-using-the-dio-extension/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/02/15/serial-io-in-php-using-the-dio-extension/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 16:36:03 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[DIO]]></category>
		<category><![CDATA[PECL]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=429</guid>
		<description><![CDATA[DIO is the Direct IO extension for PHP. I recently took over maintaining this extension and have implemented comprehensive stream support for both POSIX and Windows systems. To demonstrate the use of DIO this post will describe a PHP script that sends an SMS using a USB 3G modem. To make control of modems easier [...]]]></description>
			<content:encoded><![CDATA[<p>DIO is the Direct IO extension for PHP.  I recently took over maintaining this extension and have implemented comprehensive stream support for both POSIX and Windows systems.  To demonstrate the use of DIO this post will describe a PHP script that sends an SMS using a USB 3G modem.<br />
<span id="more-429"></span></p>
<p>To make control of modems easier over twenty years ago the Hayes Corporation developed a serial command protocol, the Hayes or AT command set.  Many other modems adopted the protocol and now its a de-facto standard.  Over the years as modem functionality expanded so did the command set.  Now it supports FAX, cell phone address books, SMSes and so on.  The AT command set comprises a set of text based commands terminated with CRLF.  The responses are similarly text strings terminated with CRLF.  Typically the modem responds with &#8220;OK&#8221;, &#8220;ERROR&#8221; or a setting value.</p>
<p>DIO currently provides two stream types <em>raw</em> and <em>serial</em>.  Raw streams provide low level access to operating system devices.  Serial streams provide access to, and abstract, serial ports.  DIO stream support is accessed just like any other PHP streams.  The appropriate URI is <a href="http://uk2.php.net/manual/en/function.fopen.php">fopen</a>ed.  The relevant URIs are:</p>
<pre>
dio.raw://[device]
</pre>
<p>for raw streams and</p>
<pre>
dio.serial://[device]
</pre>
<p>for serials streams.  In both cases [device] is the device name to open.  For example this could be /dev/random for the random device on Linux; or /dev/ttyS0 for a comms port on Linux; or COM1 for a comms port on Windows.  We&#8217;ll be using the later form of the URI as we&#8217;re opening a serial port.  </p>
<p>The example code opens the serial port as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$f</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;dio.serial:///dev/tty.ZTEUSBATPort_&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;r+&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first argument is the device to open.  In this case a serial port to the USB 3G modem connected to my MacBook.  The second is the open mode, in this case read/write.  The third is an optional argument that comprises a flag that indicates whether to search the include path for the file to open.  We don&#8217;t want this.  The final optional argument is a stream context which is a collection of stream specific additional parameters.</p>
<p>A stream context is created using <a href="http://uk2.php.net/manual/en/function.stream-context-create.php">stream_context_create</a>().  The code in the example that creates the context, prior to opening the port, is shown below.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stream_context_create</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dio'</span> <span style="color: #339933;">=&gt;</span> 
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'data_rate'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">9600</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'data_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'stop_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'parity'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'flow_control'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
		  <span style="color: #0000ff;">'is_blocking'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
		  <span style="color: #0000ff;">'canonical'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first four context options are pretty obvious.  The serial port is being configured for 9600 bits per second, 8 bits per byte with 1 additional stop bit per byte and no parity checking.</p>
<p>The next option disables hardware flow control.  Serial ports are relatively slow so they often have hardware control lines which indicate when there is data ready to be sent and space in the buffer ready to receive data.  My USB modem does not have these so the hardware flow control is disabled.</p>
<p>Next we turn off blocking.  With blocking function calls the operating system waits for data and only returns when it is ready to return the data that was requested i.e. the operating system blocks on the data.  Non-blocking function calls return whether there is data or not.  The POSIX open call also blocks on the state of the Data Carrier Detect (&#8220;DCD&#8221;) hardware control line.  Some modems have this control line and use it to indicate there&#8217;s a carrier signal on the telephone line.  Again since the USB modem does not have this we disable it.</p>
<p>Finally we enable canonical mode.  Canonical IO on POSIX means that the serial port driver will wait for a line of text ending in a newline (or the internal buffer being full) before returning.  If less characters than were entered on the line were requested the driver buffers the data for subsequent reads until the entire line is returned.  In canonical mode you can actually connect a terminal to the serial port as line editing is supported.  Since Windows does not have a canonical mode DIO provides an implementation on top of the Windows driver.  The alternative to canonical mode is byte mode where by DIO waits until the requested number of bytes have been read and returns regardless of whether there are more bytes available.</p>
<p>If all that sounds a little complicated think of it like this.  If you&#8217;re reading strings terminated with a new line use canonical mode otherwise use byte mode.</p>
<p>Remember that blocking was disabled so that opening the serial device did not block.  This isn&#8217;t desirable when actually reading data.  Blocking mode can be re-enabled on an open stream using <a href="http://uk2.php.net/manual/en/function.stream-set-blocking.php">stream_set_blocking</a> as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">stream_set_blocking</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Once the serial port has been opened with the appropriate port settings and blocking re-enabled the port can be written and read using the standard <a href="http://uk2.php.net/manual/en/function.fprintf.php">fprintf</a> and <a href="http://uk2.php.net/manual/en/function.fgets.php">fgets</a> PHP functions.</p>
<p>There are two AT commands related to sending an SMS.  The first is &#8220;AT+CMGF=1&#8243; which tells the modem to operate in SMS text mode.  This should respond with &#8220;OK&#8221;.  The second is &#8220;AT+CMGS=&#8221; which is followed by a string comprising a telephone number.  This accepts the text of an SMS which is sent when CTRL-Z is entered.  </p>
<p>There&#8217;s a little bit of additional work in the example as the modem echos data sent to it back to the sender so the PHP code consumes data after a command is sent until it sees the sent command echoed back.  The full example follows.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> 
&nbsp;
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'PHONE_NUMBER'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'5551234'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SMS_TEXT'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Hello world!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Sends data to the modem
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> send_data<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #000088;">$string</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt; <span style="color: #006699; font-weight: bold;">$string</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">fprintf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$string</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Reads lines from the serial port.  It reads until a non blank line is
 * received then returns it.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> get_string<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// remove carriage returns, line feeds and excess white space</span>
		<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$response</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Waits for OK to be sent back by the modem.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> wait_for_ok<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> get_string<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&gt; <span style="color: #006699; font-weight: bold;">$response</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">&quot;OK&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// MAIN CODE</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create the context</span>
<span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stream_context_create</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dio'</span> <span style="color: #339933;">=&gt;</span> 
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'data_rate'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">9600</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'data_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'stop_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'parity'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'flow_control'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
		  <span style="color: #0000ff;">'is_blocking'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
		  <span style="color: #0000ff;">'canonical'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Open the port</span>
<span style="color: #000088;">$f</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;dio.serial:///dev/tty.ZTEUSBATPort_&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;r+&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Re-enable blocking</span>
	<span style="color: #990000;">stream_set_blocking</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Set SMS text entry mode</span>
	send_data<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;AT+CMGF=1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	wait_for_ok<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Send an SMS</span>
	send_data<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;AT+CMGS=<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span> <span style="color: #339933;">.</span> PHONE_NUMBER <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	send_data<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> SMS_TEXT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">// Send CTRL-Z to end SMS text entry</span>
	<span style="color: #990000;">fprintf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">26</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	
	wait_for_ok<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Close the port</span>
	<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/02/15/serial-io-in-php-using-the-dio-extension/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>PHP DIO Extension: Looking for beta testers</title>
		<link>http://www.cyberspice.org.uk/blog/2010/02/02/php-dio-extension-looking-for-beta-testers/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/02/02/php-dio-extension-looking-for-beta-testers/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 19:58:20 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[DIO]]></category>
		<category><![CDATA[PECL]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=424</guid>
		<description><![CDATA[A few months ago I had a need to do some serial IO from PHP. After asking around I found out there was a PHP extension for this but it was unmaintained, unowned and out of date. To cut a long story short I ended up as the maintainer of said extension and since them [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago I had a need to do some serial IO from PHP.  After asking around I found out there was a PHP extension for this but it was unmaintained, unowned and out of date.  To cut a long story short I ended up as the maintainer of said extension and since them I have been fixing and extending it.</p>
<p>The original DIO API is very basic and POSIX oriented.  Serial support is not very configurable and doesn&#8217;t work at all on Window platforms.  So I have been working on implementing PHP stream extensions that allow you to do raw and serial IO via streams.  Anyway its ready for testing by people other than me on POSIX (Linux, OS X etc) and Windows platforms so I&#8217;m looking for beta testers.</p>
<p><span id="more-424"></span></p>
<h2>Where to get it</h2>
<p>The release candidate is downloadable as a package from:</p>
<p><a href="http://www.cyberspice.org.uk/downloads/dio-0.0.4rc3.tgz">http://www.cyberspice.org.uk/downloads/dio-0.0.4rc3.tgz</a></p>
<p>And directly from SVN at:</p>
<p><a href="http://svn.php.net/repository/pecl/dio/tags/RELEASE_0_0_4RC3">http://svn.php.net/repository/pecl/dio/tags/RELEASE_0_0_4RC3</a></p>
<h2>Documentation</h2>
<p>While I write proper PHP documentation below is a brief over view of how you use DIO.</p>
<h3>Streams</h3>
<p>DIO streams are just PHP streams.  You use <a href="http://www.php.net/manual/en/function.fopen.php">fopen()</a> to open them and <a href="http://www.php.net/manual/en/function.fread.php">fread()</a>, <a href="http://www.php.net/manual/en/function.fwrite.php">fwrite()</a>, <a href="http://www.php.net/manual/en/function.fgets.php">fgets()</a>, <a href="http://www.php.net/manual/en/function.stream-set-blocking.php">stream_set_blocking()</a> etc. There are two DIO streams, dio.raw and dio.serial.  </p>
<p>dio.raw is as it sounds, raw streams.  It uses the low level OS streams such as open(), read(), write(), close() etc. on POSIX and CreateFile(), OpenFile(), ReadFile(), WriteFile(), CloseFile() on Windows.  It does not buffer except the internal PHP buffering.</p>
<p>dio.serial is full serial support.  It allows setting of data rates, data size, stop bits, handshaking and raw/canonical modes etc.</p>
<p>Both stream types support timeouts and blocking/non-blocking use.</p>
<h3>Example code</h3>
<p>Below is a small example that opens a serial port, configuring it with a stream context, and then reads and writes from it before closing it.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> 
	<span style="color: #666666; font-style: italic;">// Create a stream context that configures the serial port</span>
	<span style="color: #666666; font-style: italic;">// And enables canonical input.</span>
	<span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stream_context_create</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dio'</span> <span style="color: #339933;">=&gt;</span> 
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'data_rate'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">115200</span><span style="color: #339933;">,</span> 
		      <span style="color: #0000ff;">'data_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span> 
		      <span style="color: #0000ff;">'stop_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> 
		      <span style="color: #0000ff;">'parity'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> 
		      <span style="color: #0000ff;">'is_canonical'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Are we POSIX or Windows?  POSIX platforms do not have a</span>
	<span style="color: #666666; font-style: italic;">// Standard port naming scheme so it could be /dev/ttyUSB0</span>
	<span style="color: #666666; font-style: italic;">// or some long /dev/tty.serial_port_name_thingy on OSX.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>PATH_SEPARATOR <span style="color: #339933;">!=</span> <span style="color: #0000ff;">&quot;;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$filename</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;dio.serial:///dev/ttyS0&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$filename</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;dio.serial://COM1&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Open the stream for read only and use it.</span>
	<span style="color: #000088;">$f</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;r+&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Writing to port...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">fprintf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;Hello world<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Reading from port...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<h3>Stream context</h3>
<p>DIO uses the stream context to obtain the port configuration settings.  There are settings which are common to all DIO streams and settings which are sub-stream specific.  The common settings are:</p>
<style type="text/css">
th,td { text-align:left; vertical-align:top; }
</style>
<table style="width: 600px; margin: 0 auto">
<tr>
<th>perms</th>
<td>Integer</td>
<td>Sets the file permissions mask when creating a file (POSIX specific, ignored on Windows)</td>
</tr>
<tr>
<th>is_blocking</th>
<td>Boolean</td>
<td>Indicates whether the stream is blocking (true, default) or non blocking (false)</td>
</tr>
<tr>
<th>timeout_secs</th>
<td>Integer</td>
<td>The time to wait for input in seconds before returning.  Also sets the stream non blocking.</td>
</tr>
<tr>
<th>timeout_usecs</th>
<td>Integer</td>
<td>The time to wait for input in micro seconds before returning.  Used in conjunction with timeout_secs.  If omitted but timeout_secs is defined it is assumed to be zero.</td>
</tr>
</table>
<p>Both the blocking setting and the timeout settings can changed after the stream is open using the PHP functions <a href="http://www.php.net/manual/en/function.stream-set-blocking.php">stream_set_blocking()</a> and <a href="http://www.php.net/manual/en/function.stream-set-timeout.php">stream_set_timeout()</a> respectively.</p>
<p>The serial stream has the following additional configuration settings.</p>
<table style="width: 600px; margin: 0 auto">
<tr>
<th>data_rate</th>
<td>Integer</td>
<td>Sets the data rate in bits per second (Not BAUD.  BAUD is symbols per second.  A symbol may include more than one bit)</td>
</tr>
<tr>
<th>data_bits</th>
<td>Integer</td>
<td>Number of bits per byte.  Typically 5, 6, 7 or 8 (default).</td>
</tr>
<tr>
<th>stop_bits</th>
<td>Integer</td>
<td>The number of stop bits. 1 (default), 2 or 3 (1.5 stop bits)</td>
</tr>
<tr>
<th>parity</th>
<td>Integer</td>
<td>The parity checking.  0 (None, default), 1 (Odd), 2 (Even).</td>
</tr>
<tr>
<th>flow_control</th>
<td>Boolean</td>
<td>Enables/disables hardware flow control</td>
</tr>
<tr>
<th>is_canonical</th>
<td>Boolean</td>
<td>Enables canonical input mode.  Canonical input buffers the input until either internal buffer is full or an end of line has been received.  So a read in canonical mode will block until an end of line or file even if more than the requested characters have been read from the remote machine.  </p>
<p>Full canonical mode handles control characters, delete, echoing characters back to the remote machine and so on.  Its basically used to implement a terminal.  DIO doesn&#8217;t have any of the latter other than the buffering. Yet!</td>
</tr>
</table>
<h3>Finally</h3>
<p>So there you are.  Any results, good or bad, are useful.  DIO has error checking and will return useful warnings if you try and feed it silly values.  Logs, PHP versions, etc. would be useful diagnosing issues.  Thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/02/02/php-dio-extension-looking-for-beta-testers/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Popping my conference cherry (Part #1)</title>
		<link>http://www.cyberspice.org.uk/blog/2009/03/06/popping-my-conference-cherry-part-1/</link>
		<comments>http://www.cyberspice.org.uk/blog/2009/03/06/popping-my-conference-cherry-part-1/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 16:03:03 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Travel]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[London]]></category>
		<category><![CDATA[PHP Women]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=119</guid>
		<description><![CDATA[Friday 27 February was PHP UK Conference 2009. I&#8217;m doing more and more PHP and other web oriented coding as a change from my day to day work which is debugging low level linux code. A conference seemed the best way to find out more about the language and technologies so, with some encouragement from [...]]]></description>
			<content:encoded><![CDATA[<p>Friday 27 February was <a href="http://www.cyberspice.org.uk/gallery/thumbnails.php?album=11">PHP UK Conference 2009</a>.  I&#8217;m doing more and more PHP and other web oriented coding as a change from my day to day work which is debugging low level linux code.  A conference seemed the best way to find out more about the language and technologies so, with some encouragement from friends, I decided to go.  I used some Hilton Honors points to get a couple of nights at the Hilton Euston in London and drove down there on the Thursday.</p>
<p>Usually I catch the train to London but as I was heading to Bristol from London on the Saturday I drove.  Also normally when I drive I leave the car in outer London and catch the tube but a combination of lack of time and Barnet Council making all street parking short term meters or residents only I found it was easier to drive all the way in and leave the car in some free over night parking by the hotel.  This worked well the first night because I entered the area after the end of congestion charging.</p>
<h3>The Social</h3>
<p><span style="float: left; margin-right: 10px; margin-bottom: 10px;"><a href="http://www.cyberspice.org.uk/gallery/displayimage.php?album=12&#038;pos=3"><img src="http://www.cyberspice.org.uk/gallery/albums/userpics/10001/thumb_IMG_5323.jpg" alt="The PHP Women" /></a></span>Thursday night was the social at The Brook Green Hotel on Shepherd&#8217;s Bush Road near to Olympia, which is where the conference was held. After a quick check in I changed and caught the tube to the Hotel.  At the hotel I met up with my roomie for the two days, <a href="http://binarykitten.jkrswebsolutions.co.uk/">Kat</a>, <a href="http://www.lornajane.net/">Lornajane</a>, <a href="http://derickrethans.nl/">Derick</a> and <a href="http://blog.libssh2.org/">Sara</a>.  I also met a load of new people and put faces to the <a href="http://www.phpwomen.org/">PHP Women</a> I knew from online.  I also drank rather a lot of vodka!  </p>
<p><span style="float: right; margin-left: 10px; margin-bottom: 10px;"><a href="http://www.cyberspice.org.uk/gallery/displayimage.php?album=12&#038;pos=5"><img src="http://www.cyberspice.org.uk/gallery/albums/userpics/10001/thumb_IMG_5325.jpg" alt="Sara poses for the camera" /></a></span>The social was organised by <a href="http://www.phplondon.org/wiki/Main_Page">PHP London</a> as a special one of their usual nights held at the hotel.  There were two talks made during the evening.  Derick made the first one on using <a href="http://www.freedesktop.org/wiki/Software/dbus">DBUS</a> with PHP.  It was interesting .  By the time of Sara&#8217;s talk I was both tired and quite drunk so I&#8217;m afraid I wasn&#8217;t paying attention.  Although I did get an awesome photo of her.</p>
<p>A round midnight Kat and I started to wend our way back to the hotel.  Once we got there Kat had a few transfers to apply to t-shirts for the &#8220;Booth Babes&#8221;.  Then we set the alarm for 6.30 am and went to sleep.</p>
<h3>The Conference</h3>
<p>The morning started far too early with the alarm going off at 6.30 am but after waking up I was quite excited as this was my first ever conference of this kind.  I&#8217;ve attended shows and expos before and <a href="http://www.wrocc.org.uk/show/1999/report.shtml">even given talks</a> in front of lots of people but never attended a &#8216;proper&#8217; conference.  Since I had to find parking for the car it seemed easiest to drive across town and leave it in the horendously expensive Olympia car park.  Like Thursday night I was driving against the traffic and so it was a pain free trip.</p>
<p><span style="float: left; margin-right: 10px; margin-bottom: 10px;"><a href="http://www.cyberspice.org.uk/gallery/displayimage.php?album=12&#038;pos=6"><img src="http://www.cyberspice.org.uk/gallery/albums/userpics/10001/thumb_IMG_5332.jpg" alt="Chatting between talks" /></a></span>Kat and I arrived at the Conference Centre around 8.30 am.  We registered, grabbed tea and coffee and helped set up the PHP Women&#8217;s stand.  The key note was due to start at 9.30 but due to registration issues it didn&#8217;t start until 9.45.  This meant we could natter longer between ourselves.</p>
<h4>The future&#8217;s so bright, I gotta wear shades</h4>
<p><a href="http://aralbalkan.com/">Aral Balkan</a> gave the key note speech and what a speech to be introduced to conferences with.  Aral is a flash developer.  Quite trendy he is a sociable guy and we talked both at the social and at the after conference party.  His talk was not just relevant to PHP  developers or even Web 2.0 developers but all developers of any software that has an end user.  And he&#8217;s absolutely right.  What is the point of having the most perfectly architected piece of software which follows more computer science patterns that you can shake a stick at if you completely miss the boat, which in most cases is the market.  Sometimes you do just have to code and refactor later.  He talked about commodity hardware and commodity software, great new tools and technologies, and was totally inspiring.  An excellent way to start the day.</p>
<h4>What&#8217;s new in PHP 5.3</h4>
<p>The talk on the new features of the PHP language by Scott MacVicar was, in some respects, the complete opposite of Aral&#8217;s talk.  It was totally technically and just described each of the new features in PHP 5.3, just as it said on the tin.  For someone still learning this was extremely useful.</p>
<h4>Of lambda functions, closures and traits</h4>
<p>The final talk of the morning I attended was another technical one which explained some of the upcoming facilities in PHP 5.4.  It described how to define lambda functions and closured (quick throw away functions useful as callbacks and so on).  And the upcoming traits mechanism that introduces a level of multiple inheritance to PHP classes whilst avoiding the diamond pattern issue and duplicating Java&#8217;s interface mechanism.</p>
<p>Then it was lunch.</p>
<p>(cont)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2009/03/06/popping-my-conference-cherry-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

