PHP parent and static Keywords

PHP parent and static Keywords

For classes, PHP also has the PHP parent keyword. The PHP parent keyword refers to the PHP base class that a PHP derived class is directly derived from and can be seen as

a sort of alias. The PHP parent keyword is used with the PHP scope resolution operator (::) to access

data or methods in the PHP base class that are overridden in the PHP derived class. The PHP parent keyword allows the PHP derived class to refer to its PHP base class without using its name, just in case the PHP base class is renamed or the PHP class hierarchy is reorganized. The PHP scope resolution operator (::) allows PHP code to access over‐ ridden parts of the PHP base class and avoid having to copy and paste now-inaccessible PHP base class code.

The following PHP code demonstrates the PHP parent keyword, used in a stripped- down version of the PHP User base class and the PHP Admin derived class:

class User {

function User ( $name ) { $this -> name = $name ; }

function getActions () { return array ( 'login' , 'logout' , 'setHomePage' );

class Admin extends User { function Admin ( $name ) { $this -> name = $name ; }

function getActions () { $a = array ( 'showSystemLog' , 'showLoggedInUsers' ); $u = parent :: getActions (); // use the "parent" keyword return array_merge ( $a , $u );

$me = new Admin ( 'admin' ); $actions = $me -> getActions ();

for ( $a = 0 ; $a < count ( $actions ); ++ $a ) {

print $actions [ $a ] . '<br />' ; }

The PHP parent keyword is used in the getActions() function of the PHP Admin derived class. The following PHP code shows the getActions() function of the PHP Admin class where the PHP parent keyword is used:

PHP parent and static Keywords | 173 PHP parent and static Keywords | 173

Together, PHP parent keyword and the PHP scope resolution operator (::), that is, the parent:: text, can be converted to the Node.js code, this.__proto__.__proto__.. As you may recall, the prototype object of a Node.js Admin object contains its private copy of the previously shared Node.js Admin functions. In Node.js, the prototype of that pro‐ totype is the User object contained within the Admin object. The __proto__ property skips the Node.js Admin functions and provides access to the overridden User functions. The following Node.js code shows the Node.js implementation of the PHP get Actions() function of the PHP Admin class:

Admin . prototype . getActions = function () { var a = [ 'showSystemLog' , 'showLoggedInUsers' ];

var u = this . __proto__ . __proto__ . getActions (); // PHP "parent" keyword return a . concat ( u ); }

Here’s the complete Node.js conversion of the PHP parent keyword example code:

function User ( name ) {

this . name = name ; }

User . prototype . getActions = function () { return [ 'login' , 'logout' , 'setHomePage' ];

function Admin ( name ) { var p = Object . create ( new User ( name ), { }); for ( var pp in this . constructor . prototype ) {

p [ pp ] = this . constructor . prototype [ pp ]; } p . constructor = this . constructor ; this . __proto__ = p ; this . name = name ; }

Admin . prototype . getActions = function () { var a = [ 'showSystemLog' , 'showLoggedInUsers' ];

var u = this . __proto__ . __proto__ . getActions (); return a . concat ( u );

} var me = new Admin ( 'admin' );

var actions = me . getActions ();

for ( var a = 0 ; a < actions . length ; ++ a ) { console . log ( actions [ a ]);

174 | Chapter 8: Classes

The following find-and-replace action converts the PHP parent keyword into the cor‐ responding Node.js access to the overridden variable or function:

Operation: "Find/Replace" in Eclipse PDT Find: parent:: Replace: this.__proto__.__proto__. Options: None Action: Replace All

The find-and-replace action can be run globally without visiting each occurrence be‐ cause the PHP parent keyword serves one specific purpose and is only used in one specific way.

Besides the PHP parent keyword, the PHP scope resolution operator (::) is used in other contexts. It can be used to access static variables in PHP classes. A PHP static class variable is a single variable that is shared by all objects of a PHP class, unlike a nonstatic class variable where each PHP object has its own variable.

The PHP static keyword is used to declare a static class variable. Unlike a nonstatic variable, a PHP static class variable must be declared. The class name and the PHP scope resolution operator (::) are used to access the static class variable.

The following PHP page declares the $num static variable in the PHP User class, which tracks the number of PHP User objects that are created. The PHP page then makes three PHP User objects and uses the User::$num variable to print out “The number of User objects is 3”:

<? php class User { static $num = 0 ; // declare the static variable

function User ( $name ) { $this -> name = $name ; ++ User :: $num ; // use the static variable

} } $gilly = new User ( 'gilly' ); $ardo = new User ( 'ardo' ); $hoss = new User ( 'hoss' );

// use the static variable again print 'The number of User objects is ' . User :: $num ; ?>

In Node.js, the prototype object of a constructor function is shared. Functions are rou‐ tinely added to the Node.js prototype so they can be shared between multiple objects. Similarly, a variable can be shared between multiple objects by adding it to the class constructor prototype.

The previous PHP static class variable example is converted to the following Node.js code. The PHP User::$ text is replaced with the Node.js User.prototype. text:

PHP parent and static Keywords | 175 PHP parent and static Keywords | 175

this . name = name ;

++ User . prototype . num ; // use the static variable

User . prototype . num = 0 ; // declare the static variable $gilly = new User ( 'gilly' );

$ardo = new User ( 'ardo' ); $hoss = new User ( 'hoss' );

// use the static variable again console . log ( 'The number of User objects is ' + User . prototype . num );

Previously, when converting PHP class inheritance to Node.js, the shared prototype was copied and removed from the chain of Node.js prototypes for the derived class objects. However, the shared prototype object still exists and still can be accessed directly. Con‐ verting inheritance from PHP to Node.js does not affect how the static class variables are implemented in Node.js. The following find-and-replace action will find where PHP static class variables are defined:

Operation: "Find/Replace" in Eclipse PDT Find: static $ Replace: classname.prototype. Options: None Action: Find, then Replace/Find

At each occurrence, replace classname in the Replace field with the actual class name that the PHP static class variable is contained in. Keep a list of the names of the classes that contain static class variables for the second find-and-replace action that follows.

A second find-and-replace action will convert any reference to a specific PHP static class variable to Node.js. In this find-and-replace action, replace classname with a class name from the list of PHP classes that contain static class variables:

Operation: "Find/Replace" in Eclipse PDT Find: classname::$ Replace: classname.prototype. Options: None Action: Replace All

The find-and-replace action should be run globally without visiting each occurrence for every PHP class that contains a static class variable. After every PHP class has been addressed, PHP static class variables will be completely converted to Node.js.

This chapter described how to convert PHP classes in all their variations to Node.js. Together with the previous two chapters, these three chapters have shown how to convert the three major elements of the PHP language into Node.js: syntax, variables, and classes. In the remaining chapters, the focus will be narrowed to more specific areas, including converting, reading, and writing files; database access; and the JSON format.

176 | Chapter 8: Classes

CHAPTER 9

File Access

Reading and writing files is common in PHP applications. Configuration and template files provide a way to customize a web application, and in order for these files to have their intended effect, a PHP application needs to read and write these files.