© Frank M. Kromann 2018
Frank M. KromannBeginning PHP and MySQLhttps://doi.org/10.1007/978-1-4302-6044-8_7

7. Advanced OOP Features

Frank M. Kromann1 
(1)
Aliso Viejo, CA, USA
 
Chapter 6 introduced the fundamentals of object-oriented programming (OOP). This chapter builds on that foundation by introducing several of PHP’s more advanced OOP features. Specifically, this chapter introduces the following five features:
  • Object cloning: PHP treats all objects as references and they can be created with the use of the new operator. With that in mind, how do you go about creating a copy of an object if all objects are treated as references? By cloning the object.

  • Inheritance: As discussed in Chapter 6, the ability to build class hierarchies through inheritance is a fundamental OOP concept. This chapter introduces PHP’s inheritance features and syntax, and it includes several examples that demonstrate this key OOP feature.

  • Interfaces: An interface is a collection of unimplemented method definitions and constants that serves as a class blueprint. Interfaces define exactly what can be done with the class, without getting bogged down with implementation-specific details. This chapter introduces PHP’s interface support and offers several examples demonstrating this powerful OOP feature.

  • Abstract classes: An abstract class is a class that cannot be instantiated. Abstract classes are intended to be inherited by a class that can be instantiated, better known as a concrete class. Abstract classes can be fully implemented, partially implemented, or not implemented at all. This chapter presents general concepts surrounding abstract classes, coupled with an introduction to PHP’s class abstraction capabilities.

  • Namespaces: Namespaces help you to more effectively manage your code base by compartmentalizing various libraries and classes according to context. In this chapter, I’ll introduce you to PHP’s namespace feature.

Advanced OOP Features Not Supported by PHP

If you have experience in other object-oriented languages, you might be scratching your head over why the previous list of features doesn’t include certain OOP features supported by other programming languages. The reason might well be that PHP doesn’t support those features. To save you from further wonderment, the following list enumerates the advanced OOP features that are not supported by PHP and thus are not covered in this chapter:
  • Method overloading : The ability to implement polymorphism through method overloading is not supported by PHP and probably never will be. It is, however, possible to achieve something that works in a similar way. This is done with the magic methods __set(), __get() and __call() etc. ( http://php.net/manual/en/language.oop5.overloading.php )

  • Operator overloading : The ability to assign additional meanings to operators based upon the type of data you’re attempting to modify is currently not supported by PHP. Based on discussions found in the PHP developer’s mailing list and an RFC for its implementation ( https://wiki.php.net/rfc/operator-overloading ), it might someday be implemented.

  • Multiple inheritance : PHP does not support multiple inheritance. Implementation of multiple interfaces is supported. And traits as described in the previous chapter provide a way to implement similar functionality.

Only time will tell whether any or all of these features will be supported in future versions of PHP.

Object Cloning

In PHP the objects are treated as references. Assigning an object to another variable simply creates a second reference to the same object. Manipulating any of the properties will have an effect on the object referenced by both variables. This makes it possible to pass objects to functions and methods. However, because all objects are treated as references rather than as values, it is more difficult to copy an object. If you try to copy a referenced object, to remedy the problems with copying, PHP offers an explicit means for cloning an object.

Let’s first look at an example, Listing 7-1, where an object is assigned to a second variable.
<?php
class Employee {
  private $name;
  function setName($name) {
    $this->name = $name;
  }
  function getName() {
    return $this->name;
  }
}
$emp1 = new Employee();
$emp1->setName('John Smith');
$emp2 = $emp1;
$emp2->setName('Jane Smith');
echo "Employee 1 = {$emp1->getName()} ";
echo "Employee 2 = {$emp2->getName()} ";
Listing 7-1

Copying an Object

The output from this example illustrates that even though $emp1 and $emp2 look like two different variables, they are both referencing the same object. It will look like this:
Employee 1 = Jane Smith
Employee 2 = Jane Smith

Cloning Example

You clone an object by prefacing it with the clone keyword , like so:
$destinationObject = clone $targetObject;
Listing 7-2 presents an object-cloning example. This example uses a sample class named Employee , which contains two properties (employeeid and tiecolor ) and corresponding getters and setters for these properties. The example code instantiates an Employee object and uses it as the basis for demonstrating the effects of a clone operation.
<?php
    class Employee {
        private $employeeid;
        private $tiecolor;
        // Define a setter and getter for $employeeid
        function setEmployeeID($employeeid) {
            $this->employeeid = $employeeid;
        }
        function getEmployeeID() {
            return $this->employeeid;
        }
        // Define a setter and getter for $tiecolor
        function setTieColor($tiecolor) {
            $this->tiecolor = $tiecolor;
        }
        function getTieColor() {
            return $this->tiecolor;
        }
    }
    // Create new Employee object
    $employee1 = new Employee();
    // Set the $employee1 employeeid property
    $employee1->setEmployeeID("12345");
    // Set the $employee1 tiecolor property
    $employee1->setTieColor("red");
    // Clone the $employee1 object
    $employee2= clone $employee1;
    // Set the $employee2 employeeid property
    $employee2->setEmployeeID("67890");
    // Output the $employee1and $employee2employeeid properties
   printf("Employee 1 employeeID: %d <br />", $employee1->getEmployeeID());
   printf("Employee 1 tie color: %s <br />", $employee1->getTieColor());
   printf("Employee 2 employeeID: %d <br />", $employee2->getEmployeeID());
   printf("Employee 2 tie color: %s <br />", $employee2->getTieColor());
?>
Listing 7-2

Cloning an Object with the clone Keyword

Executing this code returns the following output:
Employee1 employeeID: 12345
Employee1 tie color: red
Employee2 employeeID: 67890
Employee2 tie color: red

As you can see, $employee2 became an object of type Employee and inherited the property values of $employee1. To further demonstrate that $Employee2 is indeed of type Employee, its employeeid property was also reassigned.

The __clone() Method

You can tweak an object’s cloning behavior by defining a __clone() method within the object class. Any code in this method will execute directly following PHP’s native cloning behavior. Let’s revise the Employee class , adding the following method:
function __clone() {
   $this->tiecolor = "blue";
}
With this in place, let’s create a new Employee object, add the employeeid property value, clone it, and then output some data to show that the cloned object’s tiecolor was indeed set through the __clone() method. Listing 7-3 offers the example.
// Create new Employee object
$employee1 = new Employee();
// Set the $employee1 employeeid property
$employee1->setEmployeeID("12345");
// Clone the $employee1 object
$employee2 = clone $employee1;
// Set the $employee2 employeeid property
$employee2->setEmployeeID("67890");
// Output the $employee1 and $employee2 employeeid properties
printf("Employee1 employeeID: %d <br />", $employee1->getEmployeeID());
printf("Employee1 tie color: %s <br />", $employee1->getTieColor());
printf("Employee2 employeeID: %d <br />", $employee2->getEmployeeID());
printf("Employee2 tie color: %s <br />", $ employee2->getTieColor());
Listing 7-3

Extending clone’s Capabilities with the __clone() Method

Executing this code returns the following output:
Employee1 employeeID: 12345
Employee1 tie color: red
Employee2 employeeID: 67890
Employee2 tie color: blue

Inheritance

People are adept at thinking in terms of organizational hierarchies; we make widespread use of this conceptual view to manage many aspects of our everyday lives. Corporate management structures, the Dewey Decimal system, and our view of the plant and animal kingdoms are just a few examples of systems that rely heavily on hierarchical concepts. Because OOP is based on the premise of allowing humans to closely model the properties and behaviors of the real-world environment that we’re trying to implement in code, it makes sense to also be able to represent these hierarchical relationships.

For example, suppose that your application calls for a class titled Employee , which is intended to represent the characteristics and behaviors that one might expect from a company employee. Some class properties that represent characteristics might include the following:
  • name : The employee’s name

  • age : The employee’s age

  • salary : The employee’s salary

  • yearsEmployed: The number of years the employee has been with the company

Some Employee class methods might include the following:
  • doWork : Perform some work-related task

  • eatLunch : Take a lunch break

  • takeVacation : Make the most of those valuable two weeks

These characteristics and behaviors would be relevant to all types of employees, regardless of the employee’s purpose or stature within the organization. Obviously, though, there are also differences among employees; for example, the executive might hold stock options and be able to pillage the company while other employees are not afforded such luxuries. An assistant must be able to take a memo, and an office manager needs to take supply inventories. Despite these differences, it would be quite inefficient if you had to create and maintain redundant class structures for those attributes that all classes share. The OOP development paradigm takes this into account, allowing you to inherit from and build upon existing classes.

Class Inheritance

Class inheritance in PHP is accomplished by using the extends keyword. Listing 7-4 demonstrates this ability, first creating an Employee class and then creating an Executive class that inherits from Employee.

Note

A class that inherits from another class is known as a child class, or a subclass . The class from which the child class inherits is known as the parent , or base class .

<?php
   // Define a base Employee class
   class Employee {
      private $name;
      // Define a setter for the private $name property.
      function setName($name) {
         if ($name == "") echo "Name cannot be blank!";
         else $this->name = $name;
      }
      // Define a getter for the private $name property
      function getName() {
         return "My name is ".$this->name."<br />";
      }
   } // end Employee class
   // Define an Executive class that inherits from Employee
   class Executive extends Employee {
      // Define a method unique to Employee
      function pillageCompany() {
         echo "I'm selling company assets to finance my yacht!";
      }
   } // end Executive class
   // Create a new Executive object
   $exec = new Executive();
   // Call the setName() method, defined in the Employee class
   $exec->setName("Richard");
   // Call the getName() method
   echo $exec->getName();
   // Call the pillageCompany() method
   $exec->pillageCompany();
?>
Listing 7-4

Inheriting from a Base Class

This returns the following:
My name is Richard.
I'm selling company assets to finance my yacht!

Because all employees have a name, the Executive class inherits from the Employee class , saving you the hassle of having to re-create the name property and the corresponding getter and setter. You can then focus solely on those characteristics that are specific to an executive, in this case a method named pillageCompany() . This method is available solely to objects of type Executive, and not to the Employee class or any other class—unless you create a class that inherits from Executive. The following example demonstrates that concept, producing a class titled CEO , which inherits from Executive:

<?php
class Employee {
 private $name;
 private $salary;
 function setName($name) {
   $this->name = $name;
 }
 function setSalary($salary) {
   $this->salary = $salary;
 }
 function getSalary() {
   return $this->salary;
 }
}
class Executive extends Employee {
 function pillageCompany() {
   $this->setSalary($this->getSalary() * 10);
 }
}
class CEO extends Executive {
  function getFacelift() {
     echo "nip nip tuck tuck ";
  }
}
$ceo = new CEO();
$ceo->setName("Bernie");
$ceo->setSalary(100000);
$ceo->pillageCompany();
$ceo->getFacelift();
echo "Bernie's Salary is: {$ceo->getSalary()} ";
?>
Listing 7-5

Inheritance

The output will look like this:
nip nip tuck tuck
Bernie's Salary is: 1000000

Because Executive has inherited from Employee, objects of type CEO have all the properties and methods that are available to Executive in addition to the getFacelift() method , which is reserved solely for objects of type CEO.

Inheritance and Constructors

A common question pertinent to class inheritance has to do with the use of constructors. Does a parent class constructor execute when a child is instantiated? If so, what happens if the child class also has its own constructor? Does it execute in addition to the parent constructor, or does it override the parent? Such questions are answered in this section.

If a parent class offers a constructor, it does execute when the child class is instantiated, provided that the child class does not also have a constructor. For example, suppose that the Employee class offers this constructor:
function __construct($name) {
    $this->setName($name);
}
Then you instantiate the CEO class and retrieve the name property:
$ceo = new CEO("Dennis");
echo $ceo->getName();
It will yield the following:
My name is Dennis
However, if the child class also has a constructor, that constructor will execute when the child class is instantiated, regardless of whether the parent class also has a constructor. For example, suppose that in addition to the Employee class containing the previously described constructor, the CEO class contains this constructor :
function __construct() {
    echo "<p>CEO object created!</p>";
}
Then you instantiate the CEO class :
$ceo = new CEO("Dennis");
echo $ceo->getName();
This time it will yield the following output because the CEO constructor overrides the Employee constructor:
CEO object created!
My name is
When it comes time to retrieve the name property, you find that it’s blank because the setName() method , which executes in the Employee constructor, never fires. Of course, you’re probably going to want those parent constructors to also fire. Not to fear because there is a simple solution. Modify the CEO constructor like so:
function __construct($name) {
    parent::__construct($name);
    echo "<p>CEO object created!</p>";
}
Again, instantiating the CEO class and executing getName() in the same fashion as before, this time you’ll see a different outcome:
CEO object created!
My name is Dennis

You should understand that when parent::__construct() was encountered, PHP began a search upward through the parent classes for an appropriate constructor. Because it did not find one in Executive, it continued the search up to the Employee class, at which point it located an appropriate constructor. If PHP had located a constructor in the Employee class, then it would have fired. If you want both the Employee and Executive constructors to fire, you need to place a call to parent::__construct() in the Executive constructor.

You also have the option to reference parent constructors in another fashion. For example, suppose that both the Employee and Executive constructors should execute when a new CEO object is created. These constructors can be referenced explicitly within the CEO constructor like so:
function __construct($name) {
    Employee::__construct($name);
    Executive::__construct();
    echo "<p>CEO object created!</p>";
}

Inheritance and Late Static Binding

When creating class hierarchies, you’ll occasionally run into situations in which a parent method will interact with static class properties that may be overridden in a child class. This has to do with the use of the self keyword. Let’s consider an example involving a revised Employee and Executive class :
<?php
class Employee {
  public static $favSport = "Football";
  public static function watchTV()
  {
    echo "Watching ".self::$favSport;
  }
}
class Executive extends Employee {
  public static $favSport = "Polo";
}
echo Executive::watchTV();
?>
Listing 7-6

Late Static Binding

Because the Executive class inherits the methods found in Employee, one would presume that the output of this example would be Watching Polo, right? Actually, this doesn’t happen because the self keyword determines its scope at compile time rather than at runtime. Therefore, the output of this example will always be Watching Football. PHP remedies this issue by repurposing the static keyword for use when you actually want the scope of static properties to be determined at runtime. To do so, you would rewrite the watchTV() method like this:
  public static function watchTV()
  {
    echo "Watching ".static::$favSport;
  }

Interfaces

An interface defines a general specification for implementing a particular service, declaring the required functions and constants without specifying exactly how it must be implemented. Implementation details aren’t provided because different entities might need to implement the published method definitions in different ways. The nature of interfaces requires all interface methods to be public.

The point is to establish a general set of guidelines that must be implemented in order for the interface to be considered implemented.

Caution

Class properties are not defined within interfaces. This is a matter left entirely to the implementing class.

Take, for example, the concept of pillaging a company. This task might be accomplished in a variety of ways, depending on who is doing the dirty work. For example, a typical employee might do his part by using the office credit card to purchase shoes and movie tickets, writing the purchases off as “office expenses,” while an executive might ask his assistant to reallocate funds to a Swiss bank account through the online accounting system. Both employees are intent on pillaging, but each goes about it in a different way. In this case, the goal of the interface is to define a set of guidelines for pillaging the company and then ask the respective classes to implement that interface accordingly. For example, the interface might consist of just two methods:
emptyBankAccount()
burnDocuments()
You can then ask the Employee and Executive classes to implement these features. In this section, you’ll learn how this is accomplished. First, however, take a moment to understand how PHP 5 implements interfaces. In PHP, an interface is created like so:
interface iMyInterface
{
    CONST 1;
    ...
    CONST N;
    function methodName1();
    ...
    function methodNameN();
}

Tip

It’s common practice to preface the names of interfaces with the lowercase letter i to make them easier to recognize.

An interface is a collection of method definitions (names and parameter list) that is used as a form of contract when a class implements one or more interfaces. The contract is completed when a class implements the interface via the implements keyword. All methods must be implemented with the same signature as defined in the interface, or the implementing class must be declared abstract (a concept introduced in the next section); otherwise, an error similar to the following will occur:
Fatal error: Class Executive contains 1 abstract methods and must
therefore be declared abstract (pillageCompany::emptyBankAccount) in
/www/htdocs/pmnp/7/executive.php on line 30
The following is the general syntax for implementing the preceding interface:
class Class_Name implements iMyInterface
{
    function methodName1()
    {
        // methodName1() implementation
    }
    function methodNameN()
    {
        // methodNameN() implementation
    }
}

Implementing a Single Interface

This section presents a working example of PHP’s interface implementation by creating and implementing an interface named iPillage that is used to pillage the company:
interface iPillage
{
    function emptyBankAccount();
    function burnDocuments();
}
This interface is then implemented for use by the Executive class :
class Executive extends Employee implements iPillage
{
    private $totalStockOptions;
    function emptyBankAccount()
    {
        echo "Call CFO and ask to transfer funds to Swiss bank account.";
    }
    function burnDocuments()
    {
        echo "Torch the office suite.";
    }
}
Because pillaging should be carried out at all levels of the company, you can implement the same interface by the Assistant class :
class Assistant extends Employee implements iPillage
{
    function takeMemo() {
        echo "Taking memo...";
    }
    function emptyBankAccount()
    {
        echo "Go on shopping spree with office credit card.";
    }
    function burnDocuments()
    {
        echo "Start small fire in the trash can.";
    }
}

As you can see, interfaces are particularly useful because, although they define the number and name of the methods and parameters required for some behavior to occur, they acknowledge the fact that different classes might require different ways of carrying out those methods. In this example, the Assistant class burns documents by setting them on fire in a trash can, while the Executive class does so through somewhat more aggressive means (setting the executive’s office on fire).

Implementing Multiple Interfaces

Of course, it wouldn’t be fair to allow outside contractors to pillage the company; after all, it was upon the backs of the full-time employees that the organization was built. That said, how can you provide employees with the ability to both do their jobs and pillage the company, while limiting contractors solely to the tasks required of them? The solution is to break these tasks down into several tasks and then implement multiple interfaces as necessary. Consider this example:
<?php
    interface iEmployee {...}
    interface iDeveloper {...}
    interface iPillage {...}
    class Employee implements IEmployee, IDeveloper, iPillage {
    ...
    }
    class Contractor implements iEmployee, iDeveloper {
    ...
    }
?>

As you can see, all three interfaces (iEmployee , iDeveloper , and iPillage ) have been made available to the employee, while only iEmployee and iDeveloper have been made available to the contractor.

Determining Interface Existence

The interface_exists() function determines whether an interface exists, returning TRUE if it does and FALSE otherwise. Its prototype follows:
boolean interface_exists(string interface_name [, boolean autoload])

Abstract Classes

An abstract class is a class that really isn’t supposed to ever be instantiated but instead serves as a base class to be inherited by other classes. For example, consider a class titled Media , intended to embody the common characteristics of various types of published materials such as newspapers, books, and CDs. Because the Media class doesn’t represent a real-life entity but is instead a generalized representation of a range of similar entities, you’d never want to instantiate it directly. To ensure that this doesn’t happen, the class is deemed abstract. The various derived Media classes then inherit this abstract class, ensuring conformity among the child classes because all methods defined in that abstract class must be implemented within the subclass.

A class is declared abstract by prefacing the definition with the word abstract, like so:
abstract class Media
{
  private $title;
  function setTitle($title) {
    $this->title = $title;
  }
  abstract function setDescription($description)
}
class Newspaper extends Media
{
  function setDescription($description) {
  }
  function setSubscribers($subscribers) {
  }
}
class CD extends Media
{
  function setDescription($description) {
  }
  function setCopiesSold($subscribers) {
  }
}
Attempting to instantiate an abstract class results in the following error message:
Fatal error: Cannot instantiate abstract class Employee in
/www/book/chapter07/class.inc.php.

Abstract classes ensure conformity because any classes derived from them must implement all abstract methods derived within the class. Attempting to forgo implementation of any abstract method defined in the class results in a fatal error.

Abstract Class or Interface?

When should you use an interface instead of an abstract class, and vice versa? This can be quite confusing and is often a matter of considerable debate. However, there are a few factors that can help you formulate a decision in this regard:
  • If you intend to create a model that will be assumed by a number of closely related objects, use an abstract class. If you intend to create functionality that will subsequently be embraced by a number of unrelated objects, use an interface.

  • If your object must inherit behavior from a number of sources, use an interface. PHP classes can implement multiple interfaces but can only extend single (abstract) classes .

  • If you know that all classes will share a common behavior implementation, use an abstract class and implement the behavior there. You cannot implement behavior in an interface.

  • If multiple classes share the exact same code, use traits.

Introducing Namespaces

As you continue to create class libraries as well as use third-party class libraries created by other developers, you’ll inevitably encounter a situation where two libraries use identical class names, producing unexpected application results.

To illustrate the challenge, suppose you’ve created a website that helps you organize your book collection and allows visitors to comment on any books found in your personal library. To manage this data, you create a library named Library.inc.php , and within it a class named Clean . This class implements a variety of general data filters that you could apply to not only book-related data but also user comments. Here’s a snippet of the class, including a method named filterTitle() that can be used to clean up both book titles and user comments:
class Clean {
    function filterTitle($text) {
        // Trim white space and capitalize first word
        return ucfirst(trim($text));
    }
}
Because this is a G-rated website, you also want to pass all user-supplied data through a profanity filter. An online search turned up a PHP class library called DataCleaner.inc.php , which unbeknown to you includes a class named Clean. This class includes a function named RemoveProfanity() , which is responsible for substituting bad words with acceptable alternatives. The class looks like this:
class Clean {
    function removeProfanity($text) {
        $badwords = array("idiotic" => "shortsighted",
                          "moronic" => "unreasonable",
                          "insane" => "illogical");
        // Replace bad words
        return strtr($text, $badwords);
    }
}
Eager to begin using the profanity filter, you include the DataCleaner.inc.php file at the top of the relevant script, followed by a reference to the Library.inc.php library :
require "DataCleaner.inc.php";
require "Library.inc.php";
You then make some modifications to take advantage of the profanity filter, but upon loading the application into the browser, you’re greeted with the following fatal error message:
Fatal error: Cannot redeclare class Clean

You’re receiving this error because it’s not possible to use two classes of the same name within the same script. This is similar to a file system where you can’t have two files with the same name in a directory, but they can exist in two different directories.

There’s a simple way to resolve this issue by using namespaces. All you need to do is assign a namespace to each class. To do so, you need to make one modification to each file. Open Library.inc.php and place this line at the top:
namespace Library;
Likewise, open DataCleaner.inc.php and place the following line at the top:
namespace DataCleaner;

The namespace statement must be the first statement in the file.

You can then begin using the respective Clean classes without fear of name clashes. To do so, instantiate each class by prefixing it with the namespace, as demonstrated in the following example:
<?php
    require "Library.inc.php";
    require "Data.inc.php";
    use Library;
    use DataCleaner;
    // Instantiate the Library's Clean class
    $filter = new LibraryClean();
    // Instantiate the DataCleaner's Clean class
    $profanity = new DataCleanerClean();
    // Create a book title
    $title = "the idiotic sun also rises";
    // Output the title before filtering occurs
    printf("Title before filters: %s <br />", $title);
    // Remove profanity from the title
    $title = $profanity->removeProfanity($title);
    printf("Title after LibraryClean: %s <br />", $title);
    // Remove white space and capitalize title
    $title = $filter->filterTitle($title);
    printf("Title after DataCleanerClean: %s <br />", $title);
?>
Executing this script produces the following output:
Title before filters: the idiotic sun also rises
Title after DataCleanerClean: the shortsighted sun also rises
Title after LibraryClean: The Shortsighted Sun Also Rises

Namespaces can be defined as a hierarchy of sub-name spaces. This is done by adding more names separated by the namespace separator (backslash). This is useful if the same package or vendor provides multiple versions of a class, function or constant, or multiple classes with functionality that you want to group together.

As an example, here is a list of the namespaces provided by the Amazon Web Services (AWS) SDK:
namespace AwsS3;
namespace AwsS3Command;
namespace AwsS3Enum;
namespace AwsS3Exception;
namespace AwsS3ExceptionParser;
namespace AwsS3Iterator;
namespace AwsS3Model;
namespace AwsS3ModelMultipartUpload;
namespace AwsS3Sync;
The SDK contains many other namespaces for the various services provided. The names in these examples are not too long and only two or three levels are used. In some cases, you might want to specify a shorter name for your namespace. This will require less typing and make the code more readable. This is done by providing an alias to the namespace. This is best illustrated with a short example.
<php
use AwsS3Command;
$cmd = new AwsS3CommandS3Command();
In this case, the namespace was imported or used as is, and all the classes (and functions and constants) would have to be prefixed with the full namespace name.
<php
use AwsS3Command as Cmd;
$cmd = new CmdS3Command();

In the second example, the namespace is renamed to Cmd, and all references to classes and functions after that will be prefixed with the short name.

A special namespace is the global namespace. This is referenced with a backslash (). All the built-in functions and classes are placed in the global namespace. In order to access any of these from within a given namespace, you would have to specify that the function or class belongs to the global namespace. This is only needed if you are using namespaces.
<?php
namespace MyNamespace;
/* This function is MyNamespacegetFile() */
function getFile($path) {
     /* ... */
     $content = file_get_contents($path);
     return $content;
}
?>

In the example above, the new function getFile() is defined inside a namespace called MyNamespace. In order to call the global function file_get_contents() , it will have to be designated as global by prefixing it with .

Summary

This and the previous chapter introduced you to the entire gamut of PHP’s OOP features. PHP supports most of the OOP concepts that exist in other programming languages, and many of the libraries and frameworks available today utilize these concepts. If you’re new to OOP, the material should help you to better understand many of the key OOP concepts and inspire you to perform additional experimentation and research.

The next chapter introduces a powerful solution for efficiently detecting and responding to unexpected operational errors that may crop up during your website’s execution, known as exceptions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.79.59