Platinum Partner
php,silverlight,visual studio,.net & windows,expression blend

Silverlighting Your PHP, Part 3: Bringing PHP Into Visual Studio

Blending PHP with Silverlight may seem like an unholy union. First of all, Visual Studio still doesn’t support PHP development without an add-in. Second, you need a Windows box in order to run .NET code. But if you’re willing to set aside your trepidation, you’ll find that Silverlight development in Visual Studio has a lot to offer the PHP developer.

The first two articles in this series explored using PHP to create XAML and using Expression Blend to create more complex XAML for your PHP. The goal in both of those demonstrations was to show what you could do without any .NET assemblies. In other words, using XAML and JavaScript, you could create a Silverlight app that could run on any platform.

Read the other parts in this series:

 

But as much as you can do with those tools, Visual Studio Web Developer 2010 Express, a free download, gives you even more building blocks for a full-featured, data-driven Silverlight app that leverages rather than replaces your existing PHP code.

To demonstrate this, here’s a walkthrough that will Silverlight your PHP in a different way. Rather than generating XAML, you’re going to start with a PHP app that creates as its end product a simple XML data file. Then you’ll build a very basic Silverlight app that makes use of one of the many pre-rolled Silverlight controls that comes with Visual Studio, the DataGrid Control. With a little C# madness, you’ll bind the DataGrid control to your PHP-generated XML file, giving you a very cool PHP-driven data display. Last, you’ll also practice a simple technique for incorporating your PHP code into the Visual Studio project in a way that allows you to deploy the entire app at one time.

Note that since this is a Visual Studio app and will be using .NET assemblies, you’ll need to deploy this to IIS on a Windows box with .NET Framework 3.5 installed.

 

Member Registration Form in PHP

Start with a basic PHP member enrollment form. Member of what – who knows. But the goal of the page will be to save typical registration data to an external XML file.

Create a folder called “MemberGrid” in your webroot, for example C:/inetput/wwwroot/MemberGrid. Under that, create a subfolder called “xmldata”. As sample data to start with, save the following to a file called members.xml within your xmldata folder:

<?xml version="1.0"?>
<members>
<member>
<memberName>Apollo</memberName>
<memberFunction>God of Music</memberFunction>
<memberStatus>God</memberStatus>
<memberDescription>Rides a chariot all day, dances all night.</memberDescription>
</member>
<member>
<memberName>Athena</memberName>
<memberFunction>Goddess of Wisdom</memberFunction>
<memberStatus>God</memberStatus>
<memberDescription>Currently living as Tina Fey.</memberDescription>
</member>
</members>

 

Next, save the following PHP code to memberForm.php within MembersGrid. This form simply collects member data and appends it to members.xml. PHP provides multiple techniques for reading and writing XML data to an external file. This form reads the file into a DOMDocument and creates new elements from the form data.

<html>
<head>
<title>PHP Entry Form</title>
</head>
<body>

<?php

if (!isset($_POST['memberName'])) {

?>

<form action="index.php" method="post">
<p>Member Name: <input type="text" name="memberName" /></p>
<p>Member Function: <input type="text" name="memberFunction" /></p>

<p>Member Status
<input type="radio" name="memberStatus" value="Titan" /> Titan
<input type="radio" name="memberStatus" value="God" checked="checked" /> God
<input type="radio" name="memberStatus" value="Demigod" /> Demigod
<input type="radio" name="memberStatus" value="Hero" /> Hero</p>

<p>Member Description::<br />
<textarea rows="5" cols="50" name="memberDescription" ></textarea></p>

<p><input type="submit" value="Add Member"></p>

</form>

<?php

}
else {

$memberFile = new DOMDocument;
$memberFile->Load('xmldata/members.xml');

$memberList = $memberFile->getElementsByTagName('members')->item(0);

$newMember = $memberFile->createElement('member');

$memberName = $memberFile->createElement('memberName');
$textNode = $memberFile->createTextNode($_POST['memberName']);
$memberName->appendChild($textNode);

$memberFunction = $memberFile->createElement('memberFunction');
$textNode = $memberFile->createTextNode($_POST['memberFunction']);
$memberFunction->appendChild($textNode);

$memberStatus = $memberFile->createElement('memberStatus');
$textNode = $memberFile->createTextNode($_POST['memberStatus']);
$memberStatus->appendChild($textNode);


$memberDescription = $memberFile->createElement('memberDescription');
$textNode = $memberFile->createTextNode($_POST['memberDescription']);
$memberDescription->appendChild($textNode);

$newMember->appendChild($memberName);
$newMember->appendChild($memberFunction);
$newMember->appendChild($memberStatus);
$newMember->appendChild($memberDescription);

$memberList->appendChild($newMember);

unlink('xmldata/members.xml');
$appended = $memberFile->save('xmldata/members.xml');

echo('<p>New data added (return code: ' . $appended . ')</p>');

}

