PHP: Set object properties inside a foreach loop - php

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);
}
}

Related

store nested object chain in a variable

so lets say i have a object like this
{
"status": "AlreadyVerified"
}
and i want to store propert key in variable so i can access property using that variable like
$key = 'status';
echo $object->$key
but what if i have a nested object like
{
"extra_info": {#305 ▼
+"status": "AlreadyVerified"
}
}
this wouldn't work
$key = 'extra_info->status';
echo $object->$key
how can i store nested object chain in a variable so i can access its property using that variable ?
preferably some way that works for both nested and flat objects (i guess that's what the're called !)
It can be possible by write helper function like this:
function deepFind($o, $key) {
$key = explode('->', $key);
$value = $o;
foreach ($key as $i=>$k) {
if (is_object($value) && isset($value->{$k})) {
$value = $value->{$k};
} elseif (is_array($value) && isset($value[$k])) {
$value = $value[$k];
} elseif ($i == count($key) - 1) {
$value = null;
}
}
return $value;
}
Usage:
$o = (object)[
"extra_info" => (object)[
"status" => "AlreadyVerified"
]
];
echo deepFind($o, 'extra_info->status');
Online demo
This is one way to do it, albeit potentially insecure depending on where $key comes from:
<?php
$object = new stdClass();
$object->extra_info = new stdClass();
$object->extra_info->status = 'AlreadyVerified';
$key = 'extra_info->status';
eval( 'echo $object->'.$key.';' );
Output:
AlreadyVerified
Additionally, if you wanted to parse $key then you could use a recursive function to access the nested value.

PHP object operator building string within foreach?

I am trying to build an object that will hold multiple objects based of iterating through an array:
<?php
$final_object = new stdClass();
$array = ['one','two'];
$temp_str = '';
foreach ($array as $value) {
$temp_str .= $value . '->';
}
$temp_str = rtrim($temp_str, '->');
$final_object->$temp_str = 999;
print_r($final_object);
exit;
As you can guess, the parser treats '->' as a string literal and not a PHP object operator.
Is what I am attempting to do possible?
Eventually, I want to build a json string after json_encoding to: {"one":{"two": 999}}
You could store a reference of the object during the loop and assign your value at the end:
$final_object = new stdClass();
$array = ['one','two'];
$ref = $final_object ;
foreach ($array as $value) {
$ref->$value = new stdClass() ;
$ref = &$ref->$value ; // keep reference of last object
}
$ref = 999; // change last reference to your value
print_r($final_object);
Outputs:
stdClass Object
(
[one] => stdClass Object
(
[two] => 999
)
)
You could do the same using arrays:
$array = ['one','two'];
$final_object = [];
$ref =& $final_object;
foreach ($array as $value) {
$ref[$value] = [];
$ref =& $ref[$value];
}
$ref=999;
echo json_encode($final_object);
Outputs:
{"one":{"two":999}}

How to trim object properties in PHP?

I have an object $obj as
$obj->{' Property1'} = " value1";
$obj->{'Property2 '} = "value2 ";
I want to get this object $obj as
$obj->{'Property1'} = "value1";
$obj->{'Property2'} = "value2";
I am able to trim all the values using
foreach($obj as $prop => &$val)
{
$val = trim($val);
}
but doing this (below) causing an error
foreach($obj as &$prop => &$val)
{
$prop = trim($prop);
$val = trim($val);
}
Please tell a solution.
Thanks in advance.
You can't reference a key.
What you have to do is unset it, and set the trimmed version like this:
<?php
$obj = new stdClass;
$obj->{' Property1'} = " value1";
foreach($obj as $prop => $val)
{
unset($obj->{$prop});
$obj->{trim($prop)} = trim($val);
}
var_dump($obj);
A little comment to Daan's answer. In his case script will fall into infinite loop if $obj have more than one property. So a working code looks like this.
<?php
$obj = new stdClass;
$obj->{' Property1'} = " value1";
$obj->{'Property2 '} = "value2 ";
$newObj = new stdClass;
foreach($obj as $prop => $val)
{
$newObj->{trim($prop)} = trim($val);
}
$obj = $newObj;
unset($newObj);
var_dump($obj);
Because you're trying to trim the property of the object. You can't do that.
That would work for an array, but not for an object. If you need to alter the properties of an object you need to change the properties of the class.

PHP Rename object property while maintaining its position

How can I rename an object property without changing the order?
Example object:
$obj = new stdClass();
$obj->k1 = 'k1';
$obj->k2 = 'k2';
$obj->k3 = 'k3';
$obj->k4 = 'k4';
Example rename by creating new property:
$obj->replace = $obj->k3;
unset($obj->k3);
Result:
( k1=>k1, k2=>k2, k4=>k4, replace=>k3 )
See the problem?
Simply recreating the object property causes the order to change.
I had a similar issue with arrays and came up with this solution:
Implemented solution for arrays
function replaceKey(&$array, $find, $replace)
{
if(array_key_exists($find, $array)){
$keys = array_keys($array);
$i = 0;
$index = false;
foreach($array as $k => $v){
if($find === $k){
$index = $i;
break;
}
$i++;
}
if ($index !== false) {
$keys[$i] = $replace;
$array = array_combine($keys, $array);
}
}
}
Looking for something similar to this but a function that will work on objects.
Can't seem to find any documentation on object property position indexes.
So, readd your properties
$obj = new YourClass();
$backup = [];
foreach ($obj as $key => $value)
{
$backup[$key] = $value;
unset($obj->$key);
}
replaceKey($backup, $find, $replace);
foreach ($backup as $key => $value)
{
$obj->$key = $value;
}
Since you have a function for your arrays, why dont you do something like :
$array = (array) $obj;
$replacedKeyArray = replaceKey($array);
$newObject = (object) $replacedKeyArray;

PHP Dynamic object operator within foreach loop

I've got this function:
$request = array("setNewDoc", "setNewFile");
foreach($request as $key => $val) {
$result = $controller->setNewDoc($key);
$smarty->assign('result', $result);
$index = TPL_DIR . 'docs.tpl';
}
Is it possible to make this loop dynamic with putting a variable in my pointer? The $keys in my array are also the name of the function.
Like $controller->$variable($key);
Like this(pseudo code)
$result = array("setNewDoc", "setNewFile");
foreach($request as $key => $val) {
$result = $controller->set$key($request);
$smarty->assign('result', $result);
// $key = setNewDoc or setNewFile
$index = TPL_DIR . $key . '.tpl';
}
Yes you can.
You can use it to cast a new object or to acces a property.
For exmaple
$classname = foo;
$prop=name;
$myObject = new $classname();
$myObject->{$prop} or a function: $myObject->{$prop}()
You can even foreach over an object's properties
foreach ($myObject as $key => $value) {
print $key // would be name
print $value // would be the value of the property
}
Yes that's possible and it is in fact pretty easy:
<?php
class MyClass {
function myMethod()
{
echo "Hello World";
}
}
$obj = new MyClass();
$dynamicVar = 'Method';
$obj->{'my' . $dynamicVar}();
enclose your method name with curly brackets and you can do some string concatenation inside. Once everything inside the the brackets is processed it will eventually used as your method name.
For your specific use case you would write something like
<?php
$result = array("setNewDoc", "setNewFile");
foreach($request as $key => $val) {
$result = $controller->{'set' . $key}($request);
$smarty->assign('result', $result);
// $key = setNewDoc or setNewFile
$index = TPL_DIR . $key . '.tpl';
}

Categories