Basic concepts of PHP5 objects and classes

Source: Internet
Author: User
Tags parse error
PHP5 Basic concepts of objects and classes

Inherited from the most basic concepts, mainly for experienced object-oriented programmers and readers who have not yet touched the object.
As a PHP programmer, you certainly know the variables and functions. But classes and objects can be another thing. Without defining a single class, you can create a perfect system. But even if you decide not to use object-oriented programming in your own code, you may still need to understand object-oriented programming. For example, if you use a third-party library, such as a library that you can use with PHP Extension and application Repository (PEAR), you will find yourself instantiating objects and invoking methods.

What are classes and objects?
Simply put, a class is a separate block or bundle consisting of variables and methods. These components typically combine to achieve a single responsibility or a set of responsibilities. In this article, you will create a class that collects methods for querying and populating dictionaries that consist of items and values.

Classes can be used directly as a simple way to organize data and functionality, just like a set of functions and variables. However, a class can be used to ignore its existence. Class can be used to generate multiple instances in memory. Such an instance is called an object. Each object can access a set of identical functions (called methods in an object-oriented context) and variables (called attributes or instance variables), but the actual values of each variable are different in each object.

Consider a unit in a role-playing game-like a tank. Classes may set up a set of variables for a tank: defensive and offensive abilities, range, health status, etc. The class may also define a set of functions, including move () and attack (). When the system contains a tank class, the class can be used to generate dozens of or hundreds of tank objects, each of which potentially has its own health or range characteristics. Therefore, the class is the blueprint or template used to generate the object.

The simplest way to understand classes and objects might be to create classes and objects.

First Class
You can create a class with the class keyword. In the simplest case, a class consists of a keyword class, a name, and a block of code:


Class Dictionary {

}

?

The class name can contain any combination of letters, numbers, and underscore characters, but it cannot begin with a number.

The Dictionary class in the above example is completely legal despite its limited usefulness. So how do you use this class to create some objects?


$obj 1 = new Dictionary ();
$obj 2 = new Dictionary ();
$obj 3 = new Dictionary ();

?

At least formally, instantiating an object is similar to calling a function. For function calls, parentheses must be provided. As with functions, some classes require you to pass parameters to them. You must also use the New keyword. This tells the PHP engine that you want to instantiate a new object. The returned object can then be stored in a variable for future use.

Property
In the body of a class, you can declare a special variable called a property. In PHP V4, the attribute must be called with the keyword var. This is still a legitimate syntax, but mainly for backwards compatibility. In PHP V5, attributes must be declared as public, private, or protected. Can be in the keyword: can we have a little privacy here? To read about these qualifiers. But now declare all the properties as public in the example. Listing 1 shows a class that declares two properties.

Listing 1. Class that declares two properties

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

?

As you can see, you declare and assign a value to the property at the same time. You can use the Print_r () function to quickly explore the state of an object. Listing 2 shows that the Dictionary object now has more members.

Listing 2. Dictionary Object List

$en = new Dictionary ();
Print_r ($en);?

If you run the script, you will see the output of the following objects:

Dictionary Object
(
???? [Translations] = = Array
???????? (
???????? )

???? [Type] = En
)

?

You can access common object properties by using the object operator. So $en->type represents the $type property of the Dictionary object referenced by the $en. If you have access to a property, it means you can set and get its value. The code in Listing 3 creates two instances of the Dictionary class-in other words, it instantiates two Dictionary objects. It changes the $type property of an object and adds a translation of two objects:

Listing 3. Create two instances of a Dictionary class

