Trying to understand PHP OOP - php

I'm wondering why the following code won't print out anything. I'm trying to access Bar::$some_var from method in parent class. Where Bar::$some_var is defined in it's constructor.
I've tried using self::$some_var and static::$some_var in Foo::hello() but neither worked. Do I have to make $some_var static?
class Foo {
private $some_var;
public function __construct() {
$this->some_var = 5;
}
public function hello() {
print $this->some_var;
}
}
class Bar extends Foo {
public function __construct() {
$this->some_var = 10;
}
}
$bar = new Bar();
$bar->hello();
Thanks in advance.

private makes a member variable unavailable outside of a class. You need to use protected to allow extending classes to have access to that variable.
protected $some_var;
See Visibility

Your class variable cannot be private if you would like your child class to access it.
Try protected instead and it should work!

:: operator is used to access class items (constants, static
variables, static methods)
-> operator is used to access object items (non static properties and methods)
anyway in your code the problem is visibility of $some_var. It has to be almost protected, public will also work

Related

How can a PHP class that extends another inherit a private function?

I am trying to extend a PHP class without rewriting the whole thing. Here is an example:
<?
$a = new foo();
print $a->xxx();
$b = new bar();
print $b->xxx();
class foo {
const something = 10;
public function xxx() {
$this->setSomething();
return $this->something;
}
private function setSomething() {
$this->something = self::something;
}
}
class bar extends foo {
public function xxx() {
$this->setSomething();
$this->something++;
return $this->something;
}
}
?>
However when I run the script I get the following error:
Fatal error: Call to private method foo::setSomething() from context 'bar' in test.php on line 23
It would seem that bar is not inheriting the private function setSomething(). How would I fix this without modifying the foo class?
No, you can not fix this without modifying the foo class. Because an inherited class can not access parent class's private members. It's a very basic oop rule.
Declare setSomething() as protected. It'll be solved.
See manual
Private members are not inheritable, you can not use them in sub class. They are not accessible outside the class.
You must need to make that function as protected or public. Protected members are accessible to that class and for the inherited class. So, your best bet is to make that function Protected.
bar is inheriting the function alright, but it can't call it. That's the whole point of private methods, only the declaring class can call them.
Try reflection
http://php.net/manual/en/class.reflectionclass.php
Also:
Call private methods and private properties from outside a class in PHP
Did you try this?
class bar extends foo {
public function xxx() {
$this->something = parent::xxx();
$this->something++;
return $this->something;
}
}
Note the parent::xxx(); is public, so it should work... even though it looks like a static call.
Without modifying the original class, there is no way for the inherited class to directly call private methods of the parent class.

php object oriented visibility

I'm a little confused about this paragraph on OO visibilty in PHP. was curious if someone could explain it to me. examples would be GREAT! my brain is not thinking clear.
http://www.php.net/manual/en/language.oop5.visibility.php
The first paragraph reads
The visibility of a property or method
can be defined by prefixing the
declaration with the keywords public,
protected or private. Class members
declared public can be accessed
everywhere. Members declared protected
can be accessed only within the class
itself and by inherited and parent
classes. Members declared as private
may only be accessed by the class that
defines the member.
how can a parent class access a childs class member?
That's how:
class A {
public function test() {
$b = new B;
echo $b->foo;
}
}
class B extends A {
protected $foo = 'bar';
}
$a = new A;
$a->test();
PHP is an interpreted language. Properties are resolved at runtime, not at the compiling stage. And access modifiers are just checked when a property is accessed.
It makes no difference if you ad-hoc inject a new (undeclared) property so it becomes public, or if you declare a protected property in an inherited class.
The private really only affects the accessibility from the outside. The ->name resolving at runtime works regardless of that. And the PHP runtime simply doesn't prope if the property declaration was made for the current object instances class. (Unlike for private declarations.)
public scope: property (method, variable etc) can be accessed from any class in any file.
class Example {
public $foo;
}
$example = new Example;
$example->foo = 3; // everything OK
private scope: property can only be accessed only by same class.
class Example {
private $foo;
}
class Child_Class extends Example {
public function some_method()
{
parent::foo = 3; // raises error
}
}
protected scope: property can only be accessed by same class or by other classes that extend it.
class Example {
protected $foo;
}
class Child_Class extends Example {
public function some_method()
{
parent::foo = 3; // this is OK
}
}
It all has to do with a technique named encapsulation, in which you must not allow a class member's state or behavior to be changed outside the class. http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
Protected is a type of visibility which makes properties and methods declared protected available in the child classes of the declared class.
class Parent {
public $name = 'MyName';
protected $age = 20;
private $school = 'MySchool';
}
class Child extends Parent {
public function __construct() {
echo $this -> name; // valid as public
echo $this -> age; // valid as protected
echo $this -> school; // invalid as private
}
}
There you understand protected is something that used in inheritance.

