PHP V5 Migration Guide

Source: Internet
Author: User

Using the new language features of PHP V5 can significantly improve the maintainability and reliability of code. By reading this article, you will learn how to use these new features to migrate code developed with PHP V4 to PHP V5.

PHP V5 has made major improvements based on PHP V4. New language features make it easier to build reliable class libraries and maintain class libraries. In addition, rewrite the standard library to help make PHP more compliant with the same Web language, such as Java™Programming language. Let's take a look at some new PHP object-oriented features and learn how to migrate existing PHP V4 code to PHP V5.

First, let's first understand the features of the new language and how the PHP Creation Program has changed the method for creating objects using PHP V4. The idea of using V5 is to create an industrial language for Web application development. That means you need to understand the limits of PHP V4, and then from other languages (such as Java,C#,C++, Ruby, and Perl languages) extract known excellent language architectures and incorporate these architectures into PHP.

The first and most important new feature is access protection for class methods and instance variables --public,protectedAndprivateKeyword. This new feature allows the class designer to ensure control over the internal characteristics of the class, and also tells the class users which classes can and which classes cannot be touched.

In PHP V4, all codes arepublic. In PHP V5, class designers can declare which codes are externally visible (publicAnd which code is only visible to the class (private) Or only visible to the subclass of the class (protected). Without such access control, the development of code in a large team or the distribution of code as a library will be blocked, because users of those classes are likely to use incorrect methods or access code that should be private member variables.

Another big new feature is keyword.interfaceAndabstractThese two keywords allow contract programming.Contract ProgrammingIt means that a class provides a contract to another class-in other words: "This is what I want to do, and you don't need to know how it is done ". All classes implementing the interface follow this contract. All users of the interface agree to use only the methods specified in the interface. Abstract keywords make it easy to use interfaces. I will describe them later.

These two main features-access control and contractual programming-allow large coding teams to use large code libraries more smoothly. These features also enable IDE To provide a richer set of intelligent language features. This article not only illustrates several migration issues, but also takes some time to explain how to use these new main language features.

Access Control

To demonstrate the features of the new language, I usedConfiguration. This simple class contains configuration items for Web applications-for example, the path to the image directory. Ideally, this information will be stored in a file or database. Listing 1 shows a simplified version.


Listing 1. access. php4
<?phpclass Configuration{  var $_items = array();  function Configuration() {    $this->_items[ 'imgpath' ] = 'images';  }  function get( $key ) {    return $this->_items[ $key ];  }}$c = new Configuration();echo( $c->get( 'imgpath' )."\n" );?>

This is a fully orthodox PHP V4 class. The member variable stores the list of configuration items, constructs the loaded items of the program, and then namedget().

After running the script, the following code is displayed in the command line:

% php access.php4images%

Good! This result indicates that the code runs normally and is set and read properly.imgpathThe value of the configuration item.

The first step to convert this class to PHP V5 is to rename the constructor. In PHP V5, the method for initializing an object (constructor) is called__construct. This small change is as follows.


Listing 2. access1.php5
<?phpclass Configuration{  var $_items = array();  function __construct() {    $this->_items[ 'imgpath' ] = 'images';  }  function get( $key ) {    return $this->_items[ $key ];  }}$c = new Configuration();echo( $c->get( 'imgpath' )."\n" );?>

This change is not significant. Just move to the PHP V5 convention. The next step is to add access control to the class to ensure that the class users cannot directly read and write$_itemsMember variable. The change is as follows.


Listing 3. access2.php5
<?phpclass Configuration{  private $_items = array();  public function __construct() {    $this->_items[ 'imgpath' ] = 'images';  }  public function get( $key ) {    return $this->_items[ $key ];  }}$c = new Configuration();echo( $c->get( 'imgpath' )."\n" );?>

If the user of this object needs to directly access the item array, access will be denied because the array is markedprivate. Fortunately, the user discoveredget()Methods can provide a wide range of read permissions.

To illustrate how to useprotectedPermission. I need another class, which must inherit fromConfigurationClass. I call that classDBConfigurationAnd it is assumed that the class will read the configuration value from the database. This setting is as follows.


Listing 4. access3.php
<?phpclass Configuration{  protected $_items = array();  public function __construct() {    $this->load();  }  protected function load() { }  public function get( $key ) {    return $this->_items[ $key ];  }}class DBConfiguration extends Configuration{  protected function load() {    $this->_items[ 'imgpath' ] = 'images';  }}$c = new DBConfiguration();echo( $c->get( 'imgpath' )."\n" );?>

This list showsprotectedKeyword usage. The base class defines the nameload(). Subclass of this class will overwriteload()Method to add dataitemsTable.load()The method is an internal method for the class and its subclass. Therefore, this method is invisible to all external users. If all keywords areprivateThe load () method cannot be overwritten.

I do not like this design very much.DBConfigurationThis design is selected when the class can access the item array. I want to continueConfigurationClass to completely maintain the item array, so that after adding other sub-classes, those classes do not need to know how to maintain the item array. I made the following changes.


Listing 5. access4.php5
<?phpclass Configuration{  private $_items = array();  public function __construct() {    $this->load();  }  protected function load() { }  protected function add( $key, $value ) {    $this->_items[ $key ] = $value;  }  public function get( $key ) {    return $this->_items[ $key ];  }}class DBConfiguration extends Configuration{  protected function load() {    $this->add( 'imgpath', 'images' );  }}$c = new DBConfiguration();echo( $c->get( 'imgpath' )."\n" );?>

Now, the item array can be private, because the subclass uses protectedadd()Method to add a configuration item to the list.ConfigurationClass can change the method for storing and reading configuration items without considering its subclass. As longload()Andadd()If the method runs in the same way, the subclass should not have any problems.

For me, adding access control is the main reason to consider moving to PHP V5. Is it because Grady Booch says PHP V5 is one of the four object-oriented languages? No, because I once accepted a task to maintain 100 KLOCC++Code, in which all methods and members are defined as public. It took me three days to clear these definitions and significantly reduced the number of errors and increased maintainability. Why? Without access control, it is impossible to know how objects use other objects, and to make any changes without knowing what difficulties to break through. UseC++At least I have a compilation program available. PHP is not equipped with a compilation program, so this type of access control becomes increasingly important.







Contract Programming

When migrating from PHP V4 to PHP V5, the next important feature is to support contractual programming through interfaces, abstract classes, and methods. Listing 6 showsConfigurationClass. In this class, PHP V4 encoding staff attempted to build the basic interface without usinginterfaceKeyword.


Listing 6. interface. php4
<?phpclass IConfiguration{  function get( $key ) { }}class Configuration extends IConfiguration{  var $_items = array();  function Configuration() {    $this->load();  }  function load() { }  function get( $key ) {    return $this->_items[ $key ];  }}class DBConfiguration extends Configuration{  function load() {    $this->_items[ 'imgpath' ] = 'images';  }}$c = new DBConfiguration();echo( $c->get( 'imgpath' )."\n" );?>

The configuration starts with a smallIConfigurationClass, which defines allConfigurationClass or the interface provided by the derived class. This interface defines the contract between the class and all its users. Contract declares implementationIConfigurationAll classes must beget()Method andIConfigurationAll users must use onlyget()Method.

The following code runs in PHP V5, but it is best to use the provided interface system, as shown below.


Listing 7. interface1.php5
<?phpinterface IConfiguration{  function get( $key );}class Configuration implements IConfiguration{  ...}class DBConfiguration extends Configuration{  ...}$c = new DBConfiguration();echo( $c->get( 'imgpath' )."\n" );?>

On the one hand, readers can better understand the running status; on the other hand, a single class can implement multiple interfaces. Listing 8 shows how to scaleConfigurationClassIteratorInterface. For PHP, this interface is an internal interface.


Listing 8. interface2.php5
<?phpinterface IConfiguration {  ...}class Configuration implements IConfiguration, Iterator{  private $_items = array();  public function __construct() {    $this->load();  }  protected function load() { }  protected function add( $key, $value ) {    $this->_items[ $key ] = $value;  }  public function get( $key ) {    return $this->_items[ $key ];  }  public function rewind() { reset($this->_items); }  public function current() { return current($this->_items); }  public function key() { return key($this->_items); }  public function next() { return next($this->_items); }  public function valid() { return ( $this->current() !== false ); }}class DBConfiguration extends Configuration {  ...}$c = new DBConfiguration();foreach( $c as $k => $v ) { echo( $k." = ".$v."\n" ); }?>

IteratorInterface makes all classes look like arrays of their users. As you can see at the end of the script, you can useforeachOperator repetitionConfigurationAll configuration items in the object. PHP V4 does not provide this function, but you can use it in various ways in the application.

The advantage of the interface mechanism is that the contract can be quickly integrated without any method. The final stage is the implementation interface. You must implement all the specified methods. Another helpful new feature in PHP V5 isAbstract classYou can use an abstract class to easily use a base class to implement the core part of an interface, and then use this interface to create an object class.

Another purpose of an abstract class is to create a base class for multiple Derived classes. In these derived classes, the base class will never be instantiated. For example, whenDBConfigurationAndConfigurationIf both exist, you can only useDBConfiguration.ConfigurationA class is just a base class-an abstract class. Therefore, you can useabstractKeyword to force this action, as shown below.


Listing 9. abstract. php5
<?phpabstract class Configuration{  protected $_items = array();  public function __construct() {    $this->load();  }  abstract protected function load();  public function get( $key ) {    return $this->_items[ $key ];  }}class DBConfiguration extends Configuration{  protected function load() {    $this->_items[ 'imgpath' ] = 'images';  }}$c = new DBConfiguration();echo( $c->get( 'imgpath' )."\n" );?>

Now, allConfigurationAn error occurs when instantiating an object of the type, because the class is abstract and incomplete.






Static methods and members

Another important new function in PHP V5 is to support using static members and methods for classes. With this feature, you can use the popular Singleton mode. This mode is applicableConfigurationClass is ideal, because the application should have only one configuration object.

Listing 10 shows the PHP V5ConfigurationClass As a singleton.


Listing 10. static. php5
<?phpclass Configuration{  private $_items = array();  static private $_instance = null;  static public function get() {    if ( self::$_instance == null )        self::$_instance = new Configuration();    return self::$_instance;  }  private function __construct() {    $this->_items[ 'imgpath' ] = 'images';  }  public function __get( $key ) {    return $this->_items[ $key ];  }}echo( Configuration::get()->{ 'imgpath' }."\n" );?>

staticKeyword has many usage. Use this keyword to access some global data of all objects of a single type.






Magic Method

Another major new feature in PHP V5 is supportMagic methodTo enable the object to quickly change the interface of the object. For exampleConfigurationAdd member variables for each configuration item in the object. No need to useget()Method, as long as you look for a special item to treat it as an array, as shown below.


Listing 11. magic. php5
<?phpclass Configuration{  private $_items = array();  function __construct() {    $this->_items[ 'imgpath' ] = 'images';  }    function __get( $key ) {    return $this->_items[ $key ];  }}$c = new Configuration();echo( $c->{ 'imgpath' }."\n" );?>

In this example, I created a new__get()This method is called as long as the user looks for the member variables on the object. Then, the code in the method will use the item array to find the value and return the value, just as there is a member variable dedicated to this keyword. Assume that the object is an array. At the end of the script, you can see thatConfigurationThe object is like searchingimgpath.

When migrating from PHP V4 to PHP V5, you must pay attention to these language features that are completely unavailable in PHP V4, and re-verify the class to see how these classes can be used.






Exception

Finally, we will introduce the new exception mechanism in PHP V5 to end this article. Exception provides a completely new method for considering error handling. All programs inevitably generate errors, such as file not found and insufficient memory. If no exception is used, the error code must be returned. See the following PHP V4 code.


Listing 12. file. php4
<?phpfunction parseLine( $l ){   // ...   return array( 'error' => 0,     data => array() // data here   );}function readConfig( $path ){  if ( $path == null ) return -1;  $fh = fopen( $path, 'r' );  if ( $fh == null ) return -2;  while( !feof( $fh ) ) {    $l = fgets( $fh );    $ec = parseLine( $l );        if ( $ec['error'] != 0 ) return $ec['error'];  }  fclose( $fh );  return 0;}$e = readConfig( 'myconfig.txt' );if ( $e != 0 )  echo( "There was an error (".$e.")\n" );?>

The standard file I/O Code reads a file, retrieves some data, and returns the error code in case of any errors. I have two questions about this script. The first is the error code. What are the meanings of these error codes? To find out the meaning of these error codes, you must create another system to map these error codes to meaningful strings. The second problem isparseLine. I only need it to return data, but it must actually return the error codeAndData. Most engineers (including myself) are often lazy and return only data, ignoring errors because they are difficult to manage.

Listing 13 shows how clear code is when exceptions are used.


Listing 13. file. php5
<?phpfunction parseLine( $l ){   // Parses and throws and exception when invalid   return array(); // data}function readConfig( $path ){  if ( $path == null )    throw new Exception( 'bad argument' );  $fh = fopen( $path, 'r' );  if ( $fh == null )    throw new Exception( 'could not open file' );  while( !feof( $fh ) ) {    $l = fgets( $fh );    $ec = parseLine( $l );  }  fclose( $fh );}try {   readConfig( 'myconfig.txt' );} catch( Exception $e ) {  echo( $e );}?>

I don't need to worry about the error code because the exception contains incorrect descriptive text. I don't have to consider how to trackparseLineReturned error code, because if an error occurs, this function will throw only one error. Stack will extend to the nearesttry/catchBlock, which is located at the bottom of the script.

The exception mechanism will completely change the code writing method. You don't have to manage headache error codes and mappings, so you can focus on the errors to be handled. This code is easier to read and maintain, and I would like to say that you should be encouraged to add an error handling mechanism, which usually brings benefits.




Conclusion

The addition of new object-oriented features and exception handling provides a strong reason to migrate code from PHP V4 to PHP V5. As you can see, the upgrade process is not difficult. The syntax for extending to PHP V5 is like PHP. Yes, these syntaxes come from languages such as Ruby, but I think they work very well together. These languages also extend the scope of PHP from a scripting language for small sites to a language for enterprise-level applications.

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.