"Private" not not really private? - php

class Test
{
private $private = "";
public function add($string) {
$this->private[] = $string;
}
public function evaluate(Test $container) {
return $container->private;
}
}
$test = new Test();
$test->add("zero");
$test->add("one");
$test->add("two");
$result = new Test();
print_r($result->evaluate($test));
The above code demonstrates the dump of a private string, how is this possible?
Then, why is it called "private"?
Can anyone explain this to me?
Output:
Array (
[0] => one
[1] => two
[2] => four
)

Because you are calling that private property from inside the class. private means it can only be used by properties and methods inside it's own class. You call a method, which is allowed to use that property. Private properties are accessible by it's class, even if it's a different instance of the class.
You'll find the following:
print_r($result::$private);
Will give you the error:
Fatal error: Cannot access private property

private in PHP means private to any object of the same type.
As stated here in the PHP manual:
Objects of the same type will have access to each others private and protected members even though they are not the same instances.
Yes, it is different to some other languages, but it is documented, and this is the way it works.

This is because even though the attribute $private is private, the class Test still knows about it and can access it, even though it's a different instance. If you were to create a second class Test2() with the same evaluate method which expects a Test instance then the evaluate will fail. This is a bit tricky, but the class Test knows all about its members even from remote instances.

public function evaluate is public and it can access private variable inside the class. you can't direct access the public variable like $result->$private

is private because you can't access this variable/member out of class.

Related

PHP - when to use private static properties in the class