$en = new Dictionary ();
$en->translations[' tree ' = "tree";

$FR = new Dictionary ();
$fr->type = "FR";
$fr->translations[' TREE '] = "Arbre";

foreach (Array ($en, $FR) as $dict) {
???? Print "type: {$dict->type}";
???? Print "tree: {$dict->translations[' tree ']}\n";
}

?

The script output is as follows


Type:en Tree:tree
TYPE:FR Tree:arbre

?

So the Dictionary class is now more useful. A single object can store different combinations of key values, and there is a flag that tells the client more about this Dictionary.

Although the Dictionary class is currently similar to the wrapper for associative arrays, there are some clues to understand the functionality of the object. For now, we can already represent our sample data well, as shown in Listing 4.

Listing 4. Sample Data

$en = Array (
???? ' Translations ' =>array (' tree ' = ' tree '),
???? ' Type ' = ' En '
);

$FR = Array (
???? ' Translations ' =>array (' TREE ' = ' arbre '),
???? ' Type ' = ' Fr '
);

?

Although the data structure accomplishes the same purpose as the Dictionary class, it does not provide a structure guarantee. If you pass a Dictionary object, we know it has $translations property. However, if it is an associated data, there is no such guarantee. This fact makes similar $fr [' translations '] [' TREE ']; The query has some luck, unless the code that makes the query determines the origin of the array. This is the focus of the object: the type of object is the guarantee of its characteristics.

While storing data with objects has advantages, you may not feel a bit. objects can be things, but the point is that they can also do things.

Method
Simply put, a method is a function declared in a class. They are usually (but not always) invoked through object instances using object operators. Listing 5 Adds a method to the Dictionary class and calls the method.

Listing 5. To add a method to the Dictionary class

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

???? function summarize () {
???????? $ret?? = "Dictionary type: {$this->type}\n";
???????? $ret. = "Terms:". Count ($this->translations). " \ n ";
???????? return $ret;
???? }
}

