How to access Private properties in php or even can i? - php

I have a simple example of code in which i would like to set the private property $ttlBal.
<$php
$balance = new Customer;
$greeting = fopen("greeting.txt", "r");
while(!feof($greeting)){
echo fgets($greeting) . "<br>";
}
fclose($greeting);
$balance->acctBal = 12;
$balance->deposits = 12;
$balance->fdr = 12;
$balance->findAvail($balance->acctBal, $balance->deposits, $balance->ttlBal);
class Customer{
public $acctBal;
public $deposits;
private $acctAvail;
private $ttlBal;
public $fdr;
public function findAvail($bal, $dep, $ttlBal){
echo $this->ttlBal = $bal - $dep;
}
}
?>
This brings about an error that I cannot access the private property $ttlBal. In which way can I access this.

You should add a public setter method to your class:
class Foo {
private $var;
public function setVar($value) {
$this->var = $value;
}
}
Also in many cases protected is what you want if you use private. If you just want to hide the variable from public access, use protected.

Youe error is here $balance->ttlBal
Either you will make the property public or you would implement get() and set() methods for it in Customer class.
As an example
public function get_ttlBal()
{
return $this->ttlBal;
}
and then you can call
$balance->findAvail($balance->acctBal, $balance->deposits, $balance->get_ttlBal());

To access private properties, previously set by setter function, you should write and use getter method.
public function getVar() {
return $this->_var;
}

Related

Can't access construct variable in method ( php laravel )

I have a base class which sets up's other extending controllers like this:
class BaseController extends Controller
{
public $globalCurrencies;
public $globalLanguages;
public function __construct()
{
$this->globalCurrencies = $this->getCurrencies(); // this works
$this->globalLanguages = $this->getLanguages(); // this works
}
}
And I use one of helpers to extend this class like this:
class SessionHelper extends BaseController
{
public $test;
public function __construct()
{
parent::__construct(); // fire parent aka basecontroller construct
$this->test = $this->globalCurrencies; // this works (variables are set)
echo '__construct: '.$this->test; // this even displays it
}
public function getCurrencies()
{
dd('method'.$this->test); // NOT WORKING
}
public function getCurrentCurrency()
{
return $this->getCurrencies()->where('id', Session::get('currencyId'))->first() ?? null;
}
}
Later on code is used in model:
class Product extends Model
{
protected $table = "products";
public $timestamps = true;
public $sessionHelper;
public function __construct()
{
$this->sessionHelper = new SessionHelper;
}
public function getPrice($conversion_rate = null)
{
return number_format($this->price_retail / $this->sessionHelper->getCurrentCurrency()->conversion_rate, 2);
}
}
Have any body idea why I can access in construct variable but not in method? If i remember correctly construct is fired first so everything after should have access to it.
Declare $test variable as private out side the constructor. Inside the constructor keep it the way you are doing it right now and then make a setter and getter for the test variable.
class testObject
{
private $test;
function __construct($test)
{
$this->test= $this->globalCurrencies;
}
// test getter
function getTest()
{
return $this->test;
}
}
Change your method to be;
public function getCurrencies()
{
dd('method', $this->test);
}
You can not concatenate strings and objects/arrays.
If that doesn't resolve the issue - check the laravel.log

creating static instance of a class

