what is the protected mode in php - php

I Protected works only one inherited class know ,
In this code , the protected works in third class ,
Is It true or any mistake i made in my code ,
<?php
class sample_visibility{
public function my_first_public(){
$MSG = "THIS IS MY PUBLIC FUNCTION ";
return $MSG;
}
private function my_first_private(){
$MSG = "THIS IS MY PRIVATE FUNCTION ";
return $MSG;
}
protected function my_first_protected(){
$MSG = "THIS IS MY PROTECTED FUNCTION ";
return $MSG;
}
}
class sample_visibilit2 extends sample_visibility{
public function my_first_child_public(){
$MSG = "THIS IS MY CHILD PUBLIC FUNCTION ".$this->my_first_protected();
return $MSG;
}
}
class sample_visibilit3 extends sample_visibility{
public function my_first_child_public_3(){
$MSG = "THIS IS MY CHILD PUBLIC FUNCTION ".$this->my_first_protected();
return $MSG;
}
}
$OBJ_CLASS_1 = new sample_visibility();
echo $OBJ_CLASS_1->my_first_public();
$OBJ_CLASS_3 = new sample_visibilit3();
echo $OBJ_CLASS_3->my_first_child_public_3();
?>

You have made no mistake in your code. Protected elements (members or functions) are accessible by children, grandchildren, (great-)*grandchildren. Any number of inheritances is ok. They are only "protected" from unrelated classes.
public - accessible anywhere
protected - derived classes only (any number of inheritances)
private - only accessible internally

Although your question is not very clear, your code is correct and will work.
Inside the classes sample_visibilit2 and sample_visibilit3 you can access my_first_protected(), because both classes are subclasses of sample_visibility.

Related

Visibility Modifiers [duplicate]

Shouldn't it generate error when i try to set the value of a property from the extended class instead of a base class?
<?php
class first{
public $id = 22;
private $name;
protected $email;
public function __construct(){
echo "Base function constructor<br />";
}
public function printit(){
echo "Hello World<br />";
}
public function __destruct(){
echo "Base function destructor!<br />";
}
}
class second extends first{
public function __construct($myName, $myEmail){
$this->name = $myName;
$this->email = $myEmail;
$this->reveal();
}
public function reveal(){
echo $this->name.'<br />';
echo $this->email.'<br />';
}
}
$object = new second('sth','aaa#bbb.com');
?>
Private variables are not accessible in subclasses. Thats what the access modifier protected is for. What happened here is that when you access a variable that doesn't exist, it creates one for you with the default access modifier of public.
Here is the UML to show you the state:
Please note: the subclass still has access to all the public and protected methods and variables from its superclass - but are not in the UML diagram!

Why is PHP private variables working on extended class?

Shouldn't it generate error when i try to set the value of a property from the extended class instead of a base class?
<?php
class first{
public $id = 22;
private $name;
protected $email;
public function __construct(){
echo "Base function constructor<br />";
}
public function printit(){
echo "Hello World<br />";
}
public function __destruct(){
echo "Base function destructor!<br />";
}
}
class second extends first{
public function __construct($myName, $myEmail){
$this->name = $myName;
$this->email = $myEmail;
$this->reveal();
}
public function reveal(){
echo $this->name.'<br />';
echo $this->email.'<br />';
}
}
$object = new second('sth','aaa#bbb.com');
?>
Private variables are not accessible in subclasses. Thats what the access modifier protected is for. What happened here is that when you access a variable that doesn't exist, it creates one for you with the default access modifier of public.
Here is the UML to show you the state:
Please note: the subclass still has access to all the public and protected methods and variables from its superclass - but are not in the UML diagram!

PHP Calling To Object From Another Object

