I'm trying to remove stdClass property by reference. Because I don't know how deeply the property is nested, a reference is made in the loop. But the unset method does not remove variables by reference. How can I resolve it without just setting a null value?
<?php
$data = new stdClass();
$data->foo = new stdClass();
$data->foo->bar = 'value';
$pathToRemove = 'foo.bar';
$dataReference = &$data;
foreach (explode('.', $pathToRemove) as $field) {
$dataReference = &$dataReference->$field;
}
unset($dataReference);
var_dump($data);
Loop over all the elements except the last. Then use the last element as the field to delete.
$pathArray = explode('.', $pathToRemove);
$lastField = array_pop($pathArray);
$dataReference = &$data;
foreach ($pathArray as $field) {
$dataReference = &$dataReference->{$field};
}
unset($dataReference->{$lastField});
unset($dataReference); // don't need the reference variable any more
Related
This is my current code, I'm looking for a more efficient way of writing it.
Need something like looping through each variable with a foreach or adding them all to an array somehow, without me having to re-write every variable name.
$formValues = $form_state->getValues();
$relocation = $formValues['relocation'];
$europe = $formValues['europe'];
$twoyears = $formValues['twoyears'];
$realestate = $formValues['realestate'];
$nominated = $formValues['check_nominated_by'];
$nom_comp = $formValues['nom_company'];
$nom_contact = $formValues['nom_contact'];
$nom_email = $formValues['nom_email'];
$contact1 = $formValues['contact1'];
$position1 = $formValues['contact_position1'];
$email1 = $formValues['email1'];
$contact2 = $formValues['contact2'];
$position2 = $formValues['contact2'];
$email2 = $formValues['contact2'];
$contact3 = $formValues['contact3'];
$position3 = $formValues['contact3'];
$email3 = $formValues['contact3'];
tempstore = array();
$tempstore['relocation'] = $relocation;
$tempstore['europe'] = $europe;
$tempstore['twoyears'] = $twoyears;
$tempstore['realestate'] = $realestate;
$tempstore['membertype'] = $membertype;
$tempstore['nominated_by'] = '';
// All other fields need to be in this array too
// But there are a lot of unwanted fields in the $formValues
$_SESSION['sessionName']['formName'] = $tempstore;
Seeing as you know the keys you'd like to keep you can do the following:
<?php
/** The keys you want to keep... **/
$keys_to_keep = [
];
/** Will be used to store values for saving to $_SESSION. **/
$temp_array = [];
/** Loop through the keys/values. **/
foreach ($formValues as $key => $value) {
/** The correct key i.e. the key you'd like to save. **/
if (in_array($key, $keys_to_keep)) {
/** What you wish to do... **/
$temp_array[$key] = $value;
}
}
$_SESSION['sessionName']['formName'] = $temp_array;
?>
What is happening is that you are looping through your $formValues and getting both the keys and values of each pair in the array.
Then an check is being done against your $keys_to_keep to see if the current element is the one you wish to keep, if it is then you save it in to $temp_array.
Reading Material
foreach
in_array
You can use variable variables and a foreach.
Foreach($formValues as $key => $var){
$$key = $var;
}
Echo $relocation ."\n" . $europe;
https://3v4l.org/QeLjp
Edit I see now that your array variable keys are not always the same as the variable name you want.
In that case you can't use the method above.
In that case you need to use list() = array.
List($relocation, $europe) = $formValues;
// The list variables have to be in correct order I just took the first two for demo purpose.
I have the following structure in JSON:
[
{
"id":"79",
"value":"val1"
},
{
"id":"88",
"value":["val1","val2","new"]
}
]
How to handle this cases? I've tried this but it only handle the first case:
<?php
$arr = json_decode($json_string);
$itemsList = new stdClass;
$i_d=0;
foreach ($arr as $key=>$arrj):
$itemsList->id[$i_d] = $arrj->id;
$itemsList->value[$i_d] = $arrj->value;
$i_d++;
endforeach;
?>
Thanks in advance.
Inside your foreach loop, you can check that $arrj->value is an array. If it is, you can loop over it and add its values into your result object one by one, and if it isn't, you can add the single value as you already are.
<?php
$arr = json_decode($json_string);
$itemsList = new stdClass;
foreach ($arr as $key=>$arrj):
$itemsList->id[] = $arrj->id;
if (is_array($arrj->value)) { // Is it an array?
foreach ($arrj->value as $value) { // If so, add its values in a loop
$itemsList->value[] = $value;
}
} else {
$itemsList->value[] = $arrj->value; // if not, just add the single value
}
endforeach;
?>
I removed the $i_d variable; it is unnecessary because PHP will automatically create numeric indices beginning with 0 when you add values to an array using [].
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.
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);
}
}
I am looking to store some objects in an array during a foreach loop. The problem is creating a unique object each time. I have to have some kind of index appending the name of each object. Here is what I have:
function table_rows($html) {
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
($check_object . $key) = new check_class;
($check_object . $key)->check_method1($table_row);
($check_object . $key)->check_method2($table_row);
($check_object . $key)->check_method3($table_row);
$check_array[] = (check_object . $key);
}
}
Am I even close?
You could use variables for that:
function table_rows($html) {
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
$object = new check_class;
$object->check_method1($table_row);
$object->check_method2($table_row);
$object->check_method3($table_row);
$check_array[] = $object;
}
}
Of course naming the variable for an object instance $object is not very descriptive, but I hope you get the idea.
This works because the first assignment in the for-loop overwrites the "old" instance, so $object unique for each iteration.
In case Jared Drake is right and what you mean is unique array keys, not object (variable) names.
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
$check_object = new check_class;
$check_object->check_method1($table_row);
$check_object->check_method2($table_row);
$check_object->check_method3($table_row);
$check_array['check_object' . $key] = $check_object;
}
}
Maybe I'm misunderstanding the question, but can't you just use the array_push method to add each object to the end of the array in your foreach loop?