Some comments on Oracle's comparison of PHP and ASP.NET
Oracle recently published an outrageous article in a rather strange attempt to convince people that PHP is the best platform to write web applications. Not ASP.NET, which is not surprising coming from Oracle, but not Java either, which is a little more puzzling.
In this blog entry, I'm explaining what I thought when I read this paper. The disclaimer on the left applies, of course: these are my own opinions, and I'm not talking on behalf of my employer.
This article is completely unreal. Arguing that PHP is preferrable to ASP.NET is a very difficult exercise. I can imagine the marketing people at Oracle ordering this article and determining its conclusions even before it was written... It is even touching to see that the author can't hide all of the ASP.NET qualities nor all the problems of PHP.
Let's read the article together and comment it along the way.
Let's read the article together and comment it along the way.
First, the subtitle, "One developer's view of the pros and cons of the two most popular means of building web applications" should probably be more along the lines of "One PHP developer who has no clue what ASP.NET is reviews what he thinks are the pros and cons of the two most popular means of building web applications". I've built applications for years with both systems before I was hired by Microsoft, so I can probably spot most of the many voluntary or unvoluntary errors and inaccuracies in the text.
In the first paragraph, the author tries to convince us that PHP and ASP.NET fall into the same category of web platforms that "[embed] code into HTML pages with special tags that signal to a preprocessor that they contain code, and that it should do something with it". This is true of PHP, but not of ASP.NET, where the code can, but should not be in the HTML markup. Instead, a well-written page would have a declarative or templated part (the aspx file) and some codebehind (or not) that orchestrates the controls and communicates with other layers of the application if there are any.
So whereas PHP follows the flow of the page and inserts dynamic text in some places, ASP.NET separates the code from the declarative markup and has a much richer page lifecycle. Most important, in ASP.NET, the execution flow is distinct from the markup's flow.
This difference is absolutely fundamental and differentiates a platform that encourages spaghetti code from one that encourages good design and separation of concerns.
The author also tries with this simple sentence to have us believe that the "special tags" of PHP and ASP.NET are equivalent. Nothing could be more wrong: while PHP only has tags to signal the limits of the server code from the rest of the markup, ASP.NET's tags are really abstract representations for full-blown controls that embed complex behavior (such as treeviews, grids, etc.). While one forces you to output raw HTML, the other enables you to use familiar widgets like those that you would expect from a desktop application framework. Using PHP to create web pages is a little like creating desktop applications with a tool that would force you to draw every control using dots and lines (just a little, I'm pushing the analogy: PHP is not THAT bad). Abstractions are good.
So whereas PHP follows the flow of the page and inserts dynamic text in some places, ASP.NET separates the code from the declarative markup and has a much richer page lifecycle. Most important, in ASP.NET, the execution flow is distinct from the markup's flow.
This difference is absolutely fundamental and differentiates a platform that encourages spaghetti code from one that encourages good design and separation of concerns.
The author also tries with this simple sentence to have us believe that the "special tags" of PHP and ASP.NET are equivalent. Nothing could be more wrong: while PHP only has tags to signal the limits of the server code from the rest of the markup, ASP.NET's tags are really abstract representations for full-blown controls that embed complex behavior (such as treeviews, grids, etc.). While one forces you to output raw HTML, the other enables you to use familiar widgets like those that you would expect from a desktop application framework. Using PHP to create web pages is a little like creating desktop applications with a tool that would force you to draw every control using dots and lines (just a little, I'm pushing the analogy: PHP is not THAT bad). Abstractions are good.
The second paragraph is very touching because the author explains us why he is so biased. No comment.
So what is ASP.NET to Oracle (except for a menace)?
"ASP.NET works with scripted languages such as VBScript, JScript, Perlscript, and Python, as well as compiled languages such as VB, C#, C, Cobol, Smalltalk, and Lisp". Wrong. ASP.NET works only with compiled languages such as VB.NET and C#. There are .NET compiled versions of "scripting languages" like Perl, JScript or Python, though, and that's probably what caused this confusion.
The next paragraph is more or less accurate, but let's note for later that the author is aware of the fact that the .NET class library contains classes that do "image manipulation". Later, he'll tell us that "with ASP, however, you're investing from the very beginning, and you're spending for add-on technologies—libraries for doing graphics manipulations, for instance".
"in ASP.NET, integration with databases can be accomplished through ODBC". Technically, he's not lying, here, but he fails to mention that ODBC is just one of several ways to access a database, the one that should be used only if all other options are impossible. There are direct providers for Sql Server and Oracle, and third parties offer native providers for all major databases (including an Oracle provider for Oracle databases, in addition to the MS provider). Most importantly, these APIs derive from a common base, which makes it almost equivalent from a developer's point of view to develop against Sql Server or Oracle, or any other database. Whidbey also makes it a lot easier to make your code database-agnostic (like, I have to admit, Mono did before us). More on this later.
"ASP.NET's strength lies clearly in its clean design and implementation. It is an object-oriented programmer's dream, with language flexibility, and with sophisticated object-oriented features supported. In that sense, it is truly interoperable with your programmers' existing skills. Another strength of ASP.NET is the development environment." Say no more. ASP.NET rules! Oracle says so!
But don't worry, the next sillyness is in view: "But what you gain in robustness, you pay for in efficiency. ASP.NET is expensive with respect to memory usage and execution time, which is due in large part to a longer code path."
Oh? Really? What backs these gratuitous affirmations? Execution time? Can we have some pointers to check that? Because as far as I know, a web platform that is natively compiled and that has built-in page and fragment caching is very likely to be faster than a scripted, non-cached platform. Of course, you can compile PHP using a free tool, but it's an afterthought. And you have to pay for the page caching solution, whereas it come for free with ASP.NET.
I can see where the memory thing comes from. It is true that if you open the task manager on a server that's running an ASP.NET web site, you could be a little frightened by the amount of memory ASP.NET uses, if you know nothing about servers. Guess what! Memory that's not used is useless. The rational thing to do on a server is to use the memory you have (to cache stuff, for example). The quantity of memory that's used by ASP.NET can be configured in machine.config if you feel you can tweak it better than the default setting (which you usually can't, that's why it's the default setting).
The performance of ASP.NET is certainly sufficient for "small traffic" sites such as Microsoft.com, MSN, match.com, etc...
Oh? Really? What backs these gratuitous affirmations? Execution time? Can we have some pointers to check that? Because as far as I know, a web platform that is natively compiled and that has built-in page and fragment caching is very likely to be faster than a scripted, non-cached platform. Of course, you can compile PHP using a free tool, but it's an afterthought. And you have to pay for the page caching solution, whereas it come for free with ASP.NET.
I can see where the memory thing comes from. It is true that if you open the task manager on a server that's running an ASP.NET web site, you could be a little frightened by the amount of memory ASP.NET uses, if you know nothing about servers. Guess what! Memory that's not used is useless. The rational thing to do on a server is to use the memory you have (to cache stuff, for example). The quantity of memory that's used by ASP.NET can be configured in machine.config if you feel you can tweak it better than the default setting (which you usually can't, that's why it's the default setting).
The performance of ASP.NET is certainly sufficient for "small traffic" sites such as Microsoft.com, MSN, match.com, etc...
The "What is PHP" section is focused on database access, but fails to mention Sql Server as a possible database for PHP (this is an Oracle paper, after all).
It tries to convince you that database abstraction is bad (just to tie you to Oracle, but you got that part yourself) because you so badly need these marvelous Oracle features: LOB, BLOB, CLOB and BFILE.
This coming from the same people who will explain later that OS independance is an absolute necessity...
It tries to convince you that database abstraction is bad (just to tie you to Oracle, but you got that part yourself) because you so badly need these marvelous Oracle features: LOB, BLOB, CLOB and BFILE.
This coming from the same people who will explain later that OS independance is an absolute necessity...
Seriously, database independance is an important feature for many modern applications.
Due to the uncoordinated development by different teams, the database access libraries in PHP have been notoriously inconsistent to the point where the code you'd write to access a MySql database is different from the code you'd write to access a PostgreSQL database. Not in the SQL queries, which is more or less normal, but in the actual PHP code! So other people have developed so-called database abstraction layers (dba, odbc, etc.)... which do not work with all databases, and are of course largely inconsistent with one another as well as with any specialized provider.
In the "strengths and weaknesses", we only see weaknesses, except for platform independance (but not database independance), open-source development (if you happen to consider that as a strength), and "a smaller code path," whatever that means.
He misses a few other important weaknesses, like the fact that its library is terribly messy, being a function library instead of a hierarchical class library like that of .NET or Java, and having horrible names (can you guess what readline_completion_function does? It "Registers a completion function". Yes, I know, that's not very much clearer, but this is the kind of documentation you get with PHP: no sample, no clear explanation).
The author then goes on to showing us how great the new PHP5 is (whereas to say the truth, it barely gets where Python was years ago). The code example is absolutely hilarious. Anyone writing this kind of code in a job interview with me would be politely but immediately shown the door. I have to show you:
He misses a few other important weaknesses, like the fact that its library is terribly messy, being a function library instead of a hierarchical class library like that of .NET or Java, and having horrible names (can you guess what readline_completion_function does? It "Registers a completion function". Yes, I know, that's not very much clearer, but this is the kind of documentation you get with PHP: no sample, no clear explanation).
The author then goes on to showing us how great the new PHP5 is (whereas to say the truth, it barely gets where Python was years ago). The code example is absolutely hilarious. Anyone writing this kind of code in a job interview with me would be politely but immediately shown the door. I have to show you:
class blue {
function openFile ($inFile) {
if (file_exists ($inFile)) {
# code to open the file here
} else {
throw new Exception
("Cannot open file: $inFile");
}
}
}
if (file_exists ($inFile)) {
# code to open the file here
} else {
throw new Exception
("Cannot open file: $inFile");
}
}
}
$blueObj = new blue ();
try {
$blueObj->openFile ('/home/shull/file.txt');
$blueObj->openFile ('/home/shull/file.txt');
} catch (Exception $myException) {
echo $myException->getMessage ();
echo $myException->getMessage ();
# rest of exception handling code here
}
}
Do you really think you should throw an exception to test a perfectly normal application error condition? Shouldn't you throw and catch something more specific than Exception? Shouldn't openFile be static? This code sucks. Just write this instead:
$fileName = '/home/shull/file.txt';
if (file_exists($fileName) {
#work with the file
} else {
echo "File: $fileName does not exist";
}
if (file_exists($fileName) {
#work with the file
} else {
echo "File: $fileName does not exist";
}
If this is how you explain the benefits of OOP and structured exception handling to PHP users, we'll just get unamageable and ununderstandable object-oriented spaghetti code instead of plain unmanageable spaghetti code.
I'm skipping the "security comparison" FUD for now, I'll get back to it later. Let's go directly to the "database coding examples" section.
"With ASP.NET, however, it's a little more complicated, because you have the option of any of a number of languages to choose from." How that makes it more complicated and how it has anything to do with database programming elude me completely.
Let's look at the code sample. The PHP code does absolutely nothing except create and destroy a database connection (please note the "very elegant" error handling code, though). The destructor prints a useless message for no identifiable reason.
Let's look at the code sample. The PHP code does absolutely nothing except create and destroy a database connection (please note the "very elegant" error handling code, though). The destructor prints a useless message for no identifiable reason.
class oracle_object {
protected $theDB;
protected $user;
protected $pass;
protected $db;
protected $theDB;
protected $user;
protected $pass;
protected $db;
function __construct($u, $p, $d) {
$this->user = $u;
$this->pass = $p;
$this->db = $d;
}
$this->user = $u;
$this->pass = $p;
$this->db = $d;
}
function db_open () {
$theDB = @OCILogon($this->user, $this->pass, $this->db);
db_check_errors($php_errormsg);
}
$theDB = @OCILogon($this->user, $this->pass, $this->db);
db_check_errors($php_errormsg);
}
function db_close() {
@OCILogoff($theDB);
db_check_errors($php_errormsg);
}
@OCILogoff($theDB);
db_check_errors($php_errormsg);
}
function __destruct () {
print ("so long...");
}
print ("so long...");
}
}
Many things can be said about this code: the fields are not encapsulated, and it is generally not a good idea to open a connection if you're not going to use it right away (because of connection pooling), so if you write a database access helper class, opening and closing the connection should be done just around the request to the database itself. At least in .NET where the connection pool is automatically managed.
And now, the VB.NET code that is supposed to be equivalent to the one above:
And now, the VB.NET code that is supposed to be equivalent to the one above:
Class Sample
Public Shared Sub Main()
Dim oraConn As OracleConnection = New OracleConnection("Data Source=MyOracleServer;Integrated Security=yes;")
Dim oraCMD As OracleCommand = New OracleCommand("SELECT CUSTOMER_ID, NAME FROM DEMO.CUSTOMER", oraConn)
oraConn.Open()
Dim myReader As OracleDataReader = oraCMD.ExecuteReader()
Do While (myReader.Read())
Console.WriteLine(vbTab & "{0}" & vbTab & "{1}", myReader.GetInt32(0), myReader.GetString(1))
Loop
Console.WriteLine(vbTab & "{0}" & vbTab & "{1}", myReader.GetInt32(0), myReader.GetString(1))
Loop
myReader.Close()
oraConn.Close()
End Sub
End Class
oraConn.Close()
End Sub
End Class
Why are they skipped lines in there? To make the code seem longer? And who wouldn't notice that this code does a lot more than the PHP code?? It opens a connection, queries the database and outputs the results before it closes the connection. So what does this prove? Absolutely nothing.
It should be pointed out that displaying database data in a table in ASP.NET Whidbey is as simple as that:
<asp:SqlDataSource runat="server" ID="myDataSource" DataSourceMode="DataReader"
ConnectionString="<%$ ConnectionStrings:MyOracleConnectionString%>"
SelectCommand="SELECT CUSTOMER_ID, NAME FROM DEMO.CUSTOMER" />
<asp:GridView runat="server" ID="MyGridView" DataSourceID="myDataSource"/>
<asp:SqlDataSource runat="server" ID="myDataSource" DataSourceMode="DataReader"
ConnectionString="<%$ ConnectionStrings:MyOracleConnectionString%>"
SelectCommand="SELECT CUSTOMER_ID, NAME FROM DEMO.CUSTOMER" />
<asp:GridView runat="server" ID="MyGridView" DataSourceID="myDataSource"/>
Of course, this is the quick and dirty solution, and you can substitute an ObjectDataSource to the SqlDataSource if you have properly defined your own DAL, business and service layers.
Now, let's "make a choice"... The author pretends to think that "[PHP's] only weakness is its lack of a pure and perfect OOP implementation". Err, see above. He then says "Though language constructs do help, ultimately, good coding is a matter of practice, execution, good habits, and discipline". Sure, but what if you are incapable of that? I'm not pointing to anybody... Oh well, yes I am.
We now can read a very informative (not!) table "summarizing" the weak and strong points of each platform. The criteria that have been chosen are completely arbitrary, as well as the "values" in the table (what do $$, weak or strong mean? Is it something that I can measure? How much is $$?). We also note that ASP.NET security is "strong" whereas one of the main points against it according to the author is precisely the security. Consistency anywhere?
Price. ASP.NET is free, and the TCO of Windows Web Server Edition can be favorably compared to that of a LAMP approach (see http://www.microsoft.com/mscorp/facts).
Speed. I really don't know. I have yet to read a performance study that compares PHP and ASP.NET performance. If anyone knows one, I'd be happy to talk about it. The article does not point to such a study. PHP has a reputation for speed, as does ASP.NET.
"Speed is not the only consideration. Memory usage is also important." See above? Why is that important? We won't find out from the article.
"Speed is not the only consideration. Memory usage is also important." See above? Why is that important? We won't find out from the article.
Security. This is my favorite part. After all the usual FUD about IIS security, the author gives us a link to a site that proves him wrong. This is very nice of him. Let's follow the link to www.securityfocus.com and do less than 5 minutes research. First, let's do a search on IIS 6. The first article that comes out has this to say about IIS:
"[IIS] provides a reliable and secure infrastructure to host web applications."
"[IIS] provides a reliable and secure infrastructure to host web applications."
Then, let's look for vulnerabilities: choose Microsoft / IIS / 6.0. Results:
1 (One!) x-site scripting vulnerability in a web administration tool that's not even installed by default
1 (One!) x-site scripting vulnerability in a web administration tool that's not even installed by default
And three for ASP.NET
OK, let's do the same for Apache 2. Results:
25 (Twenty-five!) vulnerabilities, including DOS and Buffer Overflows
Wow, that's a lot! Let's look for PHP 4 now... Results:
19 (Nineteen!) vulnerabilities, including integer overflows, arbitrary file disclosures, cross-site scripting, etc.
25 (Twenty-five!) vulnerabilities, including DOS and Buffer Overflows
Wow, that's a lot! Let's look for PHP 4 now... Results:
19 (Nineteen!) vulnerabilities, including integer overflows, arbitrary file disclosures, cross-site scripting, etc.
Is this guy so stupid that he really thinks noone will click his link and verify what he claims? Or does he think his readers are stupid? In either case, I wouldn't give him a web site to develop...
Cross-platform applicability. Sure, if that's really paramount to you, choose J2EE ;) at least for the moment...
Open-source opportunity. Sure, if that's important to you. If consistency and accountability are more important, then I guess that's a different story.
And of course, one thing you won't hear about in Oracle's article is developer productivity. ASP.NET is the platform that will make your web developers the most productive, because it manipulates higher level abstractions, it handles all the plumbing for you and it encourages reusable code. But Oracle doesn't want you to know about that.