Using eloquent, I am querying two sets of data like so:
$all_perms = Permission::all(); //all permissions
$role_perms = Auth::user()->roles()->permissions; //permissions belonging to a role
$role_perms is a subset of $all_perms and what I want is to loop both arrays and come out with a new array containing all permissions already assigned to a role together with those not yet assigned to a role.
What I have done is loop through both arrays in a foreach loop and if any one array belongs to both sets, I mark it by adding a check key with corresponding value 1 to the array so that I can identify is as a permission already assigned to a role.
foreach ($role_perms as $role_perm) {
foreach ($all_perms as $key => $value ) {
if (array_diff_assoc($all_perm, $role_perm)) {
$all_perm['check'] = 1;
}
}
}
but it keeps throwing the error:
array_diff_assoc(): Argument #1 is not an array
Are they better ways of doing this? Or what can I do on this one to make it work?
Thanks for any help
That's because it's a collection, not an array. If you want to get an array, try to use toArray():
$all_perms = Permission::all()->toArray();
Also, is this a typo here:
array_diff_assoc($all_perm, $role_perm);
It should be $all_perms
Try using the wonderful contains method that is available on all your collections:
foreach ($role_perms as $role_perm) {
if($all_perms->contains($role_perm))
{
// do whatever is needed
}
}
Checkout the docs for help with the contains method.
Related
I'm fetching data from database, inside foreach loop i have to add one array index list_array
$list = Lists::where('name',$request->name)->get();
$Data=[];
foreach($list as $key => $list_row)
{
$list_row['list_array'][]=$list_row['data_1'];
$list_row['list_array'][]=$list_row['data_2'];
$Data[]=$list_row;
}
It should be of array type but when i declare it as array it is not working,
message: "Indirect modification of overloaded property
App\Models\Lists
Any solution to create list_array as an array index inside foreach loop. Thanks
You are not dealing with an array, you are dealing with an App/Models/Lists model. What you probably instead want to do is adding a custom attribute to the model. This happens one step before.
// your model
class Lists
{
protected $appends = ['list_array'];
public function getListArrayAttribute()
{
$data = [
// your array data from where ever
];
return $data;
}
}
You then can access (without adding it when you want to access the data) the new attribute from within the model, like so:
// where you access your data
$lists = Lists::where('name', 'whatever')->get();
foreach($lists as $list) {
dd($lists->list_array)
}
You can read more about the so called Accessors here:
https://laravel.com/docs/8.x/eloquent-mutators#defining-an-accessor (Laravel 8)
https://laravel.com/docs/9.x/eloquent-mutators#defining-an-accessor (Laravel 9)
I hope I got the intention of your question right. From your question it's not very clear what data you want to add and where it is coming from. There might be other and better ways too.
Edit:
Based on the comment from #user3653474 the Accessor function could look like this.
public function getListArrayAttribute()
{
$data = [
$this->data_1,
$this->data_2,
];
return $data;
}
data_1 and data_2 are the column names in the table of the same model.
I have a simple CRUD item called Filters. In here each filter is assigned to a category with a foreign key. What I am trying to do is loop through each foregin key to get the category name rather than id to display to the user.
I get all filters first and performed a die/dump to check all results were there and they are.
When trying to assign the category name to the correct array item I get this error:
"Indirect modification of overloaded element of App\Filter has no effect"
So to check what's happening I have die/dumped inside the foreach loop and the exact same data has now disappeared. Even if I just put a foreach loop in with no modiifcaiton of the original array, when I pass this back to the view it has been unset.
AM I being very naive and not realising something this foreach loop does that destroys this data???
I have copied my code below and commented where the dd works and doesn't;
public function show()
{
$filter = [];
$filter['filters'] = Filter::all();
//dd($filter['filters']); --this works fine here
foreach($filter['filters'] AS $key => $filter){
//dd($filter['filters']); --this returns null here
$category = Category::where('id', $filter->category)->first();
$filter['filters'][$key]->category = $category->category;
}
return view('admin.crud.filters.index')->with('filter', $filter);
}
Don't re-initialize a variable or different data-type with same name
Try to change the $filter to something else in foreach loop. Because you already have an array with same name.
Do something like:
foreach($filter['filters'] AS $key => $f){...}
I have a method:
public function winnerDetails()
{
$winners = DB::table('winners')->get();
//dd($winners);
foreach ($winners as $winner) {
$qrMainId = $winner->qrdetails_id;
}
dd($qrMainId);
}
dd($winners); returns to value of array but when i use foreach its returns one value. How can i get who value returns with foreach loop?
dd($winners) output:
and dd($qrMainId); return one value 44. But it should return another value of array 35; Thanks in advance.
To get array of ID's use
foreach ($winners as $winner) {
$qrMainId[]= $winner->qrdetails_id;
For just value use
$qrMainId='';
foreach ($winners as $winner) {
$qrMainId.= $winner->qrdetails_id;
If you want to accomplish this task in a Laravel way use the pluck method to map the array for the key that you want
<?php
public function winnerDetails()
{
$winnersId = DB::table('winners')->get()->pluck('qrdetails_id');
dd($winnersId);
}
I think you are not leveraging the power of Laravel here. Obviously, I don't know what you are trying to do but here are some pointers.
You should probably be making a model for the winners table now models in Laravel return Collections as does the DB facade you are using now. Now the Collection class contains alot of usefull helpers like pluck
At this point it becomes as easy as Winner::all()->pluck('id') and you got yourself an array of id's.
And if you would like to get them comma seperated or anything like that you can use the implode
And you would get Winner::all()->implode('id',',');
$qrMainId is a variable not an array.
It is modified in the foreach during every loop.
So your code has always the last element of the array.
Use an array to collect values like
$qrMainId[] = $winner->qrdetails_id;
or sql select directly the field you want.
I have this:
foreach ($books as $book)
{
$catname = get_category_name($book['category']);
$book['category'] = $catname;
}
print_r($books);
Right now, $book['category'] represents an integer value, which references the ID of a row in a category table of the database (e.g. ID 1 = Fiction). As you can guess, get_category_name($id) takes an ID and finds the correct row, and returns the name of the category. The function works correctly, and if i print_r($catname) in the foreach it prints the names of the categories, like it should.
I have an associative array called $books that gets filled from every row in the book table in the database. What I want to do, is take the category integer value of each book element and use get_category_name($id) to replace that integer value with the actual category name.
The problem I am having is that I cannot replace the integer value that already exists at $book['category'] with the actual category name which resides in $catname. When I use print_r($books) to see if the changes were made in the foreach, they confirm the changes do not get made.
How can I fix this?
I think you want something like this?
foreach ($books as &$book)
{
$catname = get_category_name($book['category']);
$book['category'] = $catname;
}
print_r($books);
Notice the &$book.
You either use foreach($books as &$book) and edit $book. This way you have a reference to the real book element inside the array in stead of a copy of it. Beware that if you want to do this multiple times on the same array, you will need to reset the array each time after use. See: http://nl1.php.net/reset
Or you use foreach($books as $key=>$value) and edit $books[$key]. This way you get copies of the books and their keys. But you then use the key on the original array.
THe problem is that in fact you do not change $books but $book, that is why you cant see changes in $books. Possible solution:
foreach ($books as $booksId => $book) //$booksId will contain current index in $books
{
$catname = get_category_name($book['category']);
// now you can change correct index in $books:
$books[$booksId]['category'] = $catname;
}
Edit: #Cardinal solution with refference is also correct.
I have a PHP array of objects, say with two properties a and b. So for example I can do
$arr['a1']->a = $z;
$x = $arr['a1']->b;
The array is currently using the value of each object's a property as the array key, e.g.
$arr['a1']->a == 'a1'
This is so I can quickly look up the object by that property. I now need to quickly look up by b, and so want to switch the keys from being set to property a to being set to b (both are unique).
Is there an easy way to do this? In-place or into another array are both fine.
foreach($arr as $key => $object)
{
$arr2[$object->b] = $object;
}
This will create a new array that points to the same objects.
If you want them in one array, you can do as Joost suggested in the comments ($arr[$object->b] = $object; in the loop instead). However, that will only work if there are no duplicate keys between the two sets.