I am learning php and there are still alot of unclear areas for me in the language. I wonder when and why would we use private static properties inside the class. From what I understood private properties may only be accessed by the class where it was defined. So, the private part is clear, but the static is still unclear. In the docs it says:
Declaring class properties or methods as static makes them accessible
without needing an instantiation of the class. A property declared as
static cannot be accessed with an instantiated class object (though a
static method can).
Does that mean that I can access static properties without instantiation of the class. So, for example:
class Foo{
static $bar;
public function __construct($bar){
$this->bar = $bar;
}
So, I can access the $bar property of the class like so?
Foo::$bar
But, if I do this, it wouldn't work?
$foo = new Foo();
$foo::$bar
And, then if do make a property private static for which reason would we do that, since I thought we make them static in order to access them outside of their class and making them private would make that impossible. I would be very grateful if someone could clear this up to me.
When you declare a normal property, there is a different value of that property for every instance you create of that class (each object you create with new Foo). For a static property, there is one copy of that variable for the whole class.
This is separate from the visibility of that variable - a public static property exists once per class, and can be accessed from everywhere; a private static property exists once per class, but can only be accessed from inside that class's definition.
As a simple example, you could have a counter that gave each instance of the class a unique number. You don't need code outside the class to see or change this counter, so you mark it private, but it needs to be shared amongst all instances, so you mark it static.
class Foo {
// Static counter; shared with every instance
private static $nextID=0;
// Normal instance property: each instance will have its own value
private $myID;
public function __construct() {
// Set the ID for this instance to the next ID
$this->myID = self::$nextID;
// Increment the shared counter
self::$nextID++;
}
}
Static context within a PHP class (but outside of a function) is context which exists statically, that is without the need for a backing instance of an object.
Example:
class A {
public $a = 1;
public static $b = 2;
public function instanceFunction() {
A::$a; //Wrong way
$this->a //Right way
A::$b; //Works
self::$b; // Also works
static::$b; // Also also works
}
public static function staticFunction() {
A::$a; //Does not work
$this->a //Error $this within static context
A::$b; //Works
self::$b; // Also works
static::$b; // Also also works
}
}
A::$a; // Error $a is not static so it needs an instance of an object
A::$b; // Works
$Aobject=new A();
$Aobject->a; //Works
$Aobject->b // Does not work
Using self means "refer to the class I've written this in" e.g. in this case it's always A. Using static means "refer to the class I've called this from" which applies if static inheritance is involved which PHP does manage to pull off.

How can protected property of a class be visible from a static method in PHP?

I understand OOP. What I understand so far is that private and protected cannot be referenced from outside the class using $this->blah notation. If that is correct, how can the following code work?
<?php
class test {
protected $a = "b";
public static function oo(){
$instance = new static();
echo $instance->a;
}
}
test::oo();
Gives me an output of b! Now, how in Lord's name can that happen?
In PHP 5.3, a new feature called late static bindings was added – and this can help us get the polymorphic behavior that may be preferable in this situation. In simplest terms, late static bindings means that a call to a static function that is inherited will “bind” to the calling class at runtime. So, if we use late static binding it would mean that when we make a call to “test::oo();”, then the oo() function in the test class will be called.after that you return $instance->a; static keyword allows the function to bind to the calling class at runtime.so if you use static then whatever access modifier(private,public,protected) you use it's just meaning less...
please read this link,another
That happens because you're "presenting it" by echo'ing it. You can't reference it like this for example:
class test {
private $a = 'b';
function __construct() {
echo 'instantiated';
}
}
$test = new test();
echo $test->a; // This line won't work, since it's a private var.
It would give you an error message that looks like this:
Fatal error: Cannot access private property test::$a
Example (https://eval.in/226435)
As I said before, you're accessing it from within the class itself, so you CAN view it. (That's the $instance you have there.) If you modify your code to use it like this:
class test {
protected $a = "b";
public static function oo(){
$instance = new static();
return $instance;
}
}
echo test::oo()->a;
Example of the above (https://eval.in/226439)
You'll get that "private acess blah blah" error.
You're understanding the statement wrong. "private and protected cannot be referenced from outside the class" means that as the examples above show, you CAN NOT access the variables outside the class, but with your example, you're accessing it from INSIDE the class, which means they'll do as you require (echo'ing out as you did)
What I understand so far is that private and protected cannot be referenced from outside the class
As follows, since oo is defined in the same type as a, oo has access to a.
This is actually a very good question, and shouldn't be down-voted.
From what I understand, the reason why you can access a protected/private property from within a static method of the same class, is because "the implementation specific details are already known when inside this class". I rephrased this a little from what is documented on the official page on Visibility:
Objects of the same type will have access to each others private and protected members even though they are not the same instances. This is because the implementation specific details are already known when inside those objects.
This makes sense. Visibility access is meant to only expose things that are safe for the public to use. But if you already have access to the code of the Class you're using, then there is no point of preventing you to use what you already see. Hope that makes sense..

PHP static initializer

I'd like to access a static field of a class in a static function, but the field is still <Uninitialized>. How can I initialize this field?
<?php
final class StaticTest {
private static $lookup = array(123, 456, 789);
public static function compute() {
return StaticTest::$lookup[0];
}
}
echo 'result: ' . StaticTest::compute();
?>
As you can see in the following picture taken from the Eclipse PDT debugging the static field $lookup is <Unitialized>.
The error is happening because you are trying to call a private variable while not calling self to access it.
I have given the below code a test and it seems to work. Oddly, I have also given your code a test, and that seems to work fine also.
To get around this, in your compute function, you should use this return self::$lookup[0]; instead of return StaticTest::$lookup[0];.
Another way around this would be to change the private static $lookup = array(123, 456, 789); to public static $lookup = array(123, 456, 789);. Doing this, your code would work fine, but is not the recommended way.
Doing this, it should return the result you want. Think of it similar to non static classes, to access parameters (private or public) inside of a non-static class you can use $this->, where as in a static class, you should use self:: instead. Also, not that using self:: to access a variable requires the $ to be present, where as using $this-> does not.
The answer provided by Dejv would also work, but involves using a singleton type class, which is definitely not needed for this procedure as it is instancing a new class each time, completely ignoring how static variables and functions can work.
Hope this answers your question.
Edit your code to this and it should work as you desire:
<?php
final class StaticTest{
protected static $instance;
private $lookup = array(123, 456, 789);
public function compute() {
return $this->lookup[0];
}
public static function get(){
if (!isset(self::$instance))
self::$instance = new self();
return self::$instance;
}
}
echo 'result: ' . StaticTest::get()->compute();
To explain myself here, it's always better to use the concept where you only specify that you want to use the property of object and don't care about creating the object.
It is done automatically (it object doesn't exist in memory it is created, if it exists it is called).
I can't really explain this better. I'm no braniac. I only use this concept as a substitution for application global variables.
Hope it helps!

Method accessing protected property of another object of the same class

Should an object's method be able to access a protected property of another object of the same class?
I'm coding in PHP, and I just discovered that an object's protected property is allowed to be accessed by a method of the same class even if not of the same object.
In the example, at first, you'll get "3" in the output - as function readOtherUser will have successfully accessed the value -, and after that a PHP fatal error will occur - as the main program will have failed accessing the same value.
<?php
class user
{
protected $property = 3;
public function readOtherUser ()
{
$otherUser = new user ();
print $otherUser->property;
}
}
$user = new user ();
$user->readOtherUser ();
print $user->property;
?>
Is this a PHP bug or is it the intended behaviour (and I'll have to relearn this concept… :)) (and are there references to the fact)? How is it done in other programming languages?
Thanks!
This is intended. It's even possible to access the private members of the same class. So think of the modifiers to be class wise modifiers, not objectwise modifiers.
PHP is not the only language that has this feature. Java for example has this too.
It's intended behavior. A protected variable or function means that it can be accessed by the same class or any class that inherits from that class. A protected method may only be called from within the class, e.g. you cannot call it like this:
$object = new MyClass();
$object->myProtectedFunction();
This will give you an error. However, from within the defined class 'MyClass', you can perfectly call the protected function.
Same applies for variabeles. Summarized:
use PROTECTED on variables and functions when:
1. outside-code SHOULD NOT access this property or function.
2. extending classes SHOULD inherit this property or function.

PHP Scope and Class Instance Interaction

It seems as though different instances of a class can know about each others' private member variables.
I have provided some code that attempts to showcase my issue, and I will try to explain it.
We have a class with a private member variable, $hidden. modifyPrivateMember sets the value of $hidden to 3. accessPrivateMember takes an Object as a parameter and accesses its private $hidden member to return its value.
Example code:
<?php
// example.php
class Object {
private $hidden;
public function modifyPrivateMember() {
$this->hidden = 3;
}
public function accessPrivateMember(Object $otherObject) {
return $otherObject->hidden;
}
}
$firstObject = new Object;
$firstObject->modifyPrivateMember();
$otherObject = new Object;
echo $otherObject->accessPrivateMember($firstObject);
Output of the above code:
$ php example.php
3
Can anyone explain why private members of objects are accessible to other instances of the same class? Is there some justification for this ostensible breach of scope?
private means it's restricted to only that class, not only that object.
That's just how php works. It's the same as how Java works. See http://php.net/manual/en/language.oop5.visibility.php for more info.
The only situation in which this behavior seemed useful was in a factory function:
class Object
{
private $state;
public static function makeObject()
{
$obj = new Object;
$obj->state = 'some state';
return $obj;
}
}
Even in this case, there are better solution and I agree with you that it is a breach of scope, although not that big in my opinion. After all, the one who writes the class decides if she needs to access private members from objects passed as arguments. So, it may seem useless (even to me), but you never know. It's not like you're exposing your internals to subclasses or something. It all happens in the same class and it's your business what you're doing in there.
By the way, one language that implements access modifiers per object and not per class is Ruby.

Categories