Protected static member variables

I've recently been working on some class files and I've noticed that the member variables had been set in a protected static mode like protected static $_someVar and accessed like static::$_someVar.
I understand the concept of visibility and that having something set as protected static will ensure the member variable can only be accessed in the super class or derived classes but can I access protected static variables only in static methods?
Thanks
If I understand correctly, what you are referring to is called late-static bindings. If you have this:
class A {
protected static $_foo = 'bar';
protected static function test() {
echo self::$_foo;
}
}
class B extends A {
protected static $_foo = 'baz';
}
B::test(); // outputs 'bar'
If you change the self bit to:
echo static::$_foo;
Then do:
B::test(); // outputs 'baz'
Because self refers to the class where $_foo was defined (A), while static references the class that called it at runtime (B).
And of course, yes you can access static protected members outside a static method (i.e.: object context), although visibility and scope still matters.
Static variables exist on the class, rather than on instances of the class. You can access them from non-static methods, invoking them something like:
self::$_someVar
The reason this works is that self is a reference to the current class, rather than to the current instance (like $this).
By way of demonstration:
<?
class A {
protected static $foo = "bar";
public function bar() {
echo self::$foo;
}
}
class B extends A { }
$a = new A();
$a->bar();
$b = new B();
$b->bar();
?>
Output is barbar. However, if you try to access it directly:
echo A::$foo;
Then PHP will properly complain at you for trying to access a protected member.

Accessing a protected member variable outside a class

I'm querying for the ID of a field by accessing a class function which someone has already put in place. The result is a object returned with protected member variables. I'm struggling to see how I can access the member variable values outside the class.
Accessing protected or private variables from public is incorrect (thats why they are protected or private). So better is to extend class and access required property or make getter method to get it publicaly. But if you still want to get properties without extending and if you are using PHP 5, you can acces with Reflection classes. Actually try ReflectionProperty class.
class Foo { protected $bar; }
$foo = new Foo();
$rp = new ReflectionProperty('Foo', 'bar');
$rp->setAccessible(true);
echo $rp->getValue($foo);
Here is the correct answer:
We can use bind() or bindTo methods of Closure class to access private/protected data of some class, for example:
class MyClass {
protected $variable = 'I am protected variable!';
}
$closure = function() {
return $this->variable;
};
$result = Closure::bind($closure, new MyClass(), 'MyClass');
echo $result(); // I am protected variable!
Just add a "get" method to the class.
class Foo
{
protected $bar = 'Hello World!';
public function getBar()
{
return $this->bar;
}
}
$baz = new Foo();
echo $baz->getBar();
I'm struggling to see how I can access the member variable values outside the class.
You can't: That's the whole point of protected.
You would have to extend the class with a method that fetches the variables for you.
You can't do this on an instantiated object, though - you would have to influence either the class definition, or change the class of the object at the point it was created.
You can access the protected member of class out side the class, also without extending protected member class, also without using any function of protected member class. Use below function to access it.
function getProtectedMember($class_object,$protected_member) {
$array = (array)$class_object; //Object typecast into (associative) array
$prefix = chr(0).’*’.chr(0); //Prefix which is prefixed to protected member
return $array[$prefix.$protected_member];
}
Please visit the Link to check more details about it.
with closure acces php protected variable for example
class ForExample
{
protected $var=122;
}
$call=function(){
echo $this->var;
};
$call->call(new ForExample());
If you really need that value:
Modify the class and add a public method that returns the value you want.
If you can't modify it, consider extending it and exposing the value there (it will be accessible, since it's protected). Prefer the first option, this is more of a hack.
Clearly, the class designer did not think you'd need the value you're trying to access, otherwise he would have added a method to retrieve it himself. Therefore, reconsider what you're doing.
DISCLAIMER: I don't remember how to code. It's been "a while". This may be completely off.
Well, first of all, if the members are protected, the original designer didn't intend for you to access them directly. Did you check for accessor methods?
If there aren't any, and you're conviced you really need these protected members, you could extend the type with accessors, cast, and get them that way. Like (in C++-like code)
class MyClass : public OldClass
{
public:
int getSomeValue() { return protectedValue; }
void setSomeValue(int value) { protectedValue=value; }
char* getOtherValue() { return otherProtectedValue; }
}
and then to use it
MyClass* blah = (MyClass*)TheirFactory->GiveMeAClass();
int yay=blah->getSomeValue();
You get the drift. Hope this works for you, Internet Explorer makes for a lousy compiler, so I haven't been able to test it.
}