?>

</body>
</head>

 

Since this code writes to an external file, you’ll need to open up Write permissions on the xmldata folder, as in Figure 1.

 

Take a moment to look over the code. As mentioned, this is a basic form handler, i.e it either presents the form or processes the data. In this case, “process” means add it to an aggregate file. Nothing fancy happening here – no edits, no deletes, no form validation.

But if you’ve read the first two articles in this series, you’ll also notice no XAML. No formatting of any kind. When silverlighting your app, this would present one of the first and biggest opportunities to give your users a richer experience. One easy change to make, for example, would be to separate the form UI from its handling and use a Silverlight form to collect the data.

Before moving on, test your PHP app. Submit some new data and check the resulting XML file. You should see your results added as a new <member> node within the <members> root.

 

Silverlight Project in Visual Studio

As mentioned, Microsoft provides the Express version of Visual Studio as a free download. Fortunately for web developers, it’s all you need to build your Silverlight app.  In fact, if you’re new to this end of the web, you can use Microsoft’s Web Platform Installer to download Visual Studio, Silverlight, SQL Server Express,  and a PHP engine. Check out Silverlight’s Get Started page for more info. Or you can download Visual Studio 2010 Express for the Web at http://www.microsoft.com/express/Web/. This also includes the Silverlight SDK preinstalled.

Once you’re set up and ready to go, fire off a new Silverlight project and call it MemberGrid.

 (Click for larger image)

 

Check the option to “Host the Silverlight application in a new Web site.”

 (Click for larger image)

 

When your new blank project first opens up, all you get is a blank canvas. Technically speaking, this is actually an empty Grid control, not a Canvas control. You’ll see in the toolbox on the left a list of other controls. Similar to Expression Blend, Visual Studio offers a tremendous amount of prebaked functionality that you can drop into your app, things like form controls, a date picker, a calendar, and media controls.

It also includes a set of data controls for hooking up an external dataset. That’s what you’re going to use here. Drag the DataGrid control onto the canvas and resize it to fill the entire box.

 (Click for larger image)

 

 

The DataGrid does just what it sounds like – pulls data into a preformatted grid. This grid presents the data in resizable columns of fixed or variable width, which, as of Silverlight 4, can be sorted in ascending or descending order. All you have to do to enable this functionality is hook it up to the data source, typically a SQL Server database.

In this case, you’re going to hook it up to an external XML file. Yes, the file you just created in your PHP app.

In your Solution Explorer on the right, under MemberGrid.Web, create a new folder called xmldata. Within that folder, add an existing file: members.xml.

 

Again, you may need to navigate to this folder in Windows Explorer and add security permissions to Write to the folder, which you’ll need later on. Also, you may notice in the Properties pane that your members.xml file was added to the deployed project as “Content”. This is a good thing. Usually, items in the solution are bundled in the application’s .xap file on deployment, which makes it easy to deploy the project but difficult to edit with an external script. But since your members.xml file was added with the Build Action set to “Content”, that means it will be copied to your deployment destination but not bundled into the .xap. The only other property you have to change is setting Copy to Output Directory to “Copy if newer”. This should keep Visual Studio from overwriting your data if you deploy changes after your app has been in operation for awhile.

One last bit of configuration business before you start coding. You’ll need to add a reference to the System.Xml.Linq library. You should be able to add the v4.0 component by right-clicking on the Reference folder in the Solution Explorer and selecting the System.Xml.Linq .NET component.

 

 

But you may need to navigate to the reference file manually. If that’s the case, go to the Browse tab and drill down to /Program Files/Microsoft SDKs/Silverlight/v4.0/Libraries/Client and choose System.Xml.Linq.dll.

 

 

 

Add Some C# Code

Before adding the PHP code, go ahead and hook up your data source. This involves a bit of coding, so start by naming the DataGrid control. In the XAML code below your canvas, find the name of your DataGrid and change it to “dgMemberGrid”.

 

 

While you’re down there, change AutoGenerateColumns to True, otherwise your data will be hooked up but won’t actually appear in the grid.

 

 

In the Solution Explorer, right-click on MemberGrid and add a new Class. Call it MemberRecord.

 (Click for larger image)

 

