Blog






Archive for the ‘General’ Category

PHP dot NET

Saturday, December 26th, 2009

Introduction

In PHP 5 there are new OO features for private, protected and public variables in the script, in addition it includes extensions that can communicate with engine and provides a greater ease for supporting external object models such as Java, COM, .Net and Cobra. This empowers COM support, which had been target for hack due to limitations in the extension code and the script using the extension. So we can now rewrite the COM support which would be compatible with PHP 4 COM extension.

What is to be left?

The functions/features that are not present in the PHP 5 COM support are as follows. They have been removed because these are nasty hacks which make COM idea useless, and are not well defined in the manual.

com_addref(), com_release() - script should not worry about refcounts

com_get(), com_set(), com_invoke(), com_propget(), com_propset(), com_propput() - use regular PHP OO syntax to get or invoke methods or set properties.

com_isenum() and $com->Next() - use the foreach() syntax described below instead.

com_load() - use the new operator and the COM class instead.

So, all the weak points have been left. The new things that have been added are stated below.

Iterators

While working with VBscript code, in .vbs admin scripts or from an ASP site , we regularly notice the code stated below:

<%

set domainObject = GetObject("WinNT://Domain")
for each obj in domainObject
    Response.write obj.Name & "<br>"
next

%>

The equivalent code in PHP 4 COM is:

<?php

$domainObject = new COM("WinNT://Domain");
while ($obj = $domainObject->Next()) {
    echo $obj->Name . "<br>";
}

?>

Now VB/COM hackers will wonder what the Next()is for in the code snippet. Well this is not the actual method and it cannot be done in other COM supported languages. This syntax has been dropped in PHP 5 for a better foreach() statement:

<?php

$domainObject = new COM("WinNT://Domain");
foreach ($domainObject as $obj) {
    echo $obj->Name . "<br>";
}

?>

Exceptions

Errors arising from within COM code could not be handled in a proper way in PHP 4, except that PHP would let you know that error occurred by E_WARNING. But you would never have a proper way to know precisely the location, and its debugging.

Structured exception handling (try, catch() and throw()) have been introduced in PHP 5. The built-in com_exception class allows us to define COM exceptions to PHP. Following code is written to track errors in the script:

<?php

$com = new COM("...");
try {
    $com->call_a_method();
}
catch (com_exception $e) {
    print $e . "\n";
}

?>

The catch block handles the error as is appropriate to your script. The com_exception class is extension of default exception class provided by PHP, and has all of its properties. The getCode() method of the class makes the COM exception/error code available and makes error handling very easy.

Variations

The support for VARIANT type feature of COM is not well documented in PHP 4. These are COM equivalent of the PHP variable. It can hold integer, string, object, or floating point values. The difference between them is that COM variant has much greater diversity than a PHP variable, and expressing all of them as native PHP types directly is not easy.

The task of converting variants back and forth between COM and PHP was done by variant support in PHP 4. It resulted in some disgusting code in the extension to handle the conversions. All the possible conversions are not handled by it and buggy too. There was a possibility of loss of information as conversions are made.

The support for variant in PHP has been simplified on the basis of the logic that a variant value should only be converted to a PHP type when there is a direct 1:1 mapping. For rest of the cases, variant is regarded as an overload object and defer evaluation of it until it is used in an expression. We now can have much efficient and cleaner code, it also makes scripts faster even when we are working with variant arrays because the new OO model in PHP 5 allows us to access that variant object as though it were an array. It means there is no need to copy the contents of a array and put them into PHP array.

Cast handler is another trick made possible by the new OO model which makes smart interpretation of the contents of a variant. The Zend Engine automatically detects the context in which the variant (whose evaluation we deferred above until its usage as an expression) is being used (numeric, string etc.) and will direct the variant to convert itself into appropriate format. It is helping for us while deciding how to convert the value.

In addition to this, the extension has a large number of the COM variant API functions, allowing you to add, subtract, multiply, etc. variants according to the same rules used by VB. It is not very much useful for the common basic types (integers and strings), but is useful for the more exotic variant types (dates, currency values and so on).

ByRef parameters

COM object that expect their parameters to be passed by reference, can be commonly noticed. To make these methods work as expected in PHP 4, we had to manually create an instance of a VARIANT and set its ByRef flag. The OO model in PHP 5 allows the engine to determine which parameters are to be passed by reference on the basis of the method that it calls after querying COM. The values are set automatically for you allowing you to call these methods without jumping through hoop.

Event Handling

Event Handling is strictly not new for PHP 5 (I added it in PHP 4.3), but it is not well documented, so it is worth mentioning here. To receive notification of events you need to bind to a COM object using VB. The WithEvents clause when you Dim the variable and then Visual Basic would handle the magic. In PHP things are a much easier to follow and little different.

COM object (known as a “source”) needs to have another object that can “sink” those events for handling. This can be done by declaring a class to act as your sink and create an instance of it, and then bind the events to it:

<?php

class IESink {
    public $terminated = false;

    public function OnQuit() {
        $this->terminated = true;
    }

}

$ie = new COM("InternetExplorer.Application");
$ie->Visible = true;
$ie->Navigate("http://www.php.net/");
$sink = new IESink;
com_event_sink($ie, $sink, "DWebBrowserEvents2");

while (!$sink->terminated) {
    com_message_pump(4000);
}

print "finished!\n";

?>

On running the script IE will be launched and browse to the PHP home page and then will wait for you to quit the browser before continuing. The com_event_sink() function sinks the events from $ie to $sink and uses an interface named “DWebBrowserEvents2″. The name of outgoing dispinterface for your COM object must match the interface name. The com_print_typeinfo() function allows you to find out the name and also generate a template sink class.

.Net Support

.Net support is integrated in PHP 5. PHP 5 supports the instantiation of objects defined in .Net assemblies via the COM interoperability layer for .Net. PHP sees .Net objects as though they were COM objects, in implementation terms,  although instantiation is slightly different:

<?php

$stack = new DOTNET("mscorlib", "System.Collections.Stack");
$stack->Push(".Net");
$stack->Push("Hello ");
echo $stack->Pop() . $stack->Pop();

?>

This provides easy access to the.Net class library which has thousands of different classes. The .Net runtime must be installed onto your server to use this feature.

Summary

All the features makes the script shorter and easier to read and understand and a bit faster too.

To get an experience of all these you can download a PHP 5 snapshot from http://snaps.php.net. Currently, PHP 5 is released with limited features, since it is focusing on stabilizing the code ready for release. PHP 5 is already fairly stable. In case of problems, you can report them using http://bugs.php.net.

About the Author

This article is a shorten version of the article from Wez Furlong, a Core Developer of PHP and “King” of PECL (The PHP Extension Community Library), having contributed extensions such as SQLite, COM/.Net, ActivePHP, mailparse, the Streams API and more.

Why PHP is gaining on JAVA

Friday, September 11th, 2009

I’ll be brief with an illustrative example based on my own real facts:

Once upon a time there was a guy (me) interviewing a candidate to a software engineer position in my previous company.

After an hour of asking hundred of questions, questions about design patterns, architecture layers, technology comparisons, availability, XP or not XP, the difference between the goodness and the badness, why caterpillars becomes butterflies and so on, and tired of having really elegant answers to whatever I was asking about, finally occurred to me the definitive question:

In your opinion… what do you prefer in terms of web, php or java?

After, well, some seconds, the candidate answered to me:

PHP

I saw an smile on my face thinking about the response and why not java. Of course, I immediately ask to him in order to understand why PHP

Why?

Easy (he replied), PHP was designed to the web from the beginning… JAVA was just adapted to the web.

Well, I remember that I stammered ”well, …uhmm, ehmm”, but finally I was not able to discuss about that with this argument on the table.

I’m a confessed JAVA developer, but I promise to you: I - WAS - NOT - ABLE - TO - DISCUSS - ABOUT - THAT… Do you?

Come what may… start coding

Wednesday, September 2nd, 2009

extreme-programming

(no comments)

The power of the Intercepting Filter pattern in PHP

Tuesday, September 1st, 2009

Most of the people I have the pleasure to know and work with, all of them excellent PHP developers, old colleges and friends, don’t know about this amazing pattern: The Intercepting Filter.

Seems that this pattern is not commonly used at all in the PHP world for any reason. However, it’s one of the most powerful pieces within a framework.
So, give me 5 minutes to just introduce you to this pattern.