How to access a private member inside a static function in PHP

I have the following class in PHP
class MyClass
{
// How to declare MyMember here? It needs to be private
public static function MyFunction()
{
// How to access MyMember here?
}
}
I am totally confused about which syntax to use
$MyMember = 0; and echo $MyMember
or
private $MyMember = 0; and echo $MyMember
or
$this->MyMember = 0; and echo $this->MyMember
Can someone tell me how to do it?
I am kind of not strong in OOPS.
Can you do it in the first place?
If not, how should I declare the member so that I can access it inside static functions?
class MyClass
{
private static $MyMember = 99;
public static function MyFunction()
{
echo self::$MyMember;
}
}
MyClass::MyFunction();
see Visibility and Scope Resolution Operator (::) in the oop5 chapter of the php manual.
This is a super late response but it may help someone..
class MyClass
{
private $MyMember;
public static function MyFunction($class)
{
$class->MyMember = 0;
}
}
That works. You can access the private member that way, but if you had $class you should just make MyFunction a method of the class, as you would just call $class->MyFunction(). However you could have a static array that each instance is added to in the class constructor which this static function could access and iterate through, updating all the instances. ie..
class MyClass
{
private $MyMember;
private static $MyClasses;
public function __construct()
{
MyClass::$MyClasses[] = $this;
}
public static function MyFunction()
{
foreach(MyClass::$MyClasses as $class)
{
$class->MyMember = 0;
}
}
}
Within static methods, you can't call variable using $this because static methods are called outside an "instance context".
It is clearly stated in the PHP doc.
<?php
class MyClass
{
// A)
// private $MyMember = 0;
// B)
private static $MyMember = 0;
public static function MyFunction()
{
// using A) // Fatal error: Access to undeclared static property:
// MyClass::$MyMember
// echo MyClass::$MyMember;
// using A) // Fatal error: Using $this when not in object context
// echo $this->MyMember;
// using A) or B)
// echo $MyMember; // local scope
// correct, B)
echo MyClass::$MyMember;
}
}
$m = new MyClass;
echo $m->MyFunction();
// or better ...
MyClass::MyFunction();
?>
Static or non-static?
Did you ever asked yourself this question?
You can not access non static parameters / methods from inside
static method (at least not without using dependency injection)
You can however access static properties and methods from with in non-static method (with self::)
Properties
Does particular property value is assign to class blueprint or rather to it instance (created object from a class)?
If the value is not tight to class instance (class object) then you could declare it as as static property.
private static $objectCreatedCount; // this property is assign to class blueprint
private $objectId; // this property is assign explicitly to class instance
Methods
When deciding on making a method static or non-static you need to ask yourself a simple question. Does this method need to use $this? If it does, then it should not be declared as static.
And just because you don't need the $this keyword does not
automatically mean that you should make something static (though the
opposite is true: if you need $this, make it non-static).
Are you calling this method on one individual object or on the class in general? If you not sure which one to use because both are appropriate for particular use case, then always use non-static. It will give you more flexibility in future.
Good practice is to always start to design your class as non-static and force static if particular us case become very clear.
You could try to declare your parameters as static... just so you can access it from static method but that usually is not what you want to do.
So if you really need to access $this from static method then it means that you need to rethink/redesign your class architecture because you have don it wrong.

Categories