Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1821
  • Last Modified:

Fatal error: Cannot access protected property Test::$protected in C:\wamp\www\phpvqp3_scripts\ch05\visibility.php on line 71

from oop php tutorial
why / how is this error

Fatal error: Cannot access protected property Test::$protected in C:\wamp\www\phpvqp3_scripts\ch05\visibility.php on line 71

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Visibility</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<?php # Script 5.4 - visibility.php
//  This page defines and uses the Test and LittleTest classes. 

# ***** CLASSES ***** #

/* Class Test.
 *  The class contains three attributes:
 *  - public $public
 *  - protected $protected
 *  - private $_private
 *  The class defines one method: printVar().
 */
class Test {

    // Declare the attributes:
    public $public = 'public';
    protected $protected = 'protected';
    private $_private = 'private';  

    // Function for printing a variable's value:
    function printVar($var) {
        echo "<p>In Test, \$$var: '{$this->$var}'.</p>";
    }

} // End of Test class.

/* LittleTest class extends Test.
 * LittleTest overrides printVar().
 */
class LittleTest extends Test {
    function printVar($var) {
        echo "<p>In LittleTest, \$$var: '{$this->$var}'.</p>";
    }
} // End of LittleTest class.

# ***** END OF CLASSES ***** #

// Create the objects:
$parent = new Test();
$child = new LittleTest();

// Print the current value of $public:
echo '<h1>Public</h1>';
echo '<h2>Initially...</h2>';
$parent->printVar('public');
$child->printVar('public');
// Also echo $parent->public or echo $child->public.

// Modify $public and reprint:
echo '<h2>Modifying $parent->public...</h2>';
$parent->public = 'modified';
$parent->printVar('public');
$child->printVar('public');

// Print the current value of $protected:
echo '<hr><h1>Protected</h1>';
echo '<h2>Initially...</h2>';
$parent->printVar('protected');
$child->printVar('protected');

// Attempt to modify $protected and reprint:
echo '<h2>Attempting to modify $parent->protected...</h2>';
$parent->protected = 'modified';
$parent->printVar('protected');
$child->printVar('protected');

// Print the current value of $_private:
echo '<hr><h1>Private</h1>';
echo '<h2>Initially...</h2>';
$parent->printVar('_private');
$child->printVar('_private');

// Attempt to modify $_private and reprint:
echo '<h2>Attempting to modify $parent->_private...</h2>';
$parent->_private = 'modified';
$parent->printVar('_private');
$child->printVar('_private');

// Delete the objects:
unset($parent, $child);

?>
</body>
</html>

Open in new window

0
rgb192
Asked:
rgb192
1 Solution
 
InsoftserviceCommented:
I have done slight changes please check

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Visibility</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<?php # Script 5.4 - visibility.php
//  This page defines and uses the Test and LittleTest classes. 

# ***** CLASSES ***** #

/* Class Test.
 *  The class contains three attributes:
 *  - public $public
 *  - protected $protected
 *  - private $_private
 *  The class defines one method: printVar().
 */
class Test {

    // Declare the attributes:
    public $public = 'public';
    protected $protected = 'protected';
    private $privatevar = 'private';  

    // Function for printing a variable's value:
    function printVar($var) {
        echo "<p>In Test, \$$var: '{$this->$var}'.</p>";
    }

	function toChangeProtected($var)
	{
		 $this->protected =$var;
	}
	function toChangePrivate($var)
	{
		 $this->privatevar =$var;
	}
} // End of Test class.

/* LittleTest class extends Test.
 * LittleTest overrides printVar().
 */
class LittleTest extends Test {
    function printVar($var) {
		
        echo "<p>In LittleTest, \$$var: '{$this->$var}'.</p>";
    }


} // End of LittleTest class.

# ***** END OF CLASSES ***** #

// Create the objects:
$parent = new Test();
$child = new LittleTest();


// Attempt to modify $protected and reprint:
echo '<h2>Attempting to modify $parent->protected...</h2>';
$parent->toChangeProtected('modified');
$parent->printVar('protected');
$child->printVar('protected');

// Print the current value of $_private:
echo '<hr><h1>Private</h1>';
echo '<h2>Initially...</h2>';
$parent->printVar('privatevar');
//$child->printVar('privatevar');

// Attempt to modify $_private and reprint:
echo '<h2>Attempting to modify $parent->_private...</h2>';
$parent->toChangePrivate('modifiedprivate');
$parent->printVar('privatevar');
//$child->printVar('privatevar');

// Delete the objects:
unset($parent, $child);

?>
</body>

Open in new window

0
 
Phil PhillipsDirector of DevOps & Quality AssuranceCommented:
It's because a "protected" variable can only be accessed by its own class or any extending classes.

The other variable scopes are "public" (accessible by anything), or "private" (accessible by ONLY its own class)

In that code sample, any functions that are part of the class "Test" or "LittleTest" are able to access the protected variable.  That's why the 'printVar()' function is working.  But, outside of those classes (like on line 71), the variable isn't accessible.
0
 
SurranoSystem EngineerCommented:
You can access a protected field of the parent class (Test) from a member method of the child (LittleTest) class. But what you try to do is to access the protected field from the global scope.

You can access $parent->protected from Test::printVar and from LittleTest::printVar, that's why printVar works.

Similarly, you can access $parent->private from Test::printVar but *not* from LittleTest::printVar.
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
InsoftserviceCommented:
Its a simple oops concept

Private: Only specified class can access them , even its child class or sub class can not access the data

Protected: Parent and sub class can only access the data.

Protected and private methods prevent outside calls to methods which may upset the internal state of an object.

To modify any protected variables method has to used . Did you tried my examples
0
 
Ray PaseurCommented:
Public, Protected and Private are "visibilities" associated with the properties and methods of a class.  Visibility is a logical extension of the concept of Variable Scope.  In the old ways of PHP, variable scope was basically either global or local.  In object-oriented PHP, variables (variables == properties) are scoped to be public by default.  The same is true of methods (methods == functions).

My preference for visibility, absent any other extenuating circumstances, is to make properties protected and methods public.  To inject data into the object, you must make a formal call to a setter() method.  To retrieve data from an object you must call the getter() method.  If you do it this way, you can use mock objects for unit testing.


Further reading:
0
 
rgb192Author Commented:
I know what public, protected, private are
and I think the best answer is the code sample

I added additional code

//public values
echo '<h1>Public values</h1>';
$parent->printVar('public');
$child->printVar('public');

now I learned it was variable variables

because of revised code sample I was able to learn the errored code sample

Thank you.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now