How to replace nested array value inside the Laravel request using merge? - php

There is a function to replace the input from the request which is called merge.
I would like to change a value of a nested array so that it can be validated by $this->validate method..
This is the output of $request->all()
array:2 [
"type" => "customer"
"users" => array:1 [
0 => array:3 [
"name" => "eeee"
"username" => "eeee"
"password" => "123456"
]
]
]
How do I access the username value and change it, provided I use a forloop
for($i=0; $i < count($request->users); $i++){
// i need to access the value here
// i have done something like $request->merge(['users'][$index]['username'] => 'xxx');
// it doesnt work
}
Any solution guys?
Thank you.

You can try something like this using merge method:
$new_users_data = $request->input('users');
foreach ($new_user_data as &$user_data) {
$user_data['username'] = 'new name';
}
$request->merge([
'users' => $new_users_data,
]);
You can also replace whole input with new one with request replace method.

Related

Getting data in particular format in PHP for Post request

I have to send some data in the below format-
$postData = [
'certExpiryDate' => $certExpiryDate,
'certType' => 'SSL',
'AltName' => [
$altName[0],$altName[1]
],
'csr' => $csr
];
$altName is an array that has 2 or more strings like- domain1.com, domain2.com.
The AltName parameter expects the data in this format-
'AltName' => [
'domain1.com','domain2.com'
],
(if I hardcode and send it like this, everything works fine.. this is the correct format)
If I take the array $altName directly like this-
'AltName' => [
$altName
],
I did a var_dump and for this it adds quotes outside like- "domain1.com, domain2.com", which it considers wrong.
I need it to be in the format of $altName[0],$altName[1] which would be correct, but I'm struggling on how to loop through this array in case it has more values than 2 and still get it in the required format.
Your attempt:
'AltName' => [
$altName
],
doesn't work as intended because it wraps the array $altName inside another array (created by the [ and ]).
Just set the $altName array to be the value of the property directly. There's no need for an extra array:
'AltName' => $altName
Demo: http://sandbox.onlinephpfunctions.com/code/fa3dd6a974be7ced4bdc5d878f692549b96e2b95
but I'm struggling on how to loop through this array in case it has
more values than 2 and still get it in the required format.
posting direct values:
//$altName = ["domain1.com", "domain2.com"];
//OR
$altName = array("domain1.com", "domain2.com");
$postData = ['AltName' => $altName];
var_dump($postData);
output:
array(1) {
["AltName"]=>
array(2) {
[0]=>
string(11) "domain1.com"
[1]=>
string(11) "domain2.com"
}
}

How to put value on laravel collection?

How to put value on first element in laravel collection ? Something like that $collection->put('foo', 1) but adding value to the first element.
Collection {#376
#items: array:1 [
0 => array:9 [
"id" => 83
"status" => "offline"
"created_date" => "Oct 31, 2018"
// add foo => 1 here
]
]
}
I suspect there's a cleaner way to do this, but this is the best I could come up with at the moment. You could also use map or transform with a comparison run on the key value that gets sent to their closures, but that would end up cycling through all elements of the array despite you knowing the specific one you want to target.
$collection = collect([
[
'id' => 83,
'status' => 'offline',
'created_date' => 'Oct 31, 2018'
]
]);
$firstKey = $collection->keys()->first(); //This avoids the unreliable assumption that your index is necessarily numeric.
$firstElement = $collection->first();
$modifiedElement = array_merge($firstElement, ['foo1' => 1]);
$collection->put($firstKey, $modifiedElement);
use this
$data = Model::all();
$data[0]->foo = 'your data here';

Laravel - Trying to get property of non-object - PHP

