The right way to set object properties - php

I know the question is kinda controversial, but anyway:
Let's say I have a simple class:
class A {
private $a;
private $b;
function __construct($data = array()){
if($data) $this->setAll($data);
}
function setAll($array){
foreach ($array as $key => $value){
if ( property_exists ( $this , $key ) ){
$this->{$key} = $value;
}
}
return $this;
}
function setAllByFunctions($array){
foreach ($array as $key => $value){
$method_name = "set".$key;
if ( method_exists ( $this , $method_name) ){
$this->$method_name($value);
}
}
}
function setA($value){
$this->a = $value;
return $this;
}
function setB($value){
$this->b = $value;
return $this;
}
}
What is the best way to set the object properties considering the real class can have much more properties? What are the pros and cons? Is there any article I could read about that? I wasn't able to google anything useful.
1)
$a1 = new A();
$val = Array("A" => "value of a", "B" => "value of b");
$a1->setAll($val);
2)
$a2 = new A();
$a2->setA("value of a")->setB("value of b");
3)
$val = Array("A" => "value of a", "B" => "value of b");
$a3 = new A($val);
4)
$a4 = new A($val);
$val = Array("A" => "value of a", "B" => "value of b");
$a1->setAllByFunctions($val);

Related

PHP: Set object properties inside a foreach loop

Is it possible to set property values of an object using a foreach loop?
I mean something equivalent to:
foreach($array as $key=>$value) {
$array[$key] = get_new_value();
}
EDIT: My example code did nothing, as #YonatanNir and #gandra404 pointed out, so I changed it a little bit so it reflects what I meant
You can loop on an array containing properties names and values to set.
For instance, an object which has properties "$var1", "$var2", and "$var3", you can set them this way :
$propertiesToSet = array("var1" => "test value 1",
"var2" => "test value 2",
"var3" => "test value 3");
$myObject = new MyClass();
foreach($propertiesToSet as $property => $value) {
// same as $myObject->var1 = "test value 1";
$myObject->$property = $value;
}
Would this example help at all?
$object = new stdClass;
$object->prop1 = 1;
$object->prop2 = 2;
foreach ($object as $prop=>$value) {
$object->$prop = $object->$prop +1;
}
print_r($object);
This should output:
stdClass Object
(
[prop1] => 2
[prop2] => 3
)
Also, you can do
$object = new stdClass;
$object->prop1 = 1;
$object->prop2 = 2;
foreach ($object as $prop=>&$value) {
$value = $value + 1;
}
print_r($object);
You can implement Iterator interface and loop through the array of objects:
foreach ($objects as $object) {
$object->your_property = get_new_value();
}
Hacked away at this for a few hours and this is what i finally used. Note the parameters passed by reference in two places. One when you enter the method and the other in the foreach loop.
private function encryptIdsFromData(&$data){
if($data == null)
return;
foreach($data as &$item){
if(isset($item["id"]))
$item["id"] = $this->encrypt($item["id"]);
if(is_array($item))
$this->encryptIdsFromData($item);
}
}

php read mongodb.findone() returned json values and create object

I have an employee class and i want to initialize the employee object from mongodb.findone() returned array.
foreach($res as $key => $value){
echo $value; // here values printed
}
but i need to do something like( if key = 'first_name' then employee_obj->set_first_name($value), if key = 'last_name' then employee_obj->set_last_name($value)... ) can you help me?
$employee = new Employee;
foreach($res as $key => $value){
if (property_exists($employee, $key)) {
$employee->$key = $value;
}
}
$employee->$key = $value is dynamically assigning $key property to the employee. Example:
$key = "name";
$employee->$key = "John Doe";
echo $employee->name; // John Doe
If you want to do this with private or protected properties you need to do the assignment within the class or instance:
class Employee {
// ...
private $name;
// lets you assign properties by passing in an array
public function __construct($arr = array()){
if count($arr) {
foreach($arr as $key => $value){
if (property_exists($this, $key)) {
$this->$key = $value;
}
}
}
}
}
$joe = new Employee(array('name' => 'Joe'));
echo $joe->name // Joe
$e = new Employee;
foreach($res as $k => $v){
if($k == 'first_name'){
$e->set_first_name($v);
}elseif($k == 'last_name'){
$e->set_last_name($v);
}else{
$e->$k = $v;
}
}
Does exactly that.

print dynamicly set proprites in object