Open up MemberRecord.cs. In the constructor, add the following:

public string Name { get; set; }
public string Function { get; set; }
public string Status { get; set; }
public string Description { get; set; }

 

Open the code-behind for MainPage, i.e. MainPage.xaml.cs. In the reference list, add that reference to the Linq library:

using System.Xml.Linq;

 

Replace the remainder of the code with the following:

namespace MemberGrid
{
public partial class MainPage : UserControl
{
DataGrid memberGrid;
XDocument xMembers;

public MainPage()
{
InitializeComponent();
loadXMLFile();
}

private void loadXMLFile()
{
WebClient xmlClient = new WebClient();
xmlClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(membersLoaded);
xmlClient.DownloadStringAsync(new Uri("../xmldata/members.xml", UriKind.Relative));
}

private void membersLoaded(object sender, DownloadStringCompletedEventArgs e)
{
xMembers = XDocument.Parse(e.Result);
setGridDatasource();
}

private void setGridDatasource()
{
var memberList = from memberXml in xMembers.Descendants("member")
select new MemberRecord
{
Name = Convert.ToString(memberXml.Element("memberName").Value),
Function = Convert.ToString(memberXml.Element("memberFunction").Value),
Status = Convert.ToString(memberXml.Element("memberStatus").Value),
Description = Convert.ToString(memberXml.Element("memberDescription").Value)
};
memberGrid = this.FindName("dgMemberGrid") as DataGrid;
memberGrid.ItemsSource = memberList;
}
}
}

 

Take a close look at this code and you’ll see several things going on.

First, you have many ways to hook up data. If you were going to use a static XML file that never changed, probably the easiest way to do it would be to bring it into the project as an Embedded Resource so that it gets bundled in the .xap file, then reference it in the code as a local resource. But since the file will be updated from outside the Silverlight app, you’ll want to reference it as an external file, which means creating a WebClient object, as you can see in loadXMLFile().

The advantage of using this technique is that you can also use it to reference a remote XML feed, for example an RSS feed.

As you can see from the flow of this code, page instantiation launches the XML file load asynchronously. When that’s complete, it triggers the membersLoaded() routine, which parses the XML Document and kicks off setGridDataSource().

And that’s where the goodness takes place. Similar to DOMDocument->getElementsByTagName in PHP, you use Linq to select all “member” elements from your XML Document, then iterate through them, instantiating a new MemberRecord object for each one. Still using Linq, you then hook up the various XML nodes to their corresponding MemberRecord properties.

Once your collection of MemberRecord objects has been created, your last step is to set the source of your dgMemberGrid to that collection. Once that’s done, Bang – DataGrid.

Try running the solution. You should get a simple web page with a DataGrid that displays the two sample records in your members.xml file. Already, you can begin to see the power of Silverlight in adding huge amounts of functionality to your PHP app. With relatively little coding, you have a resizable, sortable data grid that dynamically displays your data source.

 

Mix In Some PHP

To set up for deployment, you can mix in your PHP file without actually executing it. Right-click on MemberGrid.Web and choose Add -> Existing Item. Navigate to memberForm.php and add it. This copies the file to your project directory. Under the properties of the file, set Build Action to “Content” and Copy to Output Directory to “Copy always”.

 

 

For the real test, deploy the whole application to your original web directory for this thing. Right-click on MemberGrid.Web in the Solution Explorer and choose Publish. In the Publish Profile, select “File System” as the Publish Method and navigate to your deployment directory for the target. Click Publish.

 

 

While you can’t actually code and debug your PHP script through Visual Studio without a 3rd party add-in, this is a good way to collect the whole blasphemous bundle into one place for ease of deployment.

 

Run the App

Give it a go! Navigate to your memberForm.php page and enter some test data.

 

 

After you submit it, navigate to MemberGridTestPage.html. If all went well, you should see something like this:

 

 

While this walkthrough shows you some of the potential of Visual Studio in creating a Silverlight app with your PHP code, it doesn’t even address the whole issue of side-by-side development. With a coder at one end of the office working in Visual Studio and a designer at the other end working in Expression Bend, both parties can work on the same app at the same time. And face it, this one needs a little dressing up.

Using some of the techniques in the previous walkthroughs in this series, as well as the DZone Refcardz “Getting Started with Silverlight and Expression Blend,” you or the designer next to you could build out the UI while the coding is still taking place. You could add more XAML elements, some animation, maybe some new events like triggering a detail popup when you click on a row in the datagrid.

But mostly, you can continue to leverage your PHP code in new ways with very little investment in training and development software.

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}