I'm having problems with an array inside a class. I can access it if I set it to static but I cannot figure out how to modify it and access it on my function if it's not static.
class Example {
protected static $_arr = array(
"count",
);
public static function run($tree) {
$_arr[] = "new";
print_r($_arr );
}
}
How do I access the array, modify it and print it from inside my public function "run"?
$_arr[] = "new";
refers to an array that will be local to your function. to access a static variable of your class, you have to use the syntax ==> self::staticVariableName
you code should be :
class Example {
protected static $_arr = array(
"count",
);
public static function run($tree) {
self::$_arr[] = "new";
print_r(self::$_arr );
}
I have just made a snippet from the code of #MQuirion . Here I wrote how to handle non-static properties in your class. I hope now you can work with your array inside your class.
class Example {
protected $_arr = array(
"count",
);
public function run($tree) {
// print new array + your properties
$this -> _arr[] = $tree;
//To print only new assigned values without your declared properties
$this -> _arr = $tree;
print_r($this->_arr );
}
}
$obj = new Example();
$tree = array('a','b','c');
$result = $obj->run($tree);
Related
how do you define a variable in a class? seems like global only works inside the function.
<?php
$a = '20';
$b = '10';
class test {
global $a; $b;
function add() {
echo $a;
}
}
$answer = new test();
$answer->add();
?php>
i tried this one (use global inside a class but gets error instead)
also, how can you define multiple variables in just 1 line of code instead of defining it each.
To define a class property (or variable), you would do like so:
class Foo {
private $myVar = 'my var'; // define a class property
public function add() {
echo $this->myVar;
}
}
How about passing the data in via the constructor?
Code: (Demo)
$a_outside = '20';
$b_outside = '10';
class test {
public $a_inside;
public $b_inside;
public function __construct($a_passed_in, $b_passed_in)
{
$this->a_inside = $a_passed_in;
$this->b_inside = $b_passed_in;
}
public function add()
{
echo $this->a_inside + $this->b_inside;
}
}
$answer = new test($a_outside, $b_outside);
$answer->add(); // output: 30
Pass the variable to the class via arguments in the constructor call.
Define the values as variables in the class within construct call.
Access the variables within the add() method.
After all, searching enough in SO I couldn't find out a most generic with best practice solution for PHP __constructor with multiple parameter into a class function
I am trying to define a function inside a PHP class. Where I will be using this function multiple times through a simple function call. Where the function will be having 2 or more parameters.
When I do a function call by passing the parameter, it's just NULL when it reaches the __constructor.
Why it's NULL?
Also, note that there are objects nested inside the function addFruitCheckBox.
What I am doing wrong?
I may also wanted to pass a function call instead of $this->addFruitCheckBoxItemName sometimes.
There are lot of specific problems and solutions in SO. However, I believe this generic question will help me and all, for passing mulitple parameter into __constructor function in a PHP class
ini_set('display_errors', 1);
$_GET['SELECTEDTABNAME'] = 'properties';
/* all include files that are involved in function call within a function will be declared here */
class AddFruitController
{
protected $addFruitCheckBoxItemName;
protected $addFruitCheckBoxLabel;
protected $addFruitMenuItemName;
protected $addFruitChoiceItemName;
protected $addFruitTimeItemName;
public $trustedFruits;
public $trustedFruitsModel;
public $trustedFruitsSpeed;
public $addNewFruit;
public $additionalTub;
public $chooseParent;
public $FruitDown;
public $FruitSell;
public $timeTitle;
public $addFruitbutton;
public function __construct($addFruitCheckBoxItemName, $addFruitCheckBoxLabel, $addFruitMenuItemName, $addFruitTimeItemName)
{
global $interpreterMan, $fetchSeedForSapling;
// var_dump($this->addFruitCheckBoxLabel);
// var_dump($this->addFruitCheckBoxItemName);
$this->trustedFruits = $interpreterMan("Trusted Fruits");
$this->trustedFruitsModel = $interpreterMan("Model");
$this->trustedFruitsSpeed = $interpreterMan("Speed");
$this->addNewFruit = $interpreterMan("New Fruit");
$this->additionalTub = $interpreterMan("Additional Options");
$this->chooseParent = $interpreterMan("Choose Parent");
$this->FruitDown = $interpreterMan("Download Schedule");
$this->FruitSell = $interpreterMan("Install Schedule");
$this->timeTitle = $interpreterMan("Time");
$this->addFruitbutton = $interpreterMan("Add Fruit(s)");
$this->addFruitCheckBoxItemName = $addFruitCheckBoxItemName;
$this->addFruitCheckBoxLabel = $addFruitCheckBoxLabel;
$this->addFruitMenuItemName = $addFruitMenuItemName;
$this->addFruitChoiceItemName = $addFruitChoiceItemName;
var_dump($addFruitChoiceItemName);
$this->addFruitTimeItemName = $addFruitTimeItemName;
}
public function addFruitMenu()
{
global $interpreterMan;
$theWidfetch = new FruitMenu();
$theWidfetch->AssignAddJsCode(false);
$theWidfetch->AssignChoiceOrder(array($interpreterMan("English")));
$theWidfetch->AssignChoiceText(array($interpreterMan("English") => $interpreterMan("English")));
$theWidfetch->AssignGroupHeader($this->addFruitMenuItemName);
$theWidfetch->AssignItemName($this->addFruitMenuItemName);
$theWidfetch->AssignSaveLocation($this->addFruitMenuItemName);
$theWidfetch->AssignValueToUse("ipad");
$theWidfetch->WaterPath(true, true);
}
public function addFruitChoiceTable()
{
global $fetchSeedForSapling, $interpreterMan;
$weekChoiceSelection = new FruitChoiceTable();
$weekChoiceSelection->AssignAddJsCode(false);
$weekChoiceSelection->AssignChoiceOrder(
array("sun", "mon", "tue", "wed", "thu", "fri", "sat"));
$weekChoiceSelection->AssignChoiceText(array(
"sun" => $interpreterMan("SUN"),
"mon" => $interpreterMan("MON"),
"tue" => $interpreterMan("TUE"),
"wed" => $interpreterMan("WED"),
"thu" => $interpreterMan("THU"),
"fri" => $interpreterMan("FRI"),
"sat" => $interpreterMan("SAT"),
));
var_dump($weekChoiceSelection->AssignGroupHeader($this->addFruitChoiceItemName));
$weekChoiceSelection->AssignItemName("Weekday");
$weekChoiceSelection->AssignNumColumns(7);
$weekChoiceSelection->AssignValueToUse($fetchSeedForSapling("dayOfWeek"));
$weekChoiceSelection->WaterPath(true, true);
}
public function addFruitTime()
{
global $fetchSeedForSapling;
$FruitTimeSelect = new FruitTime();
$FruitTimeSelect->AssignGroupHeader($addFruitTimeItemName);
$FruitTimeSelect->AssignItemName($addFruitTimeItemName);
$FruitTimeSelect->AssignValueToUse($fetchSeedForSapling("minuteOfDay"));
$FruitTimeSelect->WaterPath(true, true);
}
public function addFruitCheckBox()
{
global $fetchSeedForSapling;
$addFruitCheckBoxObj = new FruitCheckbox();
$addFruitCheckBoxObj->AssignAddJsCode(false);
$addFruitCheckBoxObj->AssignCheckboxLabel($this->addFruitCheckBoxLabel);
$addFruitCheckBoxObj->AssignItemName($this->addFruitCheckBoxItemName);
$addFruitCheckBoxObj->AssignSaveLocation("somejob");
$addFruitCheckBoxObj->AssignValueToUse($fetchSeedForSapling("somejob"));
$addFruitCheckBoxObj->WaterPath(true, true);
}
}
For creating such complex objects, I suggest you to use Builder Design Pattern instead of assigning properties dynamically and directly.
Note: For better, you can add a layer of interface which Builder classes will implement. And you can have multiple Builder classes which generate different complex objects as per different use cases. Hope this make sense.
Try this code snippet here
<?php
class Builder {
public static function getMyClass($a, $b, $c) {
$myClass = MyClass::getInstance();
$myClass->setA($a);
$myClass->setB($b);
return $myClass;
}
}
class MyClass {
protected $a=0;
protected $b=0;
public static function getInstance() {
$myClass = new MyClass();
return $myClass;
}
function setA($a) {
$this->a = $a;
}
function setB($b) {
$this->b = $b;
}
}
$myClass = Builder::getMyClass("a", "b", "c");
print_r($myClass);
Explanation: In the above mentioned code we have a Builder class which is responsible for building such complex objects.
But still if you are still more towards dynamic assignment approach which nobody recommends, you can see this post
http://php.net/manual/en/language.oop5.decon.php
class MyClass {
protected $a1;
protected $a2;
protected $a3;
public function __construct($a1, $a2, $a3) {
$this->a1 = $a1;
$this->a2 = $a2;
$this->a3 = $a3;
}
}
I'm having trouble declaring an array in conjunction to a function. Here is my code, what am I doing wrong?
private function array_list(){
return array('1'=>'one', '2'=>'two');
}
private $arrays= array(
'a'=>array('type'=>'1', 'list'=>$this->array_list())
);
Getting unexpected T_VARIABLE error when I run this code.
You cannot declare arrays like this as property:
private $arrays= array(
'a'=>array('type'=>'1', 'list'=>$this->array_list())
);
You cannot use an array returned from a class method in the property definition.
You should populate it inside a constructor for example. Like this:
private $arrays = array();
public function __construct() {
$this->arrays = array(
'a'=>array('type'=>'1', 'list'=>$this->array_list())
);
}
Do it in a method, for example, the constructor:
class Foo {
function __construct () {
$this->arrays['list'] = $this->array_list ();
}
}
I am trying to perform a backup/restore function for static properties of classes. I can get a list of all of the static properties and their values using the reflection objects getStaticProperties() method. This gets both private and public static properties and their values.
The problem is I do not seem to get the same result when trying to restore the properties with the reflection objects setStaticPropertyValue($key, $value) method. private and protected variables are not visible to this method as they are to getStaticProperties(). Seems inconsistent.
Is there any way to set a private/protected static property using reflection classes, or any other way for that matter?
TRIED
class Foo {
static public $test1 = 1;
static protected $test2 = 2;
public function test () {
echo self::$test1 . '<br>';
echo self::$test2 . '<br><br>';
}
public function change () {
self::$test1 = 3;
self::$test2 = 4;
}
}
$test = new foo();
$test->test();
// Backup
$test2 = new ReflectionObject($test);
$backup = $test2->getStaticProperties();
$test->change();
// Restore
foreach ($backup as $key => $value) {
$property = $test2->getProperty($key);
$property->setAccessible(true);
$test2->setStaticPropertyValue($key, $value);
}
$test->test();
For accessing private/protected properties of a class we may need to set the accessibility of that class first, using reflection. Try the following code:
$obj = new ClassName();
$refObject = new ReflectionObject( $obj );
$refProperty = $refObject->getProperty( 'property' );
$refProperty->setAccessible( true );
$refProperty->setValue(null, 'new value');
For accessing private/protected properties of a class, using reflection, without the need for a ReflectionObject instance:
For static properties:
<?php
$reflection = new \ReflectionProperty('ClassName', 'propertyName');
$reflection->setAccessible(true);
$reflection->setValue(null, 'new property value');
For non-static properties:
<?php
$instance = new SomeClassName();
$reflection = new \ReflectionProperty(get_class($instance), 'propertyName');
$reflection->setAccessible(true);
$reflection->setValue($instance, 'new property value');
You can implement also a class internal method to change the object properties access setting and then set value with $instanve->properyname = .....:
public function makeAllPropertiesPublic(): void
{
$refClass = new ReflectionClass(\get_class($this));
$props = $refClass->getProperties();
foreach ($props as $property) {
$property->setAccessible(true);
}
}
I'm trying to dump elements of an object's private property through an anonymous function - of course I could achieve this in any number of other ways, but this highlights a PHP conundrum I can't solve off the top of my head, short of $foo = $this and using $foo - but THAT won't give me the private stuff, so... suggestions ?
Sample code:
class MyClass
{
private $payload = Array( 'a' => 'A element', 'b' => 'B element');
static $csvOrder = Array('b','a');
public function toCSV(){
$values = array_map(
function($name) use ($this) { return $this->payload[$name]; },
self::$csvOrder
);
return implode(',',$values);
}
}
$mc = new MyClass();
print $mc->toCSV();
I believe there is absolutely no way to do directly what you propose.
However, you can work around it either by making the anonymous method a class method (this is not what you asked for, but it could be a practical solution) or pulling everything you need out of $this explicitly and passing the extracted values into the function:
class MyClass
{
private $payload = Array( 'a' => 'A element', 'b' => 'B element');
static $csvOrder = Array('b','a');
public function toCSV(){
$payload = $this->payload;
$values = array_map(
function($name) use ($payload) { return $payload[$name]; },
self::$csvOrder
);
return implode(',',$values);
}
}
You can hack around the limitation by creating a wrapper that utilizes Reflection to allow you to access all properties and methods. You can use it like this then:
$self = new FullAccessWrapper($this);
function () use ($self) { /* ... */ }
Here a sample implementation of the wrapper, taken from here:
class FullAccessWrapper
{
protected $_self;
protected $_refl;
public function __construct($self)
{
$this->_self = $self;
$this->_refl = new ReflectionObject($self);
}
public function __call($method, $args)
{
$mrefl = $this->_refl->getMethod($method);
$mrefl->setAccessible(true);
return $mrefl->invokeArgs($this->_self, $args);
}
public function __set($name, $value)
{
$prefl = $this->_refl->getProperty($name);
$prefl->setAccessible(true);
$prefl->setValue($this->_self, $value);
}
public function __get($name)
{
$prefl = $this->_refl->getProperty($name);
$prefl->setAccessible(true);
return $prefl->getValue($this->_self);
}
public function __isset($name)
{
$value = $this->__get($name);
return isset($value);
}
}
Obviously the above implementation doesn't cover all aspects (e.g. it can't use magic properties and methods).
As you said yourself, it is private and therefore in accessible.
You can:
Pass $this->payload as a parameter to the anonymous function.
Create a method in the class and use it instead.