how to print dynamical add properties in bellow class?
class Car {
function __construct() {
}
function setInfo($car_arr) {
foreach ($car_arr as $key => $value) {
$this->{$key} = $value;
}
}
}
set class object like bellow
$car1 = new Car();
$car1->setInfo(array('make' => 'Toyota', 'model' => 'scp10'));
$car2 = new Car();
$car2->setInfo(array('anme1' => 'value1', 'anme2' => 'value2'));
now I want to to print car object bellow
make = Toyota
model = scp10
Try :
$car1 = new Car();
$car1->setInfo(array('make' => 'Toyota', 'model' => 'scp10'));
echo $car1->make;
echo $car1->model;
<?php
class Car {
function __construct() {
}
function setInfo($car_arr) {
foreach ($car_arr as $key => $value) {
$this->{$key} = $value;
}
}
}
$car1 = new Car();
$car1->setInfo(array('make' => 'Toyota', 'model' => 'scp10'));
echo "Make value is : " . $car1->make. ", Model value is : ". $car1->model;
?>
above code output Make value is : Toyota, Model value is : scp10
Please consider storing the properties explicitly like I pointed out in this answer:
<?php
class Car {
private $data = array();
function setInfo(array $carInfo) {
foreach ($carInfo as $k => $v) {
$this->data[$k] = $v;
}
return $this;
}
function __set($key, $val) {
$this->data[$key] = $val;
}
function __get($key) {
return $this->data[$key];
}
}
$car = new Car();
$car->setInfo(array('make' => 'Toyota', 'warranty' => '5 years'));
I'd consider it more "clean", but that's probably debatable.
I think you look for something like this PHP Magic Methods
For example this one:
<?php
class A
{
public $var1;
public $var2;
public static function __set_state($an_array) // As of PHP 5.1.0
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return $obj;
}
}
$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array(
// 'var1' => 5,
// 'var2' => 'foo',
// ));
var_dump($b);
?>
This will be helpful too.
You can fetch all properties using get_object_vars():
$vars = get_object_vars($car1);
foreach ($vars as $key => $value) {
echo $key . ' = ' . $value . '<br />';
}

Echo a value from an array based on function parameters

I need to be able to echo a value from a private property in one of my classes if a method is called within the class. It's a little tricky to explain so let me demostrate and hopefully someone can fill in the blank for me :)
<?php
class test {
private $array['teachers']['classes'][23] = "John";
public function __construct($required_array) {
$this->array['teachers']['classes'][23] = "John";
$this->array['students'][444] = "Mary";
$this->echo_array($required_array);
}
public function echo_array($array) {
// Echo the value from the private $this->array;
// remembering that the array I pass can have either
// 1 - 1000 possible array values which needs to be
// appended to the search.
}
}
// Getting the teacher:
$test = new test(array('teachers','classes',23));
// Getting the student:
$test = new test(array('students',444));
?>
Is this possible?
$tmp = $this->array;
foreach ($array as $key) {
$tmp = $tmp[$key];
}
// $tmp === 'John'
return $tmp; // never echo values but only return them
An other approach to get value;
class Foo {
private $error = false,
$stack = array(
'teachers' => array(
'classes' => array(
23 => 'John',
24 => 'Jack',
)
)
);
public function getValue() {
$query = func_get_args();
$stack = $this->stack;
$result = null;
foreach ($query as $i) {
if (!isset($stack[$i])) {
$result = null;
break;
}
$stack = $stack[$i];
$result = $stack;
}
if (null !== $result) {
return $result;
}
// Optional
// trigger_error("$teacher -> $class -> $number not found `test` class", E_USER_NOTICE);
// or
$this->error = true;
}
public function isError() {
return $this->error;
}
}
$foo = new Foo();
$val = $foo->getValue('teachers', 'classes', 24); // Jack
// $val = $foo->getValue('teachers', 'classes'); // array: John, Jack
// $val = $foo->getValue('teachers', 'classes', 25); // error
if (!$foo->isError()) {
print_r($val);
} else {
print 'Value not found!';
}

Iterate through an object's properties and modify the original object

I have this simple issue. In this simple script:
<?php
class MyClass {
public var1 = '1';
public var2 = '';
public var3 = '3';
}
$class = new MyClass;
foreach ($class as $key => $value) {
echo $key . ' => ' . $value . '<br />';
}
?>
The result would be:
var1 => 1
var2 =>
var3 => 3
If I want to iterate through all those properties so I can find out which one is empty, how can I assign a value to that empty property in the object?
foreach ($class as $key => $value) {
if (empty($value)) {
$value = 'something';
}
}
... is not working because I guess that PHP thinks that $value is an actual variable, not a reference.
Try this:
foreach ($class as $key => $value) {
if (empty($value)) {
$value = 'something';
$class->$key = $value;
}
}

Categories