I've been programming mainly with JAVA and have written procedural programs in PHP, but now I'm try to write some OOP bases programs in PHP and I'm facing a problem.
I've got two files , Zoo.php and Dog.php , each contains a class.
Dog.php:
<?php
class Dog {
private $name;
private $color;
public function __construct($name,$color) {
$this->name = $name;
$this->color = $color;
}
public function getName(){
return $this->name;
}
public function getColor(){
return $this->color;
}
}
And Zoo.php:
<?php
class Zoo {
private $name;
private $dogs;
public function __construct($name) {
$this->name = $name;
$dogs = array();
}
public function addDog($dogName,$dogColor){
$dog = new Dog($dogName,$dogColor);
array_push($this->dogs,$dog);
}
public function getAllDogs(){
var_dump($dogs);
}
}
echo "start";
$z = new Zoo("test_zoo");
$z->addDog("blackie","black");
$z->getAllDogs();
The code above outputs :
Fatal error: Class 'Dog' not found in C:\wamp\www\Zoo.php on line 13
I'd like to know what's wrong with the code above and how creating an object instance within another object should be done in PHP. Thanks in advance.
I gues you are not including Dog class.
<?php
include "Dog.php";
class Zoo {
/* ... */
}
Or you can use autoloading to auto include any class by default.
It's not about OOP. Just you forgot to include Dog file to use it you Zoo class :
<?php
include 'Dog.php'; // or whatever path
class Zoo { ...
Everything else should be ok and seems to be a good use of PHP OOP btw. :)
You haven't included your Dog.php in your Zoo.php. Therefore you can't create an new instance.
Just above class Zoo add this:
include("Dog.php");
class Zoo {
All you need to return function .
Three mistakes here, u'll see all of them in my code . Constructer nothing return , behave like void , so we need a method that returns dog specification.If you wanna use the classes in separate file, so u've to use php method that "include" or "require" or "require_once" etc ( see the difference of this method)
<?php
class Dog {
private $name;
private $color;
public function __construct($name,$color) {
$this->name = $name;
$this->color = $color;
}
public function getName(){
return $this->name;
}
public function getColor(){
return $this->color;
}
public function getDogs(){
return array("name"=>$this->name,"color"=>$this->color);
}
}
class Zoo extends Dog{
private $name;
private $dogs=array();
public function __construct($name) {
$this->name = $name;
$dogs = array();
}
public function addDog($dogName,$dogColor){
$dog = new Dog($dogName,$dogColor);
array_push($this->dogs,$dog->getDogs());
}
public function getAllDogs(){
var_dump($this->dogs);
}
}
echo "start";
$z = new Zoo("test_zoo");
$z->addDog("blackie","black");
$z->getAllDogs();
?>

Extended classes and static values

I'm trying to understand how PHP manages memory and variables with static methods in extended classes. I've got three classes one entitled Model, User1, User2. Hence:
class Model {
static public $structure;
static public $name;
static function get_structure() {
return self::$structure = file_get_contents(self::$name.'.json');
}
}
class User1 extends Model {
}
class User2 extends Model {
}
User1::$name = 'User1';
User2::$name = 'User2';
echo User1::get_structure();
echo User2::get_structure();
If I run User1::get_structure(); for some reason it doesn't populate the result accordingly, it seems to be grabbing the value of User2 (the last $name value declared).
I'm operating on the assumption that declaring User2 and extending Model creates a completely separate scope for my $name property. So User1 and User2 are declared as separate classes with the same structure as Model. Then I can statically define values for them in separate scopes.
I'm now however questioning that. If I extend and call the same $name variable do they both point back to the Model class? Or does it only create a separate scope when I declare each class with new User1(); and new User2();?
Thanks.
You get this behavior, because you are accessing same variable
class X
{
public static $data = null;
}
class Foo extends X{};
class Bar extends X{};
Foo::$data = 'lorem ipsum';
echo Bar::$data;
// :: output :: lorem ipsum;
Your $name variable stays tied to the Model class, even in inherited classes.
Yes, all classes that extends Model will point back to the same $name variable.
Sees static variable as a "global" variable.
Maybe this example will clarify you:
class Model
{
static public $name;
}
class User1 extends Model
{
public function setName( $name )
{
parent::$name = $name;
}
public function getName()
{
return parent::$name;
}
}
class User2 extends Model
{
public function setName( $name )
{
parent::$name = $name;
}
public function getName()
{
return parent::$name;
}
}
$user1 = new User1();
$user1->setName("User1");
$user2 = new User2();
$user1->setName("User2");
echo $user1->getName();
echo $user2->getName();
// Output : User2User2
You can work around it with:
<?php
class Model {
static public $structure;
static public $name;
static function get_structure() {
$class = get_called_class();
return $class::$structure = file_get_contents($class::$name.'.json');
}
}
class User1 extends Model {
static public $structure;
static public $name;
}
class User2 extends Model {
static public $structure;
static public $name;
}
User1::$name = 'User1';
User2::$name = 'User2';
echo User1::get_structure();
echo User2::get_structure();
... but, you might ask yourself the question whether this design is the proper one. atm it for instance looks like they should be instances with separate values & instance methods, but that might be because of the condensed example.

OOP: Problem accessing parent's property from the extended child

I try to access the parent's property from its extended child similar to the concept below,
class Base
{
protected static $me;
protected static $var_parent_1;
protected static $var_parent_2;
public function __construct ($var_parent_1 = null)
{
$this->var_parent_1 = $var_parent_1;
$this->me = 'the base';
}
public function who() {
echo $this->me;
}
public function parent_1() {
echo $this->var_parent_1;
}
}
class Child extends Base
{
protected static $me;
protected static $var_child_1;
protected static $var_child_2;
public function __construct ($var_child_1 = null)
{
parent::__construct();
$this->var_child_1 = $var_child_1;
$this->me = 'the child extends '.parent::$me;
}
// until PHP 5.3, will need to redeclare this
public function who() {
echo $this->me;
}
public function child_1() {
echo $this->var_child_1;
}
}
$objA = new Base($var_parent_1 = 'parent var 1');
$objA->parent_1(); // "parent var 1"
$objA->who(); // "the base"
$objB = new Child($var_child_1 = 'child var 1');
$objB->child_1(); // "child var 1"
$objB->who(); // should get "the child extends the base"
But I get "the child extends" instead of "the child extends the base" if I use $this->
It seems OK if I change all $this-> to self::
Why?
Is that the only proper way to access the parent's property which is to change all $this-> to self::?
EDIT:
I removed all static keywords,
class Base
{
protected $me;
protected $var_parent_1;
protected $var_parent_2;
public function __construct ($var_parent_1 = null)
{
$this->var_parent_1 = $var_parent_1;
$this->me = 'the base';
}
public function who() {
echo $this->me;
}
public function parent_1() {
echo $this->var_parent_1;
}
}
class Child extends Base
{
protected $me;
protected $var_child_1;
protected $var_child_2;
public function __construct ($var_child_1 = null)
{
parent::__construct();
$this->var_child_1 = $var_child_1;
$this->me = 'the child extends '.parent::$me;
}
// until PHP 5.3, will need to redeclare this
public function who() {
echo $this->me;
}
public function child_1() {
echo $this->var_child_1;
}
}
$objA = new Base($var_parent_1 = 'parent var 1');
//$objA->parent_1(); // "parent var 1"
//$objA->who(); // "the base"
$objB = new Child($var_child_1 = 'child var 1');
$objB->child_1(); // "child var 1"
$objB->who(); // "the child extends the base"
Then I get this error Fatal error: Access to undeclared static property: Base::$me in C:\wamp\www\test\2011\php\inheritence.php on line 109 which refers to this line,
$this->me = 'the child extends '.parent::$me;
(simplified answer, I don't know how I could explain this without writing 20 pages, sorry).
At execution time, your base and child classes are merged in a single object. In that case, your instance variables are merged too. So, you can't call parent::$avar, you just can call $this->var (as all vars become elements of the current instance)
The behavior is quite different for methods : as the child class is supposed to be a specialization of the base class, the code written in the base class does not necessarily need to be completely rewritten : you can just call it and perform additional operations, without having te rewrite the original code in the child class.
static properties are properties of the classes, not of the objects you create with them. a static property is shared by all objects of that class, and is accessed using self::
if you remove static it should work the way you want, and you would use $this-> as you are now.

Categories