More on Private Methods with PHP 5 Member Visibility

Welcome to the final chapter of the series, “Protecting the data of PHP 5 classes with member visibility.” Complemented by copious illustrative examples, this article series guides you through learning the key concepts regarding the use of public, protected, and private data members within PHP 5 classes. This way you can start defining the visibility of the properties and methods of your own classes in a very short time.

Frankly speaking, one of the most useful features introduced into the object model of PHP 5 is “member visibility.” This comes in handy for specifying whether the data members of a certain class will be public, protected. or private.

At a glance, determining the visibility of methods and properties of a given class may seem like a pretty straightforward process that can be tackled with minor hassles. However, when building object-oriented applications that work in real-world conditions, this procedure can be challenging.

Thus, if you’re a PHP developer who wants to learn in an easy way to work with public, protected, and private class members when using PHP 5, then you should start reading this article now!

Now that you’ve been introduced to the main subject of this series, it’s an excellent time to recapitulate the group of topics that I discussed in the last article. As you’ll probably recall, I explained how to declare and implement private methods within a basic PHP 5 class.

Of course, all of the examples were pretty simplistic and certainly wouldn’t be used directly in real world conditions. However, they did show how easy it is to define private methods in PHP 5, and also how useful they can be in certain situations, particularly those cases where it’s necessary to severely protect the member of a given class from undesired access.

Assuming that you’re familiar with working with private methods in PHP 5, it’s time to leap forward and tackle this final article of the series, which will be focused on covering some additional aspects concerning the use of this kind of class method. In addition, I’ll teach you how to utilize the “final” keyword, which is included with PHP 5, to prevent the methods of a specific class from being overridden by any subclass.

Are you ready to begin reading this last episode? Let’s get started!

{mospagebreak title=Reintroducing a previous hands-on example}

As I expressed in the beginning, my plan for this final part of the series consists of completing the discussion of private methods within PHP 5 classes, as well as demonstrating how to use the “final” keyword. Thus, it’d be more than convenient to review one of the hands-on examples developed in the previous tutorial of the series. It illustrated how to declare and implement a pair of private methods within a rudimentary data saving class.

Essentially, the example looked like this:


// define ‘DataSaver’ class (methods are defined private)


class DataSaver{

private $filePath;

private $data;

public function __construct($data,$filePath){

if(!$data||strlen($data)>1024){

throw new Exception(‘Invalid data for being saved to target file.’);

}

if(!file_exists($filePath)){

throw new Exception(‘Invalid target file.’);

}

$this->data=$data;

$this->filePath=$filePath;

}

// save data to target file

public function save(){

if(!$fp=fopen($this->filePath,’w’)){

throw new Exception(‘Error opening target file.’);

}

if(!fwrite($fp,$this->data)){

throw new Exception(‘Error writing data to target file.’);

}

fclose($fp);

}

// get target file via an accessor

private function getFilePath(){

return $this->filePath;

}

// get data via an accessor

private function getData(){

return $this->data;

}

}


try{

// create new instance of ‘DataSaver’ class

$dataSaver=new DataSaver(‘This string of data will be saved to a target file!’,’datafile.txt’);

// save data to target file

$dataSaver->save();

// call private methods

echo ‘Target file is the following : ‘.$dataSaver->getFilePath().'<br />';

echo ‘Data for being saved to target files is the following : ‘.$dataSaver->getData();

/* displays the following

Fatal error: Call to private method DataSaver::getFilePath() from context ” in path/to/file/

*/

}

catch(Exception $e){

echo $e->getMessage();

exit();

}


As you can see, a few interesting things happen: first, a basic “DataSaver” class is built, this time incorporating a couple of private methods, called “getFilePath()” and “getData()” respectively, into its API. Then, an instance of this class is created with the purpose of demonstrating how the PHP interpreter fires up a fatal error each time these methods are called from outside the originating class.

With this simple example grasped, I will assume that you’re pretty familiar with declaring and implementing private methods within a basic PHP 5 class. Therefore, it’s time to look further into the topics that I plan to discuss in the following section.

Well, at this point you know that when a method is declared private by a parent, it simply can’t be called by any of its eventual subclasses, right? This condition can be better understood by way of a hands-on approach, so in the next few lines I’m going to build another practical example aimed at recreating this particular situation.

To see how this brand new example will be developed, click on the link below and keep reading.

{mospagebreak title=Calling a private method from a subclass}

As I expressed in the section that you just read, I’d like to finish discussing the use of private methods in PHP 5 by coding yet another demonstrative example. In this particular case, I want you to see for yourself what happens when a private method defined by a parent is invoked by one of its child classes.

So take a look at the following code sample to dissipate any possible doubts:


// define ‘DataSaver’ class (methods are defined private)