Imagine common tasks bound to every request in your site, tasks like to switch to a given language or currency, or even to authenticate your users via a cookie.
We must provide our application in order to intercept some information within the request in order to execute a task or the other one.

One of the most common way to do that in PHP, but not the most elegant at all, is to include one or more scripts in every page on our site in charge of parse the request and execute some tasks.
In fact, it’s really common to see a kind of common.php script that every page includes in. Not so maintainable, but very practical, right?

Problem is,

  • all the new pages we add to our site need to include this script? or just some of them?
  • if I change (for whatever reason) the script name and/or location, do I have to change all the pages including it in the entire site?
  • what happens if the script is included at the same time by other script like the typical header.inc that every page includes in order to decorate the site? how can we control the script execution from 2 including levels down?
  • assuming that we have hardcoded the sequence of common tasks in the script, how can we enable or disable some of the individual operations depending on some external factors like the url?

Those problems are appearing as soon as our projects grow. I have seen it in several projects, from the smaller and annoying ones to the most notable PHP projects, projects like word press or even os-commerce. Those projects are using hundred and even thousands of includes to script in order to ensure the execution of some common tasks. It’s more like a kind of includes-spaghetti code (I don’t know if this concept already exists, but I think is pretty illustrative).

So, intercepting filters is when it comes to the rescue:

Intercepting filters are basically classes in charge of intercepting some of the requests in order to execute tasks associated to them before (or even after) the execution of our logic.

Most important values on this pattern is the fact that

  • Filters are individual classes for individual tasks that you can activate or not selectively. Some time filters can be managed declaratively.
  • Filters are executed enchained in a given order defined by us, before and after giving the control to the FrontController and the rest of our application.
  • Filters can be maintained individually.

interceptingfilter

A sample of intercepting filter could be the one you use to intercept a cookie from the client and authenticate the user.

Filter code could be as simple as:

class CookieAuthenticationFilter extends __Filter {

    public function preFilter(__IRequest &$request, __IResponse &$response) {
        if(__AuthenticationManager::getInstance()->isAnonymous()) {
            if($request->hasCookie('auth_cookie')) {
                $cookie_identifier = $request->getCookie('auth_cookie');
                try {
                    $user = __ModelProxy::getInstance()->getUserByAuthCookieId($cookie_identifier);
                    if($user != null) {
                        __AuthenticationManager::getInstance()->setAuthenticatedUser($user);
                    }
                    else {
                        AuthCookieFactory::removeAuthCookie();
                    }
                }
                catch (Exception $e) {
                    AuthCookieFactory::removeAuthCookie();
                    __ApplicationContext::getInstance()->getLogger()->error('Error trying to log-in by cookie: ' . $e->getMessage());
                }
            }
        }
    }
}

And we can associate this filter to all our pages by just declaring it in the filters.xml file as following:

picture-4

You like it? please take a look here:

http://www.lionframework.org/d.filter-1

AJAX was never easier!

Monday, February 16th, 2009

Ajax should be as easy as just write a method in our server-side code and consume it from our client javascript. No more steps!
Well, let’s illustrate it with an example:
Imagine that we have created the following method (a method to log messages):


<?php

class MyEventHandler {

  public function logMessage($message) {
      __ApplicationContext::getInstance()
                          ->getLogger()
                          ->info($message);
  }

}

And we pretend to log messages generated from our client javascript.
According to our intro, it should be as easy as just call the logMessage method from our javascript code:

<script language="javascript">

  logMessage("Message to be logged from the server side");

</script>

In the other hand, we should be able to selectively define which methods are allowed to be consumed from the client (otherwise, imagine what a security issue).
In that sense, we could let the framework know that a method is callable from javascript by just adding a comment-based notation to them:
Let see it in terms of code:

<?php

class MyEventHandler {

  /**
   * @lion remoteService
   */
  public function logMessage($message) {
      __ApplicationContext::getInstance()
                          ->getLogger()
                          ->info($message);
  }

  public function myNonCallableMethod() {
      //whatever php code here
  }

}

With the remoteService annotation we are letting lion framework know that the method foo is callable from javascript code. The framework will perform the rest of the work for us.

As soon as AJAX is asynchronous by definition, a good question could be: what about values returned by server-side methods? How are them handled by the client javascript code?
I’ll explain it in my next post (maybe tomorrow) :)
Regards Antonio