$en = new Dictionary ();
$en->translations[' tree ' = "tree";
Print $en->summarize ();

?

It provides the following output:


Dictionary Type:en
Terms:1

?

As you can see, declaring the Summarize () method is the same as declaring any function, except that it is declared in a class. The summarize () method is called by using an object operator with an Dictionary instance. The summarize () function accesses properties to provide a brief description of the state of the object.

Note the use of a new feature for this article. $this pseudo-variables provide a mechanism for an object to reference its own properties and methods. Outside the object, you can use a handle to access its elements (in this case, $en). Inside the object, there is no handle, so $this must be resorted to. If you find $this a bit confusing, try replacing it with the current instance in your mind when you encounter it in your code.

Classes are typically represented in a chart using the Universal Modeling Language (Universal Modeling language,uml). The details of the UML are beyond the scope of this article, but this diagram is a good way to visualize the relationship between classes. Figure 1 shows the Dictionary class represented in UML. The class name is at the top level, the attribute is in the middle, and the method is at the bottom.


constructor function
The PHP engine recognizes many "magic" methods. If a method is defined, the PHP engine will call these methods automatically when the corresponding situation occurs. The most commonly implemented method is the constructor method. The PHP engine invokes the constructor when instantiating an object. All the basic setup code for the object is placed in the constructor. In PHP V4, you create a constructor by declaring a method with the same name as the class. In V5, a method called __construct () should be declared. Listing 6 shows the constructors that require the Dictionaryio object.

Listing 6. Constructors that require Dictionaryio objects

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

???? function __construct ($type, Dictionaryio $dictio) {
???????? $this->type = $type;
???????? $this->dictio= $dictio;
???? }

???? //...

?

To instantiate a Dictionary object, you need to pass the type string and the Dictionaryio object to its constructor. Constructors use these parameters to set their own properties. The following code shows how the Dictionary object can be instantiated:


$en = new Dictionary ("en", New Dictionaryio ());

?

The Dictionary class is now more secure than before. All Dictionary objects have been initialized with the required parameters.

Of course, there is no way to prevent some people from subsequently changing $type properties or setting $dictio to empty. Fortunately, PHP V5 can help you achieve this.

Keyword: Can we have a little privacy here? Www.9qc.com
The Public keyword associated with the property declaration has been seen earlier. The keyword represents the visibility of the property. In fact, the visibility of attributes can be set to public, private, and protected. Properties declared as public can be written and read outside of the class, and properties declared as private are only visible in the context of an object or class. A property declared as protected can only be visible in the context of the current class and its subclasses. (In the Inheritance section you will see that these things work.) You can use the private property to actually lock the class. If you declare a property as private and try to access it from outside the class scope (as shown in Listing 7), the PHP engine throws a fatal error.

Listing 7. Attempting to access a property from outside the class scope

Class Dictionary {
???? Private $translations = Array ();
???? Private $dictio;
???? Private $type;

???? function __construct ($type, Dictionaryio $dictio) {
???????? $this->type = $type;
???????? $this->dictio = $dictio;
???? }

???? // ...
}

$en = new Dictionary ("en", New Dictionaryio ());
$en->dictio = null;

?

The output is as follows:


Fatal Error:cannot Access Private Property
Dictionary:: $dictio in ...

?

In general, you should declare most properties as private, and then provide methods to get and set these properties as needed. This allows you to control the interface of the class, make some data read-only, clean or filter parameters before assigning them to properties, and provide a set of clear rules for interacting with objects.

The method of modifying the visibility of a method is the same as modifying the property visibility by adding public, private, or protected to the method declaration. If your class needs to use some housekeeping methods that the outside world doesn't need to know about, you can declare it private. In Listing 8, the Get () method provides an interface for extracting translations for users of the Dictionary class. The class also needs to track all queries, so the private method LogQuery () is provided.

Listing 8. The Get () method provides an interface for users of the Dictionary class

function Get ($term) {
???? $value = $this->translations[$term];
???? $this->logquery ($term, $value, "get");
???? return $value;
}

Private Function LogQuery ($term, $value, $kind) {
???? Write Log information
}

?

Declaring LogQuery () as private simplifies the public interface and prevents classes from calling LogQuery () inappropriately. As with properties, attempting to call a private method from outside the containing class results in a fatal error.

In the class context operation
So far, the methods and properties you see have been manipulated in the object context. That is, you must use an object instance to access methods and properties by $this a pseudo-variable or object reference stored in a standard variable. Sometimes it may be more useful to find properties and methods accessed through classes rather than object instances. This class member is called a static member.

To declare a static property, place the keyword static behind the visibility modifier, directly in front of the property variable.

The following example shows a single static property: $iodir that holds the path to the default directory for saving and reading Dictionary data. Because the data is the same for all objects, it makes sense to have it available to all instances.

Listing 9. Single Static $iodir properties

Class Dictionary {
???? public static $iodir = ".";
???? // ...
}

?

You can use the scope resolution operator to access a static property, which consists of a double colon (::) Composition The scope resolution operator should be between the class name and the static property that you want to access.


Print Dictionary:: $iodir. "\ n";
Dictionary:: $iodir = "/tmp";

?

As you can see, accessing this property does not require instantiating the Dictionary object.

The syntax for declaring and accessing static methods is similar. Again, the static keyword should be placed after the visibility modifier. Listing 10 shows two static methods that access the $iodir attribute declared as private.

Listing 10. Two static methods for accessing $iodir properties

Class Dictionary {
???? private static $iodir = ".";
???? // ...
???? public static function Setsavedirectory ($dir) {
???????? if (! Is_dir ($dir) | |
???????????? ! Is_writable ($dir)) {
???????????? return false;
???????? }
???????? Self:: $iodir = $dir;
???? }

???? public static function Getsavedirectory () {
???????? Return self:: $iodir;
???? }
???? // ...
}

?

Users no longer have access to the $iodir attribute directory. By creating a special method to access the property, you can ensure that any value provided is sound. In this case, the method checks the given string to the writable directory before assigning it.

Note that all two methods use the keyword self and the access resolution operator to refer to the $iodir property. $this cannot be used in a static method because $this is a reference to the current object instance, but the static method is called through the class rather than through the object. If the PHP engine sees $this in a static method, it throws a fatal error and a hint message.

To invoke a static method from outside the class, use the class name plus the range resolver and method name.


Dictionary::setsavedirectory ("/tmp");
Print dictionary::getsavedirectory ();

?

There are two important reasons to use static methods. First, the utility operation may not require an object instance to do its work. By declaring as static, you save the effort of creating objects for client code. Second, the static method is globally available. This means that you can set a value that all object instances can access, and make static methods a good way to share critical data on your system.

Although static properties are often declared private to prevent others from interfering, there is a way to create a read-only static range of properties, that is, to declare constants. As with global properties, a class constant cannot be changed once it is defined. It is used for status flags and other things that do not change in the process life cycle, such as PI or all countries in Africa.

Declare class constants with the Const keyword. For example, because there is almost certainly a database behind the actual implementation of the Dictionary object, you can also assume that the item and the translation have the maximum length. Listing 11 sets it to a class constant. Http://www.k686.com

Listing 11. To set MAXLENGTH as a class constant

Class Dictionary {
???? Const MAXLENGTH = 250;
???? // ...
}

Print dictionary::maxlength;

?

The class constant is always public, so the visibility keyword cannot be used. This is also a problem because any attempt to change its value will result in a parse error. Also note that unlike regular properties, class constants do not start with the dollar sign.

Inherited
If you are familiar with object-oriented programming, you will know that I have kept the best for the last time. The relationship between a class and its generated dynamic objects makes the system more flexible. For example, each Dictionary object encapsulates a different collection of translation data, but the models of these different entities are defined in a single Dictionary class.

But sometimes you need to write down the class-level differences. Do you remember the Dictionaryio class? To recap, it gets the data from the Dictionary object, writes it to the file system, fetches the data from a file, and merges it back into the Dictionary object. Listing 12 shows a quick implementation that uses serialization to save and load Dictionary data.

Listing 12. A fast implementation using serialization

Class Dictionary {
???? // ...

???? function Asarray () {
???????? return $this->translations;
???? }

???? function GetType () {
???????? return $this->type;
???? }

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

???? Function Import () {
???????? $this->dictio->import ($this);
???? }
}

Class Dictionaryio {

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

???? function export (Dictionary $dictionary) {
???????? $translations = $dictionary->asarray ();
???????? File_put_contents ($this->path (
?????????????????????????? $dictionary, ' serial '),
?????????????????????????? Serialize ($translations));?
???? }

???? Function Import (Dictionary $dictionary) {
???????? $path = $this->path ($dictionary, ' serial ');
???????? if (! Is_file ($path)) return false;
???????? $translations = Unserialize (
???????????????????????? File_get_contents ($path));
???????? foreach ($translations as $term = = $trans) {
???????????? $dictionary->set ($term, $trans);
???????? }
???? }
}

$dict = new Dictionary ("En", New Dictionaryio ());
$dict->set ("Tree", "tree");
$dict->export ();

?

This example introduces two simple Dictionary methods, specifically, Asarray () returns a copy of the $translations array. Dictionaryio implementation has the advantages of simplicity. Because error checking is often omitted in the sample code, this is a quick and easy way to save data to a file.

Once you have deployed this library, you need to support its save format immediately. Making the format obsolete would offend the wishes of those who might store the backup in this way. But the requirements change, and you may receive complaints that the output format is inconvenient for users to edit. These users want to send the export file to a third party in XML format.

Now faced with a problem. How do I support two formats in the Dictionaryio interface?

One solution is to use conditional statements in the export () and import () methods to test the type flags, as shown in Listing 13.

Listing 13. Using conditional statements in the export () and import () methods

function export (Dictionary $dictionary) {
???? if ($this->type = = dictionaryio::serial) {
???????? Write serialized data
???? } else if ($this->type = = dictionaryio::xml) {
???????? Write XML data
???? }
}

Function Import (Dictionary $dictionary) {
???? if ($this->type = = dictionaryio::serial) {
???????? Read serialized data
???? } else if ($this->type = = dictionaryio::xml) {
???????? Read XML data
???? }
}

?

This structure is an example of a bad "code taste" because it relies on replication. Making changes in one place (for example, adding a new type of test) requires a set of corresponding changes elsewhere (bringing other types of tests into the line), and the code can quickly become difficult to read.

Inheritance provides a more elegant solution. You can create a new class, Xmldictionaryio, that inherits the interfaces set by Dictionaryio, but overrides some of these features.

Use the extends keyword to create subclasses. The following is the smallest implementation of the Xmldictionaryio class:


Xmldictionaryio extends Dictionaryio {
}

?

Xmldictionaryio now features exactly the same as Dictionaryio. Because it inherits all the public (and protected) properties from Dictionaryio, you can apply the same action applied to the Dictionaryio object to the Xmldictionaryio object. This relationship extends to the object type. The Xmldictionaryio object is obviously an instance of the Xmldictionaryio class, but it is also an example of Dictionaryio-in the same way that, in the order of generalization, one is human, mammal, and animal. You can use the instanceof operator to test this and return TRUE if the object is a member of the specified class, as shown in Listing 14.

Listing 14. Test inheritance with the instanceof operator

$dictio = new Xmldictionaryio ();
if ($dictio instanceof Xmldictionaryio) {
???? Print "Object is an instance of xmldictionaryio\n";
}

if ($dictio instanceof Dictionaryio) {
???? Print "Object is an instance of dictionaryio\n";
}

?

The output is as follows:


Object is an instance of Xmldictionaryio
Object is an instance of Dictionaryio

?

As instanceof accepts $dictio are Dictionaryio objects, the method will also accept these objects as arguments. This means that the Xmldictionaryio object can be passed to the constructor of the Dictionary class, even if Dictionaryio is the type specified by the signature of the constructor.

Listing 15 is a fast and dirty Xmldictionaryio implementation that uses the DOM to complete the XML functionality.

Listing 15. Xmldictionaryio implementation

Class Xmldictionaryio extends Dictionaryio {

???? function export (Dictionary $dictionary) {
???????? $translations = $dictionary->asarray ();
???????? $ doc = new DOMDocument ("1.0");
???????? $dic _el = $doc->createelement ("dictionary");
???????? $doc->appendchild ($dic _el);
???????? foreach ($translations as $key = = $val) {
???????????? $term _el = $doc->createelement ("term"); ???????????? $dic _el->appendchild ($term _el);
???????????? $key _el = $doc->createelement ("key", $key);
???????????? $val _el = $doc->createelement (
?????????????????????? "Value", $val);
???????????? $term _el->appendchild ($key _el);
???????????? $term _el->appendchild ($val _el);
????????}
???????? File_put_contents ($this->path (
?????????????????????????? $dictionary, ' xml '),
????????????????? ????????? $doc->savexml ());
????}

???? Function Import (Dictionary $dictionary) {
???????? $path = $this->path ($dictionary, ' xml ');
???????? if (! Is_file ($path)) return false;
???????? $doc = Domdocument::loadxml (
?????????????? File_get_contents ($path));
???????? $termlist = $doc
???????????????????? ->getelementsbytagname ("term");
???????? foreach ($termlist as $term) {
???????????? $key = $term->getelementsbytagname ("key")
?????????????????? ->item (0)->nodevalue;
???????????? $val = $term
?????????????????? ->getelementsbytagname ("value")
?????????????????? ->item (0)->nodevalue;
???????????? $dictionary->set ($key, $val);
???????? }
???? }
}

?

The details about getting and generating XML are, of course, introduced. There are many ways to do this, including the perfect SimpleXML extension. In short, the import () method takes an XML document as an argument and uses it to populate the Dictionary object. The export () method obtains the data from the Dictionary object and writes it to the XML file. (In the real world, an XML-based format called XLIFF is likely to be used for importing into third-party translation tools.) )

Note that both import () and export () call the utility method path (), which does not exist in the Xmldictionaryio class. But it doesn't matter, because path () is implemented in Dictionaryio. When Xmldictionaryio implements a method, the implementation is called for the Xmldictionaryio object when the method is called. When no implementation exists, the call fails to be returned to the parent class.


Conclusion
Due to limited space, it is not possible to introduce them all. Further research has two directions: breadth and depth. Breadth refers to those features beyond the scope of this article, such as abstract classes, interfaces, iterator interfaces, reflection, exceptions, and object replication. Depth refers to a design problem. While it is important to understand the scope of tools available in PHP for object-oriented programming, it is equally important to consider how best to use these features. Fortunately, there are a lot of available resources devoted to designing patterns in the object-oriented context.


This article is from goldtimes.net original link: goldtimes.net/member/view.asp?id=1423

Thanks to k686 Green software feeds.

  • 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.