Showing posts with label PHP. Show all posts
Showing posts with label PHP. Show all posts

September 26, 2008

Closures in PHP 5.3

If early releases are any indication, PHP is scheduled to receive some pretty significant updates in version 5.3. In addition to namespaces, I'm particularly interested in the addition of closures.

According to object-oriented programming expert Martin Fowler, closures are defined as a block of code that can be passed to a function. However, delegates (C#), anonymous classes (Java) and function pointers (C) don't quite qualify because the following also needs to be true:
  1. Closures need to be able to refer to variables already present in scope at the time they're defined.

  2. Closures shouldn't require complex syntax (I personally think this point is a tad subjective).
As you can imagine this capability might be helpful when writing a function that repeatedly executes a block of code specific to the function. It wouldn't make sense to refactor this block of code to the class level if it doesn't get used anywhere outside the function. With closures, the block of code distinct to the function may be defined and repeatedly called upon without having to bloat your classes.

PHP's upcoming syntax for closures is shaping up to be comparable to the C# 2.0 implementation. In the .NET world closures first arrived as anonymous methods in C# 2.0 (these were later simplified into lambda expressions in C# 3.0).

For comparison's sake C# anonymous methods look something like this:
/* Returns true if tOne and tTwo are  both evenly 
divisible by the denominator (denom) */
public bool EvenlyDivisible(int denom, int tOne, int tTwo)
{
//Define the closure
Predicate evenlyDivisible = delegate(int testNum)
{
//Note that denom is defined outside closure scope
if ((testNum % denom) == 0)
{
return true;
}
else
{
return false;
}
};

//Use the closure as necessary
if (evenlyDivisible(tOne) && (evenlyDivisible(tTwo)))
{
return true;
}
else
{
return false;
}
}
When released, a comparable implementation in PHP 5.3 will probably look something like the following:
/* Returns true if $tOne and $tTwo are  both evenly 
divisible by the denominator ($denom) */
function EvenlyDivisible($denom, $tOne, $tTwo)
{
$evenlyDivisible = function ($testNum) use ($denom) {
//Note that $denom is defined outside closure scope
if (($testNum % $denom) == 0)
{
return true;
}
else
{
return false;
}
};

//Use the closure as necessary
if ($evenlyDivisible($tOne) && ($evenlyDivisible($tTwo)))
{
return true;
}
else
{
return false;
}
}
For additional information please check out the closure proposal on php.net.

July 03, 2007

Experiments with Moodle

MoodleThe other day I was asked to help install Moodle for a friend. If you've not heard of it, Moodle is an open source PHP application used (as their site describes) to "help educators create effective online communities." It includes blogs, wikis and content management combined to compliment lesson plans with the synergy of online collaboration and social interaction. I won't get into reviewing the application itself but I will say a few things about my experience with the installation process.

For starters Moodle requires a web server, PHP and a relational database. My goal was to set up the application on an existing Windows / IIS / MySQL shared hosting account on Go Daddy.

To prepare for this activity I decided to take Moodle for a spin on my MacBook Pro where I'm running Apache, PHP 5 and MySQL. The installation required two additional items I was not expecting: a cron job and permissions for the application to write to a special "Data" directory. Nonetheless, the automated setup script worked flawlessly and I was up and running within fifteen minutes.

I naively thought that the Windows installation would be similar. However, no matter what I tried I couldn't get the setup script to run properly. Perhaps due to hosting limitations? Maybe I made a mistake somewhere along the line? One way or another, I was quick to switch to a Linux plan where, similar to OS X, set up was quick and painless.

I know others have had success with Moodle on Windows but all the same I'd recommend a Linux server as the most appropriate vehicle for this application.

October 13, 2006

Windows Vista as a Development Platform

As Windows Vista RC2 hit last week I've come across several mildly disturbing articles regarding the integrity of Vista as a development platform. First off was the announcement of SP1 Beta for Visual Studio 2005 on Somasegar's blog. Sounds like good news, right? Well, further down he also reveals that Vista will not support Visual Studio 2002 or Visual Studio 2003. In addition, he admits that Visual Studio 2005 will most likely suffer from compatibility issues beyond those addressed in SP1. In my mind this doesn't communicate strong support for what is supposed to be Microsoft's flagship development platform. I imagine this issue could easily stop most developers from trying Vista anytime soon due to the fact that they still need to continue supporting older applications via older versions of Visual Studio.

There have also been rumors going back and forth debating Java's ability to keep up with the new "Aero" look and feel in Vista. Thankfully, it appears as if this will only be an issue for older versions of Java.

On a positive note, IIS 7 in Vista will finally elevate PHP to a first class citizen. The newest version of Microsoft's webserver is on target to introduce a FastCGI host. Such a change will honor the single-process-per-request execution model of PHP, but do so much more efficiently than traditional CGI. For more information check out this blog entry by Mike Volodarsky (member of the IIS team).

July 29, 2006

Approximating Master Pages in PHP

Most sites on the Internet have common design elements that do not change from page to page. Usually, only content or minor navigational cues vary. To handle the unchanging aspects, developers have often relied on server-side includes - dividing regions like headers, side navigations and footers into separate files.

But now with the advent of ASP.NET 2.0 Master Pages offer a more complete templating alternative. With Master Pages an entire template common to the site is stored in one file with a .master extension. Developers add a ContentPlaceHolder control inside a Master Page to indicate where they would like their page specific content to appear. Then one or more Web Forms may be set up to automatically dress themselves with the shared visual components defined in the Master Page.

So is it possible to make PHP emulate this behavior? To some degree, yes, with output buffering and one server-side include file that represents the "Master Page." Lets say we are aiming to create our HTML by combining this template file and a content file (we'll call these master.php and index.php, respectfully). Our simplified example will aim to achieve the following end result:



The template that will act as our "Master Page" will need to contain all aspects of the design labeled "Template Specific." Since no such control like the ContentPlaceHolder exists, we will use PHP variables to indicate where we would like our page specific content to appear.

master.php
<html>
<head>
<title><?php echo $pagetitle; ?></title>
</head>
<body style="margin-top:20px;margin-left:20px;margin-right:20px;">
<table width="100%" border="0" cellpadding="10" cellspacing="0"border="0">
<tr bgcolor="#33FFFF">
<td colspan="5"><h2>Template Specific Header</h2></td>
</tr>
<tr bgcolor="#EEEEEE">
<td nowrap><a href=#">Navigation Link 1</a></td>
<td nowrap><a href="#">Navigation Link 2</a></td>
<td nowrap><a href="#">Navigation Link 3</a></td>
<td nowrap><a href="#">Navigation Link 4</a></td>
<td width="100%">&nbsp;</td>
</tr>
</table>
<br />
<table width="100%" cellpadding="10" cellspacing="0" border="0">
<tr>
<td width="30%" valign="top" bgcolor="#EEEEEE"><strong>Template Specific
Navigation</strong><br /><br />
<a href="#">Link 1</a><br />
<a href="#">Link 2</a><br />
<a href="#">Link 3</a><br />
</td>
<td width="70%" valign="top"><?php
echo $pagemaincontent;
?></td>
</tr>
</table>
<br />
<table width="100%" cellspacing="0" cellpadding="10" border="0">
<tr>
<td colspan="2" bgcolor="#33FFFF">Template Specific Footer</td>
</tr>
</table>
</body>
</html>

Now any pages that we would like to have adhere to the template only need to define the page specific variables and include our master.php file.

index.php
<?php
//Buffer larger content areas like the main page content
ob_start();
?>
<em>Page Specific Content Text</em><br />
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed nonummy nibh euismod tincidunt ut laoreet
dolore magna aliat volutpat. Ut wisi enim ad minim
veniam, quis nostrud exercita ullamcorper
suscipit lobortis nisl ut aliquip ex consequat.
<br /><br />
Duis autem vel eum iriure dolor in hendrerit in
vulputate velit molestie consequat, vel illum
dolore eu feugiat nulla facilisis ats eros et
accumsan et iusto odio dignissim qui blandit
prasent up zzril delenit augue duis dolore te
feugait nulla facilisi. Lorem euismod tincidunt
erat volutpat.
<?php
//Assign all Page Specific variables
$pagemaincontent = ob_get_contents();
ob_end_clean();
$pagetitle = "Page Specific Title Text";
//Apply the template
include("master.php");
?>

Even though it's not perfectly aligned with ASP.NET's Master Page feature set, the technique described above allows us to consolidate what might otherwise be numerous server-side include files.

February 23, 2006

PHP to ASP.NET Scalar Query Port

Lets pretend for a moment that you are writing a bit of PHP code that determines if a value is present in your database. Such code might look something like the following:
<?php
function UserExists($username, $db) {
$sql = "SELECT * FROM Accounts WHERE UserName = '" . $username . "'";
$result = mysql_query($sql, $db);
if (mysql_num_rows($result) > 0) {
return true;
}
else {
return false;
}
}
?>

Now suppose you've been asked to switch this application to ASP.NET 2.0/C#. What would you do? One possible port of this scalar query is listed below:
protected bool UserExists(string userName)
{
int results = 0;
SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["Sample ConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT COUNT(*) FROM Account WHERE UserName = @username";

try
{
SqlParameter paraUserName = new SqlParameter("@username", SqlDbType.NChar, 40);
paraUserName.Value = userName;
conn.Open();
cmd.Parameters.Add(paraUserName);
results = (int)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
finally
{
conn.Close();
}

//Return true if userName was found in the database
if (results > 0)
{
return true;
}
else
{
return false;
}
}

December 17, 2005

New Software Galore

It's amazing just how many new iterations of well-known server and browser software has been released in the last few months:

Apache 2.2
Php 5.1.x
MySql 5.0
Ruby On Rails 1.0
.NET 2.0
SQL Server 2005
Firefox 1.5

It will likely take a bit of time (and kicking the tires) before these technologies are considered ready for mass consumption by the server admins. All the same, they continue to signify a steady march forward for internet growth and development...

October 25, 2005

The PHP Collaboration Project

Over the course of the last couple of weeks the PHP Collaboration Project has been unveiled. This effort is being supported by many big players in the industry (such as IBM, Oracle, MySQL and Intel among others). So what does this group aim to achieve through this collaboration?

The full description of goals indicate that initially two primary agendas will be pursued. The first is to team up with the Eclipse Foundation to create a new development IDE specifically optimized for PHP developers. While this isn't exactly a new idea, I must say that I would welcome such a standardized tool with the support and weight of most of the industry behind it. Dreamweaver is nice, but it's pricey and not really designed to address my object oriented programming needs like a full IDE could.

The second goal of the PHP Collaboration Project strikes me with less enthusiasm. It calls for the creation of a new framework called the Zend PHP Framework, described as follows:
A Web application framework which standardizes the way PHP applications are built. The Zend PHP Framework accelerates and improves the development and deployment of mission-critical PHP Web applications.
I was under the impression that this framework is already in place...and that it goes by the name PEAR. I guess I'm mistaken. The Zend PHP Framework documentation is rich with words like "simplicity", "clean" and "extensible". In my humble opinion whatever framework they devise will likely be a little clunky until someone gets around to adding namespace support (currently implemented in PAT). Namespaces would likely go a long way towards helping them achieve the organizational goals of this proposed framework.

Unfortunately, it doesn't appear as if Zend or their partners have released any code yet. Perhaps I'm a bit of a skeptic, but I find it difficult to ignore the coincidence that this collaboration was realized mere months after the EDC reported a significant decline in PHP's adoption and usage. You can almost hear Zend exclaim "Oh snap, PHP kind of sucks for larger enterprise sites and people are starting to notice! We'd better do something!"

Well, they've announced something. Hopefully they'll follow through and help usher in some standardized tools that will continue to make PHP a viable option for web applications.

October 15, 2005

Data Models

One of the many features that was celebrated by the introduction of .NET was the flexibility of the new ADO.NET data model. For the first time developers had an opportunity to address in-memory data in a standardized way thanks to the System.Data namespace. It allowed access to the data source of choice either via DataReaders (a similar concept graced classic ASP) or by using the new DataSet object. With DataSets developers no longer had to rely on hitting the database each and everytime they required a result set for their pages. Instead they could load the result set once as an in-memory representation of their data and then proceed to work with it as necessary.

While DataSets allow for a great amount of flexibility, they are not a perfect solution for every occasion. For instance, they're generally not a great option to use if you need to cycle through an incredibly large result set. Using a DataSet in this circumstance will likely strain the memory of your server. Additionally, DataSets are a tad bit slower than DataReaders. These are important considerations when planning your solution.

So what is PHP's equivalent of ADO.NET's rich data model? Well...there isn't such a thing. At least as of this writing there is no component within the standard PHP distribution that allows for this kind of behavior. PDO is on the way for PHP 5.1, but this only offers a standard API for addressing multiple databases - not anything in the way of an abstact in-memory representation of the targeted data.

For the most part I get the sense that the PHP community doesn't see this as a problem. There are other worthy priorities that are currently steering this open source project (for example, Unicode support in PHP 6). And even though PHP supports object-oriented features, its extensions are widely functional (SPL and MySQLi are among the small group of exceptions). With this in mind, PHP doesn't strike me as an environment where a heavy object like a DataSet is likely to flourish.

All the same there are times when something like a DataSet would come in handy in PHP. Say, for example you pull a small to medium-size result set from your database. The page that you are working on requires you to sort or transform this data and display it in several different ways. In ASP.NET this would be no problem. You could simply use a DataView object on your DataSet and be on your way. But how could this be addressed in PHP? You could query the database each and every time your page needs to order/organize this result set...but this is bound to slow down your application.

You could definitely write your own data model in PHP or search for an open source implementation - these are very viable options. Here's a cheap way to emulate partial functionality of the DataSet in PHP:
<?php
//Select resultset and save it's rows as elements in an array
$sql= "SELECT * FROM TABLE";
$result = mysql_query($sql, $db);
$resultarr = array();
$resultcount = 0;
while ($resultrow = mysql_fetch_array($result)) {
$resultarr[$resultcount] = $resultrow;
$resultcount++;
}

/*
Now throughout this page you can use PHP's array functions to transform the result set for each of the times the data has to be displayed differently
*/
?>

This approach is quick and dirty but it may allow you to reduce the queries on your page while you are preparing or searching the web for a more robust open source option.