I am currently trying to learn Laravel and PHP in general.
I need to be able to import an Excel file, then get the data from that file. Currently, the import part works and I can see the data from the file. However, I am having trouble accessing the data.
I've read about the toArray() function in Laravel, and is using that as below:
$data = Excel::load($path, function($reader) {})->skipColumns(2)->get();
$data = $data->toArray();
foreach ($data as $key => $value) {
//We only need some of the available data.
echo $value->next_milestone_desc_cur._comp._incl_rltd;
echo $value->shipment_id;
}
Above code gives me below error:
Trying to get property 'next_milestone_desc_cur' of non-object
Below is an output from the array, which I have generated using dd($value):
array:543 [▼
0 => array:20 [▼
"next_milestone_desc_cur._comp._incl_rltd" => "005. DK - Add DropMode/Local Trp Org in Pickup Tab"
"milestone_cur._comp._sequence_no" => "005"
"cur._comp._export_validation" => "NOT OK"
"shipment_id" => "SBRY0162091"
"consol_id" => "CDK327188" ]
1 => array:20 [▼
"next_milestone_desc_cur._comp._incl_rltd" => "005. DK - Add DropMode/Local Trp Org in Pickup Tab"
"milestone_cur._comp._sequence_no" => "005"
"cur._comp._export_validation" => "NOT OK"
"shipment_id" => "SBRY0162124"
"consol_id" => "CDK327221"
]
What am I doing wrong here? I have also tried
echo $value[0]->next_milestone_desc_cur._comp._incl_rltd;, however this doesn't work either.
You are trying to access an array as an object hence your error and to address you second point, you need to use a nested loop to then access the sub-array.
Your array looks something like this:
$array = [
0 => [
0 => [
'test' => 'value'
],
1 => [
'test' => 'something'
]
],
1 => [
0 => [
'test' => 'value'
],
1 => [
'test' => 'something'
]
]
];
You need the following loop:
foreach ($array as $key => $nested) {
foreach ($nested as $nested_value) {
// You have access to your inner arrays.
echo $nested_value['test'] . ' | ';
}
}
Where your nested loops $nested would be $value.
Live Example
Repl
Your output from dd($value) shows that $value is an array. So you cannot use arrow notation that is for objects. Change these lines:
echo $value->next_milestone_desc_cur._comp._incl_rltd;
echo $value->shipment_id;
To:
echo $value[0]["next_milestone_desc_cur._comp._incl_rltd"];
echo $value[0]["shipment_id"];

Unsetting element in array

I am trying to remove a key/value pair from an array but it does not seem to work. Basically, I make an API call which returns JSON. As such I do
$tempArray = json_decode($projects, true);
If I output $tempArray I see something like this
array:2 [
0 => array:9 [
"id" => 4
"name" => "Some Project Name"
"value" => "234"
"user_id" => "1"
"client_id" => "97"
"contact" => "Jane Berry"
]
1 => array:9 [
"id" => 3
"name" => "Another Project Name"
"value" => "6"
"user_id" => "1"
"client_id" => "97"
"contact" => "John Doe"
]
]
I essentially need to remove the value element so I do this
unset($tempArray['value']);
If I output $tempArray after the unset, it displays exactly the same as before, with the value element and value there.
What do I need to do to completely remove this from my array?
Thanks
unset will not look recursivly to sub-array to remove the key value. Only if you have at first level a key named value will be removed. In your array first level keys are: 0 and 1.
So to remove value from all sub-arrays you have to go throw all items from the array and unset it. You can do this with a simple foreach.
foreach($tempArray as $key => $data) {
unset($data['value']);
$tempArray[$key] = $data; //Overwrite old data with new with value unset.
}
Now you will not have value key in sub-array items.
As per my comment, you have no key called 'value' which is a top level key in your array. If you array looked like this:
$myArray = array(
"value" => "My Value to delete",
"anotherKey" => "hello world",
);
Then you could do unset($myArray['value']); and you would remove the key and value. In your case, the key you are looking for is nested under a numeric key [0] or [1]. You could reference these specifically like this:
unset($tempArray[0]['value']);
but what I imagine you are looking to achieve is to remove any trace of the key value from your array in which case you would be better off doing something like this:
foreach($tempArray as &$nestedArray){
unset($nestedArray['value']);
}
Note the & symbol before the $nestedArray. This means 'pass by value' and will actually update the $tempArray in a single line without the need for anything else.
Further Reading:
PHP Docs - Arrays
PHP Docs - Foreach loop
PHP Docs - Pass by reference

Unset object variable's property in a method, affected its value in parent scope?

I made a small library to read database-exported xml file, and output it as an structured associate array. It can also filter the output by table columns.
After I've done the code, when I play with this class I find something weird. unset is acting as if the variable was passed by reference.
I could not spot any possible bugs, so I put up my the particular method where $this->rows is being set, hoping someone could enlight me.
private function populateData($rowLimit)
{
if (!$this->getColumns()) {
throw new ReaderException(__FUNCTION__ . " # Unable to get columns name.");
}
// database->tableName->rows
$rows = $this->getSimpleXmlElement()->children()->children();
if ($this->getFilteredColumns()) {
$toRemoves = array_values(array_diff($this->getColumns(),
$this->getFilteredColumns()));
foreach ($rows as $row) {
foreach ($toRemoves as $toRemove) {
unset($row->{$toRemove});
}
}
}
$rows = $this->simpleXmlToArray($rows)['row'];
if ($rowLimit) {
$limited = [];
for ($i = 0; $i < $rowLimit; $i++) {
$limited[] = $rows[$i];
}
$this->setRows($limited);
} else {
$this->setRows($rows);
}
$structArray = [
'database' => $this->getDatabaseName(),
'table' => $this->getTableName(),
'columns' => !$this->getFilteredColumns() ? $this->getColumns()
: $this->getFilteredColumns(),
'rows' => $this->getRows()
];
$this->setStruct($structArray);
return $this;
}
$xml = new SomeXmlReader($companyTableFilePath);
$xml->get(1);
output:
[
"database" => "myDatabase",
"table" => "companies",
"columns" => [
"id",
"name",
"license_no",
"phone",
"created",
"modified",
],
"rows" => [
[
"id" => "1",
"name" => "SOME COMPANY NAME",
"license_no" => "884652",
"phone" => null,
"created" => "2015-09-25 16:01:57",
"modified" => "2015-09-25 16:01:57",
],
],
]
When I tried to filter off some columns, I do
$xml->setFilteredColumns(['id','name'])->get(1);
it returns the result as expected: the columns have been trimmed.
Output:
[
"database" => "myDatabase",
"table" => "companies",
"columns" => [
"id",
"name",
],
"rows" => [
[
"id" => "1",
"name" => "SOME COMPANY NAME",
],
],
]
However, right after this line, when I test it again with
$xml->setFilteredColumns(['id','name','phone'])->get(1);
on the next line, something went wrong. The output is:
[
"database" => "myDatabase",
"table" => "companies",
"columns" => [
"id",
"name",
"phone",
],
"rows" => [
[
"id" => "1",
"name" => "SOME COMPANY NAME",
],
],
]
After some tracing, I find that $this->getSimpleXmlElement() had been modified by unset. Within this app lifecycle, I can no longer get the complete/original value of $this->getSimpleXmlElement().
Is there a fundamental mistake I've made, or this is a PHP language behaviour?
There is rather a lot of code to follow through here - consider making a more compact example - but it sounds like your misunderstanding is fairly simple.
Objects are never copied when going from one scope to another, because a variable doesn't "contain" an object, it "points at" one (this is not quite the same as pass-by-reference, but the effect is similar in many cases).
So when you run unset($row->{$toRemove});, you are indeed editing the $row object, and by extension the whole SimpleXML document.
If you want a copy of an object to work with, you have to explicitly "clone" it, as discussed in the PHP manual.

Categories