Advanced PHP V5 Object Research

Source: Internet
Author: User
Tags abstract array arrays constructor file system implement include require
Object | advanced

Advanced PHP V5 Object Research
This article describes some of the more advanced design-oriented features of PHP V5. These include various object types that allow you to detach components from your system and create reusable, extensible, scalable code.


To grasp the hint

The advantages of the object type and type hint are introduced first. A class defines a type. Any object that is instantiated from this class belongs to the type defined by that class. So, use the car class to create the car object. If the car class inherits the Vehicle superclass, the car object will also be a Vehicle object. This reflects the way we categorize things in the real world. But as you'll see, the type is not just a useful way to classify system elements. Types are the foundation of object-oriented programming, because types are a guarantee of good and consistent behavior. Many design tips come from this assurance.

"Getting started with the objects in PHP V5" demonstrates that the object gives you the interface. When the system passes the Dictionary object, you can determine that it has $translations arrays and summarize () methods. In contrast, associative arrays do not provide the same level of certainty. To take advantage of the clear interface provided by your class, you need to know that your object is actually an instance of Dictionary, not a imposter. You can manually verify this by using the instanceof operator, which is a handy tool for PHP V5 to introduce between object instances and class names.

instanceof Dictionary

If the given object is an instance of the given class, the instanceof operator resolves to true. The first time you encounter a Dictionary object in the calling method, you can check its type before using it.

if ($en instanceof Dictionary) {
Print $en->summarize ();
}

However, if you use PHP V5, you can build an object type check into a class or method declaration.

In "Getting to know the objects in PHP V5", focus on two classes: Dictionary, which stores terminology and translations, Dictionaryio, which Dictionary data export (import) from (to) the file system. These features make it easy to send Dictionary files to Third-party translators, and third-party translators can use their own software to edit data. You can then re-import the processed files. Listing 1 is a version of the Dictionary class that accepts a Dictionaryio object and stores it for future use.

Listing 1. Accept a version of the Dictionary class for the Dictionaryio object

Class Dictionary {
Public $translations = Array ();
Public $type = "En";
Public $dictio;

function Adddictionaryio ($dictio) {
$this->dictio= $dictio;
}

function Export () {
if ($this->dictio) {
$this->dictio->export ($this);
}
}
}

Class Dictionaryio {
function Export ($dict) {
Print "Exporting dictionary data". ($dict->type) \ n ";
}
}

$en = new Dictionary ();
$en->adddictionaryio (New Dictionaryio ());
$en->export ();

Output
Dumping dictionary data (En)

The Dictionaryio class has a single method, export (), which accepts a Dictionary object and uses it to output false messages. Dictionary now has two new methods: Adddictionaryio (), accepting and storing Dictionaryio objects, export (), exporting Dictionary data using the provided objects-or in a fully implemented version.

You may wonder why the Dictionary object not only instantiates its own Dictionaryio object, or even handles the import export operation internally, but does not turn to the second object at all. One reason is that you might want a Dictionaryio object to use more than one Dictionary object, or you want to store a separate reference to that object. Another reason is that you can take advantage of class switching or polymorphism by passing the Dictionaryio object to Dictionary. In other words, you can pass an instance of a Dictionaryio subclass, such as Xmldictionaryio, to Dictionary, and change the way the data is saved and retrieved at run time.

Figure 1 shows the Dictionary and Dictionaryio classes and their usage relationships.

As shown, there is nothing to prevent the encoder from passing completely random objects to Adddictionaryio (). A similar error is obtained only when you run export (), and it is found that objects that are already stored in the $dictio actually do not have the export () method. When using PHP V4, you must test the parameter types in this example to absolutely ensure that the encoder passes the correct type of object. When using PHP V5, you can deploy parameter hints to enforce object types. Add only the desired object type to the parameter variable of the method declaration, as shown in Listing 2:

Listing 2. To add an object type to a parameter variable in a method declaration

function Adddictionaryio (Dictionaryio $dictio) {
$this->dictio= $dictio;
}

function Export () {
if ($this->dictio) {
$this->dictio->export ($this);
}
}

Now, if the client encoder tries to pass an object of type error to Adddictionaryio (), the PHP engine throws a fatal error. Therefore, type hints make your code more secure. Unfortunately, the hint is only valid for the object, so you cannot require a string or integer in the argument list. These original types must be tested manually.

Even if Adddictionaryio () is guaranteed to get the correct object type, there is no guarantee that the method will be invoked first. The export () method tests the presence of $dictio properties in the export () method to avoid errors. However, you may want to be more restrictive, requiring the Dictionaryio object to be passed to the constructor, ensuring that $dictio is always populated.