I'm rather new in PHP and it turns out that I'm not able to find a solution for the following problem:
I have a simple class like this:
class User{
private $name;
function __construct($name){
$this->name = $name;
}
}
All I want to do is to define a static instance of it, like one of these:
public const UNKNOWN_USER = new User("unknown);
so that I can use this as a dummy everywhere, e.g.:
public static login($name){
if( /* userdoesnotexist */ ){
return UNKNOWN_USER;
}
}
and check for it - of course:
if( login($name) == UNKNOWN_USER){
/* I don't know you! */
}
I've tried the following:
$UNKNOWN_USER = new User("unknown");
/* $UNKNOWN_USER not available in class-methods */
define(UNKNOWN_USER, new User("unknown"));
/* not allowed */
class User{
const UNKNOWN_USER = new User("unknown");
/* "new" leads to a syntax error */
}
For constants only scalar values are allowed (float, int, string, bool, NULL). But you can set your UNKNOWN-insatnce to a static class variable
class User{
public static $unknown_user = NULL;
...
}
User::$unknown_user = new User("unknown");
and then user User::$unknown_user instead of UNKNOWN_USER.
You cannot use const for anything else then scalar types. That excludes any objects. What you are trying to achive here is to make an object immutable. You can do this in many ways though they are nither simple nor straightforward. Take a look at the Builder pattern for instance. Another way would be to make the object lockable. But all of the safe methods to achieve this require some coding on your part.
The simplest lockable pattern for your example, that I can think of:
class User{
private $name;
private $is_locked = false;
function __construct($name){
$this->setName($name);
}
public function lock() {
$this->is_locked = true;
}
public function getName() {
return $this->name;
}
public function setName($name) {
if ( $this->is_locked ) {
throw new Exception("The object is locked");
}
$this->name = $name;
}
}
Now you can do:
$user1 = new User("John");
$user1->setName("Johnny");
but after you lock the object, you can't manipulate it anymore:
$user1->lock();
$user1->setName("Big John"); // Exception thrown
You can do that like this:
<?php
//Normal UnknownUser singleton pattern
class UnknownUser {
private static $instance;
//define properties
public $myproperty = "hiho123";
private function __construct() {
}
public static function getInstance() {
if(empty($instance)) {
self::instance = new UnknownUser();
}
return self::instance;
}
//Make the class constant
function __set($name, $value) {
throw new Exception("Can't set property: " . __CLASS__ . "->$name");
}
}
You can call the UnknownUser, like this:
$unknownUser = UnknownUser::getInstance();
And this make this class global and constant, can not be modified, because the magic method __set is activated to disable editing the properties.

PHP member data lost when abstract method returns

Here's an example of an abstract class and a derived class. There is one abstract method, "collectData" in class A, that is implemented in class B. When the method "getData" is called, "collectData" is then called, setting values in the private member variable "$data". Afterward, getData returns the contents of this variable. If you run this, you would expect the return value to be array(1, 2, 3). But it is an empty array. Why? I'm using PHP 5.3.10 by the way.
<?php
abstract class A
{
private $data;
public function __construct()
{
$this->data = array();
}
abstract protected function collectData();
public function getData()
{
$this->collectData();
return $this->data;
}
}
class B extends A
{
protected function collectData()
{
$this->data = array(1, 2, 3);
}
}
$test = new B();
$data = $test->getData();
print_r($data);
It should not be:
private $data;
but:
protected $data;
Private properties are not visible after derivation.
Make the $data property public or protected and You will see...
If the property is private, print_r does not see it... Or call var_dump($data) - this should print out also the private members...
Put a setter and a getter in your abstract class to manage the data property
public function setData($data){
$this->data = $data;
}
public function getData($data){
return $this->data;
}

How do I use objects and access their methods while within an object in PHP?

How do I use an object (along with its methods and properties) when I'm inside an object?
Say I have useless classes like these:
class Fruit {
private $name; // Name of the fruit.
private $health = 10; // 0 is eaten, 10 is uneaten.
private $object; // This is a PHP object.
public function __construct($name) {
$this->name = $name;
}
public function set($varname,$value) {
$this->$varname = $value;
}
}
class Eater {
private $name;
public function eat($object) {
$object->set('health',0); // I know I can pass and modify objects like this.
// The object is passed by reference in PHP5 (but not 4), right?
}
}
And I use it as such:
<?php
$pear = new Fruit("Pear");
$apple = new Fruit("Apple");
$paul = new Eater("Paul");
$paul->eat($apple);
?>
But if I modify the Eater class like so:
class Eater {
private $name;
private $objectToEat; // Let's say if I need the object to be over here instead of in a method.
public function set($varname,$value) {
$this->$varname = $value;
}
public function eat() {
$this->objectToEat->set('health',0); // This doesn't work!
}
}
And set the main program like so:
<?php
$pear = new Fruit("Pear");
$apple = new Fruit("Apple");
$paul = new Eater("Paul");
$paul->set('objectToEat',$apple);
$paul->eat();
?>
How can I access the object's properties from inside a method? I know I use $this->objectToEat to tell PHP I'm talking about the class properity, but since that property is an object, how do I access the object's methods?
I've tried $this->objectToEat->set('health',0) but that doesn't work. I hope you guys understand what I'm trying to get at (sorry, I can't figure out how to condense my question without compromising clarity)!
You have to set the property correctly. Since it's private, you can't do this from outside the object, so you have to use encapsulation:
class Eaters {
private $name;
private $objectToEat;
public function eat() {
$this->objectToEat->set('health',0); // Assumed "object" was just a typo
}
public function setObjectToEat($object) {
$this->objectToEat = $object;
}
}
Then use it like so:
<?php
$pear = new Fruit("Pear");
$apple = new Fruit("Apple");
$paul = new Eater("Paul");
$paul->setObjectToEat($apple);
$paul->eat();
?>
Note: In this brief example, your original method is a better design. In certain cases, you might want to prime the method to be used by setting properties beforehand, but more often you want to call it with parameters directly, since it's more clear and more reusable (compartmentalized).
This answer modifies Renesis' answer
In the class, the object to eat is a private variable hence you can't go
$paul->objectToEat = $apple;
What you can do is to make a setter method inside Eaters
class Eaters {
private $name;
private $objectToEat;
public function eat() {
$this->objectToEat->set('health',0); // Assumed "object" was just a typo
}
public function setFood($object) {
$this->objectToEat = $object;
}
}
Therefore, you can call the setFood() method instead.
OR
Change eat() to
public function eat($object) {
$this->object->set('health',0);
return $object;
}
Saving the modified object back to the original variable.
OR
class Eaters {
private $name;
public function eat(&$object) { // this passes object by reference
$object->set('health', 0);
}
}
Although this code is not tested, that is how you can pass a variable by reference.
NOTE: You only need the & when defining the method not when you're passing an argument. For more info about Passing by Reference go to this link
It's probably because your eat method isn't accepting any parameters, and the Eaters class has no $object property.
Can you make $objectToEat a reference and then use it as such in the eat() function?
you have to set $this->object in class Eaters
function __construct($object){
$this->object = $object;
}
or
<?php
$pear = new Fruit("Pear");
$apple = new Fruit("Apple");
$paul = new Eater("Paul");
$paul->eat($apple);
?>
class Tester {
private $variable;
private $anObj;
public function testFn($val) {
$this->variable = $val;
$this->anObj = new SecondObj();
$this->doSomething();
}
public function doSomething() {
echo("My variable is set to " . $this->variable);
$this->anObj->wow();
}
}
class SecondObj {
public function __construct() {
echo("I'm new!");
}
public function wow() { echo("Wow!"); }
}
$tester = new Tester();
$tester->testFn(42);
Output:
I'm new!My variable is set to 42Wow!

Object properties

Is the only way to assign $systime a value of a built-in-functions, is through a method?
class Test{
private $systime;
public function get_systime(){
$this->systime = time();
}
}
Right off i would think something like this right?:
class Test{
private $systime = time();
public function get_systime(){
echo $this->systime;
}
}
Thanks
You should be able to use a constructor to assign the value, for example:
class Test {
private $systime;
function __construct() {
$this->systime = time();
}
public function get_systime(){
echo $this->systime;
}
}
$t = new Test();
$t->get_systime();
For more information on __construct() see the php manual section on object oriented php.
From http://www.php.net/manual/en/language.oop5.basic.php (Just before Example 3)
The default value must be a constant
expression, not (for example) a
variable, a class member or a function
call.
However, you can also assign a value from the constructor:
class Test{
private $systime;
public function __construct(){
$this->systime = time();
}
public function get_systime(){
echo $this->systime;
}
}

Categories