1. PHP 5 Enterprise Edition

    1/12/2006
    By eko, category: PHP

    Introduction

    Without dispute, “enterprise” is a much-disputed term in the software
    market. Many companies label their software as an enterprise application
    due to marketing reasons in the hope to grab a piece of the cake. PHP
    companies are not free from entering the “enterprise barkers”,
    especially now that PHP 5 is out[1] – mostly because it offers
    better objectoriented and XML programming features compared to PHP4. But
    does that qualify to meet the demands of the enterprise market? The past
    years have seen a convergence in the enterprise application sector,
    favouring a component-based and multi-tier application architecture.
    Hence, the question is also whether such architecture can be built for
    mission-critical projects with available PHP software. The evolution of
    enterprise software development has mainly been driven by the Java 2
    Enterprise Edition (J2EE)[2]. Today, J2EE could be named the de facto
    industry standard for the development of distributed multi-tier
    architecture applications. It is backed up by industry leaders like Sun,
    Oracle, BEA, and IBM. This article will compare PHP’s software stack
    with what’s available in (and for) J2EE, to overcome the typical
    Java versus PHP discussions that usually focus on language features, but
    do not take into account the overall picture. Basically, this article
    assembles a PHP5EnterpriseEdition(PHP5EE).

    In a Nutshell
    This discussion of J2EE and a comparable PHP software stack called
    PHP5EE provides useful information for:

    * Project managers and developers as guidelines for decision making
    in the pre-implementation phase of an enterprise Web project, who are
    looking for an over-view of available software alternatives in the Java
    and PHP world
    * Developers who want to make their PHP application more standardized
    or generic in the way that J2EE is
    * Developers who want to integrate elements of J2EE to be used by
    their PHP application or vice versa

    What is “Enterprise”?
    The enterprise software domain is an endless field of exploration and
    evaluation, a moving and complex target. To approach this topic, I will
    first formulate a broad working definition of the term “enterprise”:

    An application can be regarded as enterprise software if it is useful
    for large enterprises in that it solves a set of problems which are
    particularly relevant to such organizations. As we can tell from this
    definition, both business and technical factors account for the success
    of an enterprise application; hence they will be addressed in the
    following sections. You should bear in mind that J2EE or PHP5EE are
    software development frameworks, tools, or execution platforms; rather
    then ready-made applications. Due to this fact, there are basically
    three actors involved: (1) enterprise customers in need of a certain
    application, (2) companies who develop those applications based on an
    enterprise architecture and respective libraries, (3) vendors of
    software development kits (SDK) for the enterprise market, like Sun
    Microsystems.

    Business Factors
    Some of the main business factors for customers and suppliers of
    enterprise applications as well as frameworks are:

    * The general economic situation influences the financial resources
    available for decision-makers.
    * Time-to-market can be significantly reduced for application
    developers if they can rely on third-party libraries and do not have to
    reinvent the wheel. This factor is also important for suppliers of SDKs
    to stay ahead of alternative frameworks.
    * Especially when seen from the perspective of application
    developers, it is highly important that the used framework is a
    dynamicallydevelopedproduct to stay competitive in the market.
    * Most enterprises have to deal with legacy systems that form a
    heterogeneous set of software installations and want them to be
    integrated as good as possible.
    * Concerning a heterogeneous environment, cross-platform portability
    might well be a crucial factor, although not for those enterprises that
    stick to one platform due to strategic decisions.
    * For those companies who offer basic software infrastructure like
    libraries, frameworks, and tools, the in-markettrackrecord can decide
    upon the success of their products, because the more market experience,
    the higher the credibility and anticipated reliability of the software.
    * It needs a pool of skilled programmers who can deal with a certain
    enterprise product to ensure the quality and sustainability of the
    product and related services.

    Of course, there are many more factors, but for now we shall concentrate
    on how the mentioned factors apply to the J2EE versus PHP5EE discussion.
    The following evaluation is meant to draw the general picture; I will
    elaborate on each point from the technical perspective later.

    General Economic Situation
    In an economic downturn, as it has been experienced after the Internet
    hype, costs need to be reduced. Some argue that this favours Open Source
    solutions over proprietary software. Whether this is true or not, it
    does not really play a role for our comparison of J2EE and PHP5EE,
    because both architectures can be implemented with Open Source software.
    Given that J2EE is supported by Sun and other industry leaders, more
    money and work time is devoted to the further development of J2EE
    compared to the PHP Web development market.

    Time-To-Market
    Due to this fact, the proposed PHP5EE has, generally speaking, a slower
    time-to-market then J2EE – at least if compared on a similar
    technical level of code quality. Of course, both frameworks have their
    strengths and weaknesses if we speak of time-to-market. One could claim
    that it took PHP four years to go from pseudo object orientation in PHP
    4 to a more mature model in PHP 5. On the other side, PHP was already
    there before JavaServer Pages (JSP)[4] came to life, which allows
    program snippets to be conveniently embedded into HTML. To be more
    precise, we should take a closer look at how J2EE is developed compared
    to the proposed PHP5EE. J2EE is an effort mostly directed by Sun,
    channelled by a standardization procedure called the
    JavaCommunityProcess[3]. Despite its name, the specifications are not
    defined by a community of Open Source programmers, rather by a board of
    companies. This is very contrary to how the PHP engine and parts of the
    PHP5EE are specified, because this is very much an Open Source effort.
    Thus, no concerted development plan exists for the PHP5EE, which makes
    it hard to predict how dynamically the software stack in total is
    developed and maintained. Of course, once a J2EE developer makes use of
    Open Source products like JBoss, Struts, Turbine, and Cocoon, she faces
    the same dilemma.

    Legacy Systems
    As far as the integration with legacy systems and cross-platform
    portability is concerned, it is hard to say whether J2EE or PHP5EE is
    better equipped to do the job, they are rather the same. It is certainly
    a myth that Open Source products are, in general, better in dealing with
    heterogeneous environments just because everyone can contribute an
    extension. The more important point is how long a product has been in
    use in the enterprise market, since decision makers assume that the
    answer to this question is directly correlated to the problem solving
    power of the product. This assumption must be modified if there exists a
    single-vendor monopoly, then, the software will likely be less adaptive
    to specific customer needs. This is not the problem with PHP5EE because
    its development model is that of a reactive Open Source community.
    Though the development process of J2EE is different, it seems to be open
    enough for proprietary and open source projects[5] to ensure diversity
    and adaptiveness.

    In-Market Track Record
    The big players in the J2EE market certainly have a long in-market track
    record, which is not the case for most companies that do PHP application
    programming, leaving aside that none of them can be called a big
    company. This disadvantage is lessened by the fact that the PHP5EE is
    based on Open Source software – some of its parts are developed by
    several coders from different small to medium size companies to
    eventually create high quality software. Although the in-market track
    record seems to be less important on the product-side when using Open
    Source software, it nevertheless plays a role on the service-side of the
    enterprise software business.

    Skilled Programmers
    Currently, it is hard to find skilled PHP developers[6]. One reason
    might be that since PHP is easy to learn, many think they are good
    programmers after some months of PHP, thus making it difficult for
    companies to separate the wheat from the chaff. Another valid point
    might be that there are simply more well-paid Java jobs out there?
    Furthermore, J2EE is an established concept in the enterprise market and
    a good bet for aspiring programmers to get a job after having uplearned
    the framework. On the contrary, many PHP frameworks exist and
    slowlyconverge only because of PEAR[7]. Evaluating and learning about
    the various PHP frameworks still takes a lot of time and leaves
    programmers with a vague job perspective.

    Technical Factors
    Next, we take a look at the technical factors that define an enterprise
    framework. Some of them are directly correlated to the earlier-
    mentioned factor and others that have not been mentioned here. (The
    “others” could as well be discussed as business factors since many
    technological concepts, say, `interoperability’, have been
    identified as key selling points in the enterprise market.) For now, we
    concentrate on the technology:

    * Fast prototyping and development is a technical factor that plays
    together with the time-to-market business factor. Enterprise frameworks
    are supposed to help developers concentrate on the business logic of the
    application and to ship with libraries that implement often needed
    solutions.
    * Enterprise platforms should be based on a modern
    programmingparadigm, which of today is object oriented programming
    (OOP).
    * An enterprise application should have the ability to support
    increasing numbers of users. In other words, it should be scalable.
    * The performance of an enterprise solution effectively describes how
    fast the program can be executed.
    * Enterprise applications should provide highavailability, which is
    achieved by a redundant cluster of machines to service requests.
    * What has been discussed above concerning legacy systems translates
    to two technical factors that enable communication with other software
    systems – interoperabilityandextensibility.
    * Maintainability describes how easily an application can be
    analyzed, modified, updated, or deployed after (or even before) it has
    reached production status.

    Again, there are surely more technical factors that could be added. For
    now, let’s take a closer look at how these points relate to the J2EE
    versus PHP5EE comparison.

    Fast Development
    PHP as a programming language, combined with its wide range of available
    extensions, offers indisputably quick and easy Web development
    capabilities. However, this does not automatically qualify it as the
    better choice for enterprise development, when compared to J2EE, as far
    as fast development is concerned. Due to the level of complexity that
    enterprise applications need to handle, they are intrinsically complex
    software. It is a feeble argument that PHP application development is
    simpler because it adheres to the Unix-way of “keep it simple, stupi”.
    Sure, single parts of an enterprise application should always be as
    intuitively comprehensible as possible, but the whole system will,
    inevitably, be complex because of the many dependencies between the
    parts and several different technological concepts that co-exist in such
    an application. PHP5EE can definitely serve as a better platform for
    fast prototyping, but once it comes to the point where the production
    system has to be implemented, J2EE is not necessarily slower in terms of
    development speed.

    Modern Programming Paradigm
    Concerning OOP, PHP has made a big step forward[8] with the latest major
    release. PHP 5 allows programmers to define class methods and attributes
    as private, public, protected(ppp), which is important for a clean
    separation of classes. The ppp-modifiers are a prerequisite for more
    orthogonallydesigned applications that incorporate less coherent object
    couplings, thus making them easier to modify. The PHP 5 engine further
    supports this, since it ensures that classes defined as abstract or
    interface need to be inherited or implemented, allowing for more
    sophisticated (and actually verified) class roles. The Standard PHP
    Library (SPL) “is a collection of interfaces and classes that are meant
    to solve standard problems”[9]. Currently, it provides several iterator
    interfaces; in the future, more design patterns will be added. Due to
    several reasons[10], PHP 5 did not introduce Java-like namespaces or an
    import()function that could have helped to avoid clashes between classes
    or methods with the same name and additionally allow working with class
    packages for easier application deployment. However, this functionality
    can be partially mimicked with __autoload()[11]. Also new in PHP 5 are
    exceptions[12] with a try/catch-flow; just like what Java offers.
    Nevertheless, PHP 5 is still weaker in OOP compared to Java, but the
    strength certainly is that programmers can also do procedural coding
    with PHP 5 in cases where the OO-paradigm does not fit[13]. PHP 5 thus
    gives project managers and implementers the possibility to assess the
    trade-off between an inconsistent application of OOP mixed with
    procedural code and an application that better adapts to its environment
    with a variety of programming paradigms.

    Scalability, Performance, Availability
    I will not discuss the issues of scalability, performance, high
    availability in extenso, since there are already some good
    articles[14][15] available on the subject. When we talk about J2EE
    application servers, I will refer back to these factors concerning the
    `shared nothing cluster approach’ of PHP5EE.

    Maintainability
    The last point in the list of technical factors is maintainability.
    Those aspects of maintainability that affect the deployment of
    uplearned. Typically, they are implemented as Enterprise JavaBeans
    (EJB)[25] or a Servlet[26].

    * Components are executed in their own runtime environment, also
    called a container, that can handle specific routines associated with
    the respective component type.
    * J2EE is designed to allow for multi-tier applications that separate
    display, logic, and storage, and adhere to the Model-View-Controller
    (MVC)[27] pattern. JavaServer Pages (JSP)[28] is the predominant
    technology to implement the display layer.
    * Apache Struts[29] is a well-known Open Source implementation of the
    MVC pattern in Java.
    * Components like EJBs are executed in a multi-threaded environment.
    * Additionally, components can be accessed in a distributed fashion,
    for example via Web Services or Remote Method Invocation(RMI-IIOP)[30].
    * Application servers provide a consistent runtime environment to
    J2EE applications. JBoss[31] is a well-known Open Source application
    server.

    Figure1 summarizes the above; the diagram is taken from the J2EE
    tutorial[32]. In the following section, I will present implementations
    of some of the above J2EE elements in PHP that let you assemble a kind
    of PHP 5 Enterprise Edition. Their limitations and missing pieces will
    also be discussed. Although there are many Open Source PHP frameworks
    available online, most of them adhere to a monolithic concept; they are
    simply not tested or mature enough and eventually do not meet the
    earlier-mentioned technical factors.

    J2EE Architecture.

    PHP5EE Libraries
    J2EE comes with a multitude of libraries for various tasks, just like
    the PHP community does – but are they qualitatively the same, do
    they cover the same tasks? There are some libraries available for PHP
    that provide solutions where no equivalent exists for Java, but I will
    not concentrate on them here, because my focus is to ask for equivalents
    from the J2EE perspective. The PEAR project is the most remarkable
    attempt to create a consistent repository of OO PHP libraries.
    Currently, it includes more then 260 packages. Since PHP 5, extensions
    can as well have an OO-interface, they are part of the PHP Extension
    Community Library (PECL)[33] as well as those that are procedural, or
    both. PECL currently develops over 90 packages. Unfortunately, only
    those extensions that are part of the PHP core are thread-safe; most of
    the others are not. This is not the fault of PHP, since PHP itself is
    thread-safe. The problem is that many extension developers did not
    implement the proper functionality to ensure the extension runs in a
    multi-threaded environment like Apache 2 Web server. Here, we shall
    briefly go through the important J2EE libraries and see what can be done
    in PHP:

    * Databases : PHP has used relational databases since its early days.
    Therefore, many solutions for database connectivity exist. A unified
    approach like the Java Database Connectivity (JDBC) package is provided
    by the well-maintained PEAR::DB[34]. Its successor, called PEAR::MDB[35]
    has a better and faster overall design, but not the same user base. Also
    underway is a PHP extension available through PECL called PHP Data
    Objects Interface (PDO)[36] – a very promising attempt to provide a
    native abstract database interface which is not yet stable enough for
    enterprise production.
    * Authorization and Authentication : A J2EE server provides
    mechanisms for user authorization and authentication. It knows several
    authentication mechanisms and most of them can be done with
    PEAR::Auth[37] for PHP5EE. For authorization tasks, J2EE servers ship
    with a sophisticated model based on realms, users, groups, and roles
    – something that PEAR::LiveUser[38] provides in a similar way. For
    now we shall leave aside the issue of authentication and authorization
    of components like EJBs and come back to them when we talk about
    components in PHP
    * XML :Interfaces for XML processing can be found in J2EE’s JAXP
    API and covers SAX, DOM, and XSLT. The new PHP 5 XML extensions[39]
    based on libxml and libxslt provide the same functionality. So PHP5EE is
    well equipped in this field.
    * Web Services :No matter, whether the Web Services hype of the past
    years corresponds with the usefulness of this technology, it is still
    regarded as a must-have enterprise feature. J2EE comes with the JAX-RPC
    API that implements Web Service technologies like XML-RPC, SOAP, WSDL,
    UDDI. For PHP5EE, basic and some sophisticated Web Services features
    have been implemented in PEAR::SOAP[40] and PEAR::UDDI[41]. Since PHP5,
    a SOAP extension[42] has been built into the PHP core, however, it lacks
    features and has not been widely used. Java’s Web Service interfaces
    have the clear advantage in that they are more advanced and tested.
    * Transactions :A transaction library takes care that data integrity
    is ensured in operations within multiple (distributed) programs. With
    transaction control, components can roll back an operation and revert to
    the previous state in case the operation fails. The Java Transaction API
    (JTA) helps developers to manage and coordinate transactions across
    heterogeneous Enterprise Information Systems (EIS). In J2EE lingua, EIS
    describes all systems that contain data that needs to be accessed by
    J2EE like RDBMS, LDAP, or any third-party application or legacy system.
    JTA can, for example, span transaction-safe updates to multiple
    databases from different vendors. I have not heard of anything similar
    available for PHP up to now.
    * Message services :The Java Message Service (JMS) API enables
    communication between J2EE components and applications, and forms the
    basis for a Message Oriented Middleware (MOM). JMS is a key feature of
    J2EE concerning the management of distributed business logic, since
    components can be loosely coupled via an asynchronous messaging
    architecture. Recently, PHPMQ[43] has been released to serve the same
    purpose. It is based on the MantaRay messaging bus[44] and the Java
    extension for PHP[45] that lets PHP call the Message-
    ProviderConnectorJava class, which acts as a wrapper around the
    java.rmi.Namingclass with the help of a PHP class named messaging. As
    the latest release, version 0.2.2, of PHPMQ suggests, the current code
    is a working and promising proof of concept but not meant to be used in
    a production scenario.
    * Connectors :The Java Connector Architecture (JCA) is an abstraction
    layer to allow a unified and transparent access to legacy systems aka
    EIS. So-called Resource Adapters that link into JCA are available for
    J2EE from SAP and Siebel for example. I have found nothing that could
    leverage this functionality to the PHP5EE.

    This overview shows that it is currently an impossible undertaking to
    assemble a PHP5EE equivalent to J2EE. In some fields, PHP5EE libraries
    are on a par with those in J2EE concerning production use; in others,
    they cover the basic functionality or are not yet production ready;
    there are also fields where simply no equivalent PHP implementation
    exists. It must be noted that interfaces of PHP libraries are, almost
    always, very different to similar Java packages, which cannot be a
    criteria per se when talking about the quality of the APIs. Instead, an
    important factor is that the presented PHP packages are more or less
    inconsistent. Many PEAR packages are still implemented in PHP 4 OO, they
    do not make use of exceptions, nor of abstract, interface, private,
    public, protected. Most of the Open Source PHP code available is
    currently in
    the phase of transition from PHP 4 to PHP 5. Furthermore, most of the
    PHP5EE libraries are implemented in PHP (PEAR packages), while others
    are PHP extensions written in C (PECL packages). Although a PHP5EE
    developer does not necessarily have to know C to make use of extensions,
    the faster execution time of extensions makes one wish that all PHP5EE
    libraries would be implemented as PECL packages. This circumstance
    indicates that highly skilled PHP5EE programmers should know C –
    something that is not the case for J2EE developers, because they can
    stick to the Java language.

    PHP5EE Components
    Speaking of components, one could argue that the PHP engine itself is to
    PHP5EE what the JSP/Servlet container is to J2EE. With numerous template
    systems available for PHP, the multi-tier separation of display and
    business logic can be achieved in a similar quality with both platforms.
    The situation is very different when it comes to multi-threaded and
    distributed business components like EJBs. This technology can be
    mimicked on a low level with either a non-blocking stream[46] that calls
    another PHP script; or on *nix only with the Process Control Functions
    (PCNTL)[47] used by PEAR::PHP_Fork[48] that resembles the
    java.lang.Threadclass interface. A far better solution is offered by the
    Site Resource Manager (SRM)[49] that, ironically, calls its EJBs
    “bananas” instead of “beans”. This project was started a few
    years ago and the main developer (Derick Rethans) has recently resumed
    development after some months of pause. Many bugs have been fixed in the
    current CVS version. So SRM now performs quite stable.

    SRM allows a PHP script to call remote classes aka SRM Bananas, to
    define application level variables, and more. A SRM client is
    implemented with the SRM extension that hooks into PHP just like any
    other extension. Listing1exemplifies a call to an SRM banana, which
    consists of instantiating the SRM constructor with the connection
    parameters for the SRM daemon on the remote host. Then an SRM
    Application (aka SRM Banana) is created with the connection object and
    the name of the class that is called. Finally, a method of the remote
    object is invoked.

    The SRM daemon manages the classes that can be called from SRM clients.
    The daemon utilizes the PHP SAPI to interface with PHP and execute a
    remotely called SRM Banana locally that is then passed to the SRM
    client. All SRM Banana files follow a naming convention and reside in a
    directory that has been defined as the include path for the daemon in
    its srm.iniconfiguration file. Figure 2 visualizes the complete SRM
    architecture and Listing 2 shows how an SRM Banana is implemented –
    they are created by extending the Bananaclass and defining the methods.
    To actually make the class an SRM Banana, it needs to be instantiated
    and the Banana::run(0 method executed – only then can the SRM daemon
    properly pass the object to the remote SRM client. Derick’s work on
    SRM is part of his employment at eZ System, an Open Source PHP CMS
    company. This shows that there actually exists growing corporate
    interest in having a technology of distributed business logic components
    for PHP. Unfortunately, SRM development focuses on PHP 4 and there are
    no definite plans to port it to PHP 5 as yet.

    PHP5EE Application Servers
    What keeps all J2EE elements together is the application server with the
    proper runtime environment and various tools included. There are no
    out-of-the-box Open Source solutions available for PHP5EE, similar to
    JBoss for Open Source J2EE. Not only do PHP5EE developers have to make
    up the framework on their own with several third-party products like
    PEAR classes, but they also have to compose a PHP5EE application server
    on their own. This means, there is no integrated solution for the
    deployment, execution, maintenance, clustering, load balancing, and so
    on of a PHP5EE product, as yet. They need to combine several proprietary
    and Open Source software like Cisco’s Local Director, Linux Vertial
    Servers, and Squid for load-balancing; SiteScope for performance
    monitoring; rsync, scp, and sftp for deployment, and so on. Although,
    this does not sound like a consistent runtime environment, note that the
    Open Source tools mentioned here are common knowledge in the PHP
    community. Looking at it from that perspective, there actually exists a
    relatively consistent PHP5EE application server based on best practices
    – it is just not available as one single product.

    Of course, the PHP5EE application server cannot compete with the variety
    of high-end application servers available for J2EE. For example, PHP
    favours a shared nothing cluster approach due to its Apache-centric
    design of forked processes, which allows “infinite horizontal
    scalability in the language itself” as Rasmus Lerdorf put it in his
    article ” Do you PHP?”. Shared nothing means that every server
    has its own filesystems with its own copy of applications running in the
    cluster. This system becomes problematic when the application needs to
    be updated often. There are many J2EE application servers that follow
    either the shared nothing or shared disk approach. A shared disk cluster
    obtains the applications running in the cluster from one single storage
    device. Thus, such a device becomes a single point of failure and a
    single logical device interface interacts with redundant storage media
    (SAN).

    PHP5EE with J2EE
    To overcome the deficits of a PHP5EE, Zend and Sun have partnered in
    defining and implementing a standard for PHP to interact with Java –
    the JSR 223[50] specification. It aims at positioning PHP for front-end
    applications that interact with business logic done with J2EE. A
    reference implementation can be found behind the Download pagelink of
    the specification’s homepage. The JSR 223 also specifies how PHP can
    be called from within Java, and Zend also offers a PHP Enabler for Sun
    Java System Web Server[51], but I won’t go into details on that. The
    realization and usage of JSR 223 is quite similar to the afore-mentioned
    Java extension, which has been in the `experimental’ stage for a
    long time. PHP is integrated in the Java Servlet environment with a Java
    wrapper around the PHP engine (which is why a Tomcat server needs to be
    set up if you want to use JSR 223 for the Web), which makes it quite
    simple to call Java classes from inside of a PHP script as Listing 3
    demonstrates. It remains to be seen when JSR 223 is ready for production
    environments and how reliable it will be.

    Summary
    It is obvious from this comparison that PHP5EE cannot keep up with J2EE.
    So, whenever PHP 5 is claimed to be ready for the enterprise, it must be
    doubted as far as large and complex projects are concerned. That said,
    however, the earlier statement must be refined because it is not really
    clear how to define a piece of software as a large and complex
    enterprise application. The most adequate interpretation of the
    comparison is that PHP5EE best serves the needs of small- to medium-size
    enterprises (SME), because they often do not need high-level frameworks
    and application servers as offered by the J2EE
    market. Furthermore, PHP5EE is strong in solving Web-related tasks that
    don’t heavily depend on distributed and multithreaded business
    components like EJBs. If they do so, the JSR 223 is a promising sign
    that PHP can expand to this niche of the enterprise market. By some
    means or the other, the objective of this article was to play the
    devil’s advocate and compare the Open Source PHP software stack with
    what is available with J2EE. Some might argue that this was an unfair
    comparison, but I would counter that only by comparing with the best
    products in the market, the deficits of PHP become clear and can be
    addressed properly. In no way should this article be a dispraise of all
    the good volunteer work that happens in the PHP community, but it
    definitely needs more successful companies in the PHP market who
    continuously climb up the ladder and extend the PHP software stack. The
    most important task for the community as well as the companies seems to
    be to actually create a kind of PHP5EE that constitutes a consistent and
    qualitatively managed framework for enterprise Web development with PHP.

    By Sandro Zic

2 Comment(s)

  1. Sandro Zic, 04.Dec.2006 12:47 pm

    Hehehehe mas eko makasih lho dah di posting di blognya

    kapan2 maen nang angkringan maneh yo…
    ngobrol2 PHP 5 Enterprise Edition


  2. Weh… gini nih… bagus… punya ilmu ya ditulis gitu….
    sip deh….


Add Comment

Recent Post

Recent Comment

Archive