Call override Method

In Listing 3, Xmldictionaryio integrates Dictionaryio. While Dictionaryio writes and reads serialized data, Xmldictionaryio operates the XML and can be shared with third-party applications. Xmldictionaryio can override its parent method (import () and export ()), or you can choose not to provide your own implementation (path ()). If the client invokes the path () method in the Xmldictionaryio object, the path () method implemented in Dictionaryio is invoked.

In fact, both of these methods can be used at the same time. You can override the method and invoke the parent implementation. To do this, use the New keyword parent. Use parent with the range resolution operator and the name of the method being discussed. For example, suppose you need xmldictionaryio to use the current working directory (if one is available) in a directory called XML, otherwise it should use the default path generated by the parent Dictionaryio class, as shown in Listing 3:

Listing 3. Xmldictionaryio using the XML directory or the default path generated by the Dictionaryio class

Class Xmldictionaryio extends Dictionaryio {

function path (Dictionary $dictionary, $ext) {
$sep = Directory_separator;
if (Is_dir (". { $sep}xml ")) {
Return ". {$sep}xml{$sep} {$dictionary->gettype ()}. $ext ";
}
Return Parent::p Ath ($dictionary, $ext);
}
// ...

As you can see, this method checks the local XML directory. If the test fails, it is assigned to the parent method using the parent keyword.

Subclass and Constructor methods

The parent keyword is particularly important in the constructor method. If you do not define a constructor in a subclass, the parent constructor is called explicitly on your behalf. If you do not create a constructor method in a subclass. It is your responsibility to call the constructor of the parent class and pass any parameters, as shown in Listing 4:

Listing 4. Invoking the parent class ' s constructor

Class Specialdictionary extends Dictionary {
function __construct ($type, Dictionaryio $dictio, $additional) {
Do something with $additional
Parent::__construct ($type, $dictio);
}
}


Abstract classes and methods

Although it is perfectly legal to provide the default behavior in the parent class, this may not be the most ingenious approach. For initiators, you must rely on the author of the subclass to understand that they must implement import () and export () in order to create a class in the broken state. Moreover, the Dictionaryio class is actually a brother, not a father and son. Xmldictionaryio is not a special case of dictionaryio; instead, it is an alternative implementation.

PHP V5 allows you to define a partially implemented class whose primary role is to specify the core interface for its children. Such a class must be declared abstract.


Abstract class Dictionaryio {}


An abstract class cannot be instantiated. You must create a subclass (that is, create a class that inherits it) and create an instance of the subclass. You can declare standard and abstract methods in an abstract class, as shown in Listing 5. Abstract methods must be qualified with the abstract keyword and must consist of only one method signature. This means that an abstract method should include an abstract keyword, an optional visibility modifier, a function keyword, and an optional list of parameters within parentheses. They should not have any method principals.

Listing 5. Declaring abstract classes


Abstract class Dictionaryio {

protected function Path (Dictionary $dictionary,
$ext) {
$path = Dictionary::getsavedirectory ();
$path. = Directory_separator;
$path. = $dictionary->gettype (). $ext ";
return $path;
}

Abstract function Import (Dictionary $dictionary);
Abstract function Export (Dictionary $dictionary);
}


Note that the path () function is now protected. This allows access from the subclass, but does not allow access from outside the Dictionaryio type. Any class that inherits Dictionaryio must implement the import () and export () methods, or you may get fatal errors.

Any class that declares an abstract method must itself be declared abstract. A subclass of an inherited abstract class must implement all abstract methods declared as abstract in its parent class or itself.

Listing 6 shows the specific Dictionaryio class, and for simplicity, the actual implementation is omitted here.

Listing 6. The specific Dictionaryio class


Class Serialdictionaryio extends Dictionaryio {

function export (Dictionary $dictionary) {
Implementation
}

Function Import (Dictionary $dictionary) {
Implementation
}
}

Class Xmldictionaryio extends Dictionaryio {

protected function Path (Dictionary $dictionary, $ext) {
$path = Strtolower (parent::p Ath ($dictionary, $ext));
return $path;
}

function export (Dictionary $dictionary) {
Implementation
}

Function Import (Dictionary $dictionary) {
Implementation
}
}


The Dictionary class requires a Dictionaryio object to be passed to its constructor, but it neither knows nor cares whether the object is an instance of Xmldictionaryio or Serialdictionaryio. The only thing it knows is that a given object inherits Dictionaryio, and therefore it is guaranteed to support the import () and export () methods. This class switching at runtime is a common feature of object-oriented programming, called polymorphism.

Figure 2 shows the Dictionaryio class. Note that abstract classes and abstract methods are represented in italics. The graph is a good example of polymorphism. It shows that the defined relationship of the Dictionaryio class is with Dictionaryio, but Serialdictionaryio or Xmldictionaryio will implement the relationship.


Figure 2. Abstract Dictionaryio classes and their specific subclasses


Interface

With Java? Programming language applications, PHP only supports single inheritance. This means that a class can only inherit a parent class (although it may indirectly inherit many ancestors). While this ensures clean design, there are times when you might want to define multiple sets of capabilities for a class.

One advantage of using objects is that types can provide you with a guarantee of functionality. The Dictionary object always has a get () method, whether it is a Dictionary itself or an instance of its subclass. Another feature of Dictionary is its support for export (). Suppose you need to have a large number of other classes in the system equally exportable. When you want to save the state of a system to a file, you can provide separate export () methods for these completely different classes, then aggregate the instances, loop through all instances, and call export () for each instance. Listing 7 shows the second class that implements the export () method.

Listing 7. The second class that implements the export () method


Class Thirdpartynews {
// ...
}

Class Ournews extends Thirdpartynews {
// ...
function Export () {
Print "Ournews export\n";
}
}


Note that this example includes a constraint, that is, the new class Ournews inherits an external class called Thirdpartynews.

Listing 8 shows the class that aggregates the class instances that are equipped with the export () method.

Listing 8. Class for assembling class instances equipped with export () method


Class Exporter {
Private $exportable = Array ();
function Add ($obj) {
$this->exportable[] = $obj;
}

function Exportall () {
foreach ($this->exportable as $obj) {
$obj->export ();
}
}
}


The exporter class defines two methods: Add (), accepts objects to be stored, and exportall (), loops through stored objects to call export () on each object. The disadvantage of this design is obvious: add () does not check the type of the provided object, so Exportall () is at a fatal risk when it makes a brisk call to export (). What is really useful here is some type hints in the Add () method signature. Dictionary and Ournews are dedicated to different roots. You can rely on type checking within the Add () method, but this is not elegant and not fixed. Each time you create a new type that supports export (), you need to create a new type check.

Interface eliminates this kind of trouble. As the name indicates, the interface defines the functionality rather than the implementation. Declares an interface with the interface keyword.


Interface Exportable {
Public function export ();
}


For abstract classes, you can define any number of method signatures. Subclasses must provide an implementation of each method. Unlike an abstract class, however, an interface cannot contain any specific method at all (that is, any attribute of any method cannot be separated from its signature). class implements the interface with the Implements keyword, as shown in Listing 9.

Listing 9. Classes that implement interfaces with the Implements keyword


Class Ournews extends Thirdpartynews
Implements exportable {
// ...
function Export () {
Print "Ournews export\n";
}
}

Class Dictionary implements exportable, iterator {
function Export () {
//...
}
}


You can implement any number of interfaces by using a comma-delimited list after implements. You must implement all the methods declared in each interface, or declare your implementation class abstraction. What can be done about it? Now, Dictionary and Ournews objects share types. All such objects are still exportable. You can check them with type hints and instanceof tests. Listing 10 shows the modified Exporter::add () method.

Listing 10. Modified Exporter::add () method


Class Exporter {
Private $exportable = Array ();
function Add (exportable $obj) {
$this->exportable[] = $obj;
}
//...


Interface is a difficult concept to grasp. After all, they don't actually provide any useful code. The trick is to remember the importance of types in object-oriented programming. The interface is similar to the contract. It lends the class A name that puts the class in place, which in turn guarantees that a particular method will be available. In addition, classes that use the Exportable object neither know nor care about the behavior that occurs when the export () is invoked. It only knows that it can safely invoke the method.

Figure 3 shows the relationship between the exportable interface and its implementation class. Note that the exporter has a use relationship with the exportable interface rather than the concrete implementation. Interface relations are indicated by dashed and open arrows.

Conclusion
This article supports the use of the value of types in PHP V5. Object types allow you to separate components in your system from each other, resulting in reusable, scalable, and scalable code. Abstract classes and interfaces help you design systems based on class types. The client class can be coded to require only abstract types, while the implementation policies and results are left to the concrete class instances that are passed to them at run time. That is, Dictionary is neither limited to serialized data nor limited to XML. If a new format must be supported, Dictionary will not need any further development. It has nothing to do with saving data and loading data from the file system and loading the data into the file system. Dictionary only knows that it must have a Dictionaryio object to guarantee the functionality of export () and import ().
If the class guarantees the interface, you must be able to guarantee the class. Although the instanceof feature provides a good way to check the type, you can also scroll the object type check to the method signature itself by using a type hint in the argument list



Related Article

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.