class DataSaver{

protected $filePath;

protected $data;

public function __construct($data,$filePath){

if(!$data||strlen($data)>1024){

throw new Exception(‘Invalid data for being saved to target file.’);

}

if(!file_exists($filePath)){

throw new Exception(‘Invalid target file.’);

}

$this->data=$data;

$this->filePath=$filePath;

}

// save data to target file

public function save(){

if(!$fp=fopen($this->filePath,’w’)){

throw new Exception(‘Error opening target file.’);

}

if(!fwrite($fp,$this->data)){

throw new Exception(‘Error writing data to target file.’);

}

fclose($fp);

}

// get target file via an accessor

private function getFilePath(){

return $this->filePath;

}

// get data via an accessor

private function getData(){

return $this->data;

}

}


// extends ‘DataSaver’ class

class DataHandler extends DataSaver{

// fetch data from target file

public function fetch(){

if(!$data=file_get_contents($this->filePath)){

throw new Exception(‘Error reading data from target file.’);

}

return $data;

}

}


try{

// create new instance of ‘DataHandler’ class

$dataHandler=new DataHandler(‘This string of data will be saved to a target file!’,’datafile.txt’);

// save data to target file

$dataHandler->save();

// call private method

echo $dataHandler->getFilePath();

/* displays the following

Fatal error: Call to private method DataSaver::getFilePath() from context ” in path/to/file/

*/

}

catch(Exception $e){

echo $e->getMessage();

exit();

}


As you can see, I first derived a basic subclass from the “DataSaver” parent, then created a new instance of it, and finally called its “getFilePath()” method in the global scope. This demonstrates in a nutshell that a private method defined by a base class can’t also be invoked by any of its child classes. Not too difficult to understand, right?

So far, so good. Having explained how the prior hands-on example functions, it’s time to end this discussion of private class methods with PHP 5. But wait a minute! Before I finish, I’d like to point out that PHP 5 provides developers with yet another mechanism for preventing the methods of a base class from being overridden by one or more subclasses.

As you might have guessed, I’m talking about the “final” keyword, whose appropriate utilization will be the final subject of this article. Thus, if you’re interested in learning how to use it within your own classes, jump ahead and read the following section. It’s only one click away.

{mospagebreak title=Another way to protect class methods: the final keyword}

Even though it’s not very popular with programmers, PHP 5 supports the use of the “final” keyword, which can be applied to a number of methods of a given class to prevent them from being overridden by any other subclass. Naturally, this keyword is an effective mechanism that can be used to protect one or more methods, but as I said before, isn’t widely utilized by developers nowadays.

Despite its lack of popularity, you may want to see how the “final” keyword can be used in a concrete case. Below I redefined the same “Datasaver” class that I used in the previous section, and it now includes a final version of its “save()” method that can’t be overridden by any child class.

That being explained, the brand new signature of the mentioned class looks like this:


// define ‘DataSaver’ class (uses the ‘final’ keyword)


class DataSaver{

protected $filePath;

protected $data;

public function __construct($data,$filePath){

if(!$data||strlen($data)>1024){

throw new Exception(‘Invalid data for being saved to target file.’);

}

if(!file_exists($filePath)){

throw new Exception(‘Invalid target file.’);

}

$this->data=$data;

$this->filePath=$filePath;

}

// save data to target file

final public function save(){

if(!$fp=fopen($this->filePath,’w’)){

throw new Exception(‘Error opening target file.’);

}

if(!fwrite($fp,$this->data)){

throw new Exception(‘Error writing data to target file.’);

}

fclose($fp);

}

// get target file via an accessor

private function getFilePath(){

return $this->filePath;

}

// get data via an accessor

private function getData(){

return $this->data;

}

}


Pretty simple, right? As you can see, the “save()” method included in the above “Datasaver” class is preceded by the “final” keyword, meaning that the method in question can only be used “as is” by all of the eventual subclasses.

To demonstrate this concept more clearly, I’m going to derive a child class from the pertinent “DataSaver.” This is indicated below:


// extends ‘DataSaver’ class


class DataHandler extends DataSaver{

// try to override method in the parent

public function save(){

session_start();

$_SESSION['data']=$this->data;

}

}


As you can see, at this point I built a basic subclass that overrides the implementation of the “save()” method declared by the corresponding parent. However, this process simply won’t work because of the application of the “final” keyword, which is something that can be seen in the following script:


try{

// create new instance of ‘DataHandler’ class

$dataHandler=new DataHandler(‘This string of data will be saved to a target file!’,’datafile.txt’);

// try to save data to target file

$dataHandler->save();

/* displays the following

Fatal error: Cannot override final method DataSaver::save() in path/to/file/

*/

}

catch(Exception $e){

echo $e->getMessage();

exit();

}


Since the respective “save()” method has been declared “final,” it can’t be overridden by a subclass. So in the above script, the PHP interpreter triggers a fatal error notifying the user about this condition.

As is usual with many of my articles on PHP web development, I encourage you to use all of the code samples included in this article so you can extend your existing skills in using member visibility in PHP 5.

Final thoughts

It’s hard to believe, but we’ve come to the end of this series. Overall, the experience has been instructive, since hopefully you now have a more solid background in declaring and implementing public, protected, and private class members when developing object-based applications with PHP 5.

See you in the next tutorial on PHP development! 

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort