<?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>Jason Irwin dot Net &#187; PHP</title>
	<atom:link href="http://j2fi.net/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://j2fi.net</link>
	<description>Battling Imaginary Windmills in Japan</description>
	<lastBuildDate>Wed, 28 Jul 2010 05:11:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Creating a Simple REST API With VB, PHP and MySQL</title>
		<link>http://j2fi.net/2009/05/24/simple-api/</link>
		<comments>http://j2fi.net/2009/05/24/simple-api/#comments</comments>
		<pubDate>Sun, 24 May 2009 07:00:03 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[VB]]></category>

		<guid isPermaLink="false">http://j2fi.net/?p=1247</guid>
		<description><![CDATA[The internet is an interesting place.  A few weeks ago I had posted an article showing people how to make Crystal Reports play nice with SQL Server Compact Edition.  Since then, I&#8217;ve had a few people contact me with questions [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://j2fi.net/wp-content/uploads/2009/05/vs_and_mysql.png"><img style=' float: left; padding: 4px; margin: 0 7px 2px 0;'  class="alignleft size-medium wp-image-1248" src="http://j2fi.net/wp-content/uploads/2009/05/vs_and_mysql-300x137.png" alt="Visual Studio &amp; MySQL" width="240" height="110" /></a>The internet is an interesting place.  A few weeks ago I had posted an article showing people <a title="Jason Irwin dot Net | Crystal Reports and SQL Server CE" href="http://j2fi.net/2009/04/05/crystal-reports-and-sql-server-ce/" target="_self">how to make Crystal Reports play nice with SQL Server Compact Edition</a>.  Since then, I&#8217;ve had a few people contact me with questions about how to use SQL Server CE as well as how to make Crystal Reports access other data sources.  One question seemed to come up more often than any other, though:  How do I get VB to access a MySQL Database hosted somewhere on the internet without granting a user direct access to that database?</p>
<p>It&#8217;s a pretty good question, and the solution is one that I&#8217;ve had to employ several times over the last few years.</p>
<p><em>Disclaimer: As with any other solution you would find on the internet, this is not a &#8220;one size fits all&#8221; answer.  The code that I am going to show has been overly simplified and should be used as a starting point to your solution.  That said, if you have any questions about the code, I&#8217;ll do my best to answer them.</em></p>
<p><strong>How It Works</strong></p>
<p>The idea behind this solution is rather simple.  Pass some information to a PHP file on a server using a WebRequest in VB, and build a DataTable dynamically using the XML data returned from the web.  There are no security checks built into any of this code, but that can be added later.</p>
<p>So, with all that stuff said, let&#8217;s take a look at the PHP code that we&#8217;ll be using.</p>
<p>[code lang="php"]</p>
<p>&lt;?php$rptID = $_POST['reportid'];<br />
$toDate = $_POST['todate'];//Connect to the database<br />
$db = mysql_connect("localhost","your_username","your_password");<br />
mysql_select_db("your_database");//Query the Database<br />
$res = mysql_query("SELECT rpt.id, rpt.LastName, rpt.FirstName, rpt.Whatever WHERE id = " . $rptID );// Start the XML Document<br />
echo "&lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?&gt;";<br />
echo "&lt;Report&gt;";</p>
<p>//If information exists, write it out as XML<br />
If($rs = mysql_fetch_row($res)) {<br />
do {<br />
echo "&lt;Detail&gt;";<br />
echo "&lt;id&gt;".$rs[0]."&lt;/Code&gt;";<br />
echo "&lt;LastName&gt;".$rs[1]."&lt;/LastName&gt;";<br />
echo "&lt;FirstName&gt;".$rs[2]."&lt;/FirstName&gt;";<br />
echo "&lt;Whatever&gt;".$rs[3]."&lt;/Whatever&gt;";<br />
echo "&lt;/Detail&gt;";<br />
} while($rs = mysql_fetch_row($res));<br />
mysql_close();<br />
}<br />
echo "&lt;/Report&gt;";<br />
?&gt;<br />
[/code]</p>
<p>As you can see, this code is as plain as it gets.  We have two variables, a MySQL Query, and the result set is returned in XML format.  Of course you&#8217;ll probably want to change the MySQL query to something that&#8217;ll work on your own database&#8230;.</p>
<p><strong>The VB Code</strong></p>
<p>The next thing we&#8217;ll look at is the code in VB.net.  The example here is using VS2005 with the .NET 2.0 Framework.  It&#8217;s nothing fancy, and it should be forward compatible right up to the 4.0 Framework due out with VS2010.</p>
<p><span id="more-1247"></span></p>
<p>The first thing we&#8217;ll do is create a super simple class that will access the PHP file.</p>
<p>[code lang="vb"]</p>
<p>Imports System<br />
Imports System.Net<br />
Imports System.Text<br />
Imports System.XmlPublic Class clsAPI#Region " Class Variables "<br />
Private xURL As String                              ' URL to Call<br />
Private xPostData As Object                         ' Post Data to send to API<br />
Private xResp As String                             ' Response from PHP API<br />
#End Region#Region " Properties "<br />
Friend Property URL() As String<br />
'Target URL<br />
Get<br />
Return xURL<br />
End Get<br />
Set(ByVal Value As String)<br />
xURL = NoNull(Value)<br />
End Set<br />
End PropertyFriend Property PostData() As Object<br />
Get<br />
Return xPostData<br />
End Get<br />
Set(ByVal Value As Object)<br />
xPostData = Value<br />
End Set<br />
End PropertyFriend ReadOnly Property XMLResponse() As String<br />
Get<br />
Return xResp<br />
End Get<br />
End Property<br />
#End Region#Region " Main API Code "<br />
Public Sub Connect()<br />
'Create a new WebRequest object with the specified URL<br />
Dim rq As WebRequest = WebRequest.Create(URL)'Set Method and Header information<br />
With rq<br />
.Method = "POST"<br />
.ContentType = "application/x-www-form-urlencoded"<br />
End With</p>
<p>'Send the data to the php page<br />
SendData(rq, PostData)</p>
<p>'Assign the response from the php page to the variable for XMLResponse<br />
xResp = GetXMLResponse(rq)<br />
End Sub</p>
<p>Private Sub SendData(ByRef req As WebRequest, ByVal data As String)<br />
'Store the post data as a byte array for passing to the page<br />
Dim b As Byte() = Encoding.ASCII.GetBytes(data)<br />
req.ContentLength = b.Length</p>
<p>Dim sr As Stream = req.GetRequestStream()<br />
sr.Write(b, 0, b.Length)<br />
sr.Close()<br />
End Sub</p>
<p>Private Function GetXMLResponse(ByRef req As WebRequest) As String<br />
Dim rs As WebResponse = req.GetResponse()<br />
Dim sr As Stream = rs.GetResponseStream()</p>
<p>'Create StreamReader to Convert stream to text<br />
Dim xr As StreamReader = New StreamReader(sr)</p>
<p>'Return the response as text<br />
Return xr.ReadToEnd()<br />
End Function<br />
#End Region</p>
<p>End Class</p>
<p>[/code]</p>
<p>There&#8217;s not a whole heck of a lot to this class, so feel free to add all the properties, methods, and everything else that should be in here with a proper application.</p>
<p><strong>The Other Functions&#8230;</strong></p>
<p>From here, we need to add two simple functions to a form (or anywhere else) to access the class.</p>
<p>[code lang="vb"]</p>
<p>Friend Function doAPIQuery(ByVal tProcName As String, ByVal tPostQuery As String, ByVal ResultName As String) As DataTable<br />
'Function Queries the Online Database and Returns a DataTable<br />
Dim ds As New DataSet("ds")Try<br />
Dim wbg As New clsAPI<br />
With wbg<br />
.PostData = tPostQuery<br />
.URL = "http://www.whateveryoursiteis.com/" &amp; tProcName<br />
.Connect()'Construct the Columns from the XML Nodes<br />
Dim dt As New DataTable<br />
ds = CreateDataSetFromXML(.XMLResponse, ResultName)'Create a StringReader and Pass the XML Response through it<br />
Dim sr As New StringReader(.XMLResponse)'Read in the XMLString to populate the table<br />
ds.ReadXml(sr, XmlReadMode.Auto)<br />
End WithCatch ex As Exception<br />
MsgBox(ex.Message, MsgBoxStyle.Exclamation, "doAPIQuery Error")<br />
End Try</p>
<p>'Return the DataTable<br />
Return ds.Tables(0)<br />
End Function</p>
<p>Private Function CreateDataSetFromXML(ByVal XMLData As String, ByVal ResultName As String) As DataSet<br />
'Function Reads an XML Field and Constructs DataTable Columns based on the results<br />
Dim xmlDoc As New XmlDocument<br />
Dim xmlNodes As XmlNodeList<br />
Dim xNode As XmlNode<br />
Dim baseDataNodes As XmlNodeList<br />
Dim ds As New DataSet("ds")</p>
<p>Try<br />
xmlDoc.LoadXml(XMLData)<br />
ds.Tables.Add(ResultName)</p>
<p>xmlNodes = xmlDoc.GetElementsByTagName(ResultName)<br />
For Each xNode In xmlNodes<br />
baseDataNodes = xNode.ChildNodes</p>
<p>'Create a Column for Each Node in the XML Result<br />
For Each basedatanode As XmlNode In baseDataNodes<br />
'If the Menu Item hasn't been added yet, do so now<br />
If ds.Tables(0).Columns.IndexOf(NoNull(basedatanode.Name)) &lt; 0 Then _<br />
ds.Tables(0).Columns.Add(NoNull(basedatanode.Name), Type.GetType("System.String"))<br />
Next<br />
Next</p>
<p>Catch ex As Exception<br />
MsgBox(ex.Message, MsgBoxStyle.Exclamation, "CreateDataSetFromXML Error")<br />
End Try</p>
<p>'Return the DataTable<br />
Return ds<br />
End Function</p>
<p>[/code]</p>
<p>And that&#8217;s that.  To have data returned from the PHP file that we created earlier we would need only to create a DataTable and populate it like so:</p>
<p>[code lang="vb"]</p>
<p>Dim dt as new DataTable("Result")<br />
dt = doAPIQuery("whatever.php", "reportid=99&amp;todate=2009-05-24", "Result")</p>
<p>[/code]</p>
<p>The doAPIQuery function sends and receives data through the API class, and the CreateDataSetFromXML function reads that XML response and converts it into a DataTable that can be used anywhere in the application.  Heck, the way this code is presented, there would be little problem adapting this if you wanted to create 100 different PHP files to do different functions and return different result sets.</p>
<p><a href="http://j2fi.net/wp-content/uploads/2009/05/panel.png"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-medium wp-image-1249" src="http://j2fi.net/wp-content/uploads/2009/05/panel-300x177.png" alt="Panel &amp; Gears" width="180" height="106" /></a>Is this the best way to have a VB-based application communicate with an online MySQL database?  Like everything else in the world, it depends.  Some would argue that this method is the lazy man&#8217;s way out of doing the job right, while others would argue this method would be sufficient for small custom applications built for a small business.  At the end of the day, it&#8217;s up to you to decide what the best solution is while designing an application.</p>
<p>That said, if you believe you have a better way of getting VB and MySQL to communicate without granting direct access to the database server over the web, I&#8217;d love to hear it.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://j2fi.net">Jason Irwin dot Net</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@j2fi.net so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://j2fi.net/2009/05/24/simple-api/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
