PHP V5.3 using deferred static binding to enliven object-oriented programming

Source: Internet
Author: User
Tags assert empty generator implement inheritance php and variable ruby on rails

PHP V5.3 solves some of the problems of object-oriented programming (OOP) through its deferred static binding (LSB) feature. Learn how LSB fixes the OOP programming problem in PHP and how to implement some well-known object-oriented design patterns that require the use of LSB.
Object-oriented Programming (OOP) enables developers to reduce and simplify code by using data abstraction, encapsulation, modularity, polymorphism, and inheritance-with a deep understanding of OOP. The understanding of OOP features also allows PHP coders to take advantage of design patterns-some well-known algorithms for solving common problems. PHP has provided OOP functionality since V3.0, but until V5.3 arrives, the quirks of PHP's OOP implementations will prevent the use of some common design patterns. These oddities have completely disappeared as PHP V5.3 the delayed static binding (LSB) feature.

This article shows you some design patterns that are problematic before the advent of PHP V5.3, explaining why these patterns don't work. Then it shows the LSB characteristics of PHP V5.3, and gives a single example and active record design pattern.

Re-review of OOP

If you have ever contacted PHP OOP, you may decide not to use it for the following reasons:

Read one of the many blog posts claiming to be problematic with PHP OOP.

Tried to implement a simple design pattern, but did not succeed.

For PHP V5.3, OOP blogs are all positive, and the problem with PHP oop has largely been solved. It's time to go back to PHP OOP. In this article, you will see some design patterns that have been problematic before the advent of V5.3: Single, generator, factory method, and activity records.

The single example, builder, and factory method design patterns are considered to be created patterns because they assist in building objects. A singleton pattern may be one of the most commonly used OOP design patterns; It restricts the number of object instances of a class to only 1. For example, a database connection pool is an example of a singleton design pattern: We generally do not want the application to have multiple resource-intensive instances of the connection pool class.

When you need to detach the build and representation of complex objects, you need to use the builder design pattern, which allows you to create multiple objects using the same construction process. The implementation of the generator pattern can be complex, but once the generator is available, it simplifies the construction and use of objects created by the builder. A converter with output HTML, XML, or PDF capabilities is an example of the need to use a builder.

And the factory method pattern, as the name suggests, defines a method for producing objects in large quantities. You can use the factory method pattern when an application needs to create an object whose type depends on the implementation of the subclass.

The active record mode can be used to wrap relational database persistence methods within a domain class. Each instance of an active record is related to a specific row within the database. This class contains methods for inserting, deleting, and updating one or more rows within a database. The active record design pattern is defined by Martin Fowler in Patterns of Enterprise application architecture and is increasingly popular for use in the Ruby on Rails.

The implementation problem of the pre--LSB creation design pattern

All of the four design patterns mentioned above use static properties and methods. For example, take a look at the connection pool single example shown in Listing 1.

Listing 1. A simple single example

<?php
Class Connpool {
private static $onlyOne;
private static $count = 0;
Private Function __construct () {
Real-world DB Conn Stuff ...
}

public static function getinstance () {
if (!is_object (self:: $onlyOne)) {
$klass = __class__;
Self:: $onlyOne = new $klass ();
Self:: $count + +;
}
Return self:: $onlyOne;
}
public static function Getinstancecount () {return self:: $count;}
}

$db = Connpool::getinstance ();
ASSERT (1 = = $db->getinstancecount ());
$db 2 = connpool::getinstance ();
ASSERT (1 = = $db 2->getinstancecount ());
?>
Note this static $onlyOne variable. The variable is designed to hold an instance of the connection pool object. The static modifier before $onlyOne relates this variable to the class itself. $onlyOne variable is a class property because its scope is this class. The $onlyOne property has only one instance. When a property does not have a static modifier, it is called an object property because the property is unique to each instance of the class.

Note that the Connpool constructor method (called __construct) is empty. In a production implementation, you can use this method to create an interval for database connection pooling.

The static GetInstance method contains the template code for a single example. It creates a $onlyOne instance only if the static $onlyOne variable is empty. Notice how it uses the __class__ variable to get the type of the class and then create an instance of the class.

The Getinstancecount method is used only to prove that only one instance of the connection pool was created. The four lines of code at the bottom of Listing 1 prove that no matter how many times an instance of a Connpool pool class is requested, it returns the same object.

So so far, this single example is all right-until you decide you want to support multiple databases with subclasses of this connection pool in the form of an object-oriented inheritance tree. Listing 2 shows the inheritance tree (the instance counter and the constructor code are removed for clarity).

Listing 2. A single failed attempt to the instance when there is no LSB

<?php
Class Connpool {
private static $onlyOne;
protected static $klass = __class__;

public static function getinstance () {
if (!is_object (self:: $onlyOne)) {
Self:: $onlyOne = new self:: $klass ();
}
Return self:: $onlyOne;
}
}

Class ConnPoolAS400 extends Connpool {
protected static $klass = __class__;
}
$db = Connpoolas400::getinstance ();
ASSERT (' ConnPoolAS400 ' = Get_class ($db)); Fails
?>
To support multiple types of Single instance classes, the Connpool class adds a $klass static variable and assumes it is overwritten in subclasses. The ConnPoolAS400 subclass extends the Connpool class and provides its own version of the $klass property. Our expectation is that when an instance of the ConnPoolAS400 class is created, the $klass property saves the ConnPoolAS400. But when this code is executed, it does not run as expected. When the PHP utility function Get_class returns connpool instead of ConnPoolAS400, the declaration at the bottom of the code fails. The problem is that the getinstance method of the Connpool class uses its own $klass property version rather than the ConnPoolAS400 overlay.




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.