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){...}
Related
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.
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.
In my controller I get all the entries from Athletes table, names, surnames etc... Save them in the array and pass them to my view. In my view file I then list all the entries using foreach . All the Athletes are listed fine...
However I want to check every Athlete and see if they exist in the table My Team! So in my foreach loop in my view I use this function
$this->my_team_model->exist($this->session->userdata("id"), $athletes[$i][6]) === TRUE
First parameter of exist() function is user id I get from session, second parameter is id of Athlete from Athletes table ($athletes[$i][6]).
So you see I really need that second Athlete id parameter! But I can only get it when the Athletes are listed one by one in my view. But I know I shouldn't use functions and logic in my view files. How can I do this in my controller?
you should be using that same foreach loop in your controller and get the required data there itself, append the data to the array you pass to the view:
$array = $this->some_model->all_the_data_of_atheletes();
foreach( $array as $key => $eachAthelete ){
$exists = $this->model->call_to_function( $this->session->userdata("id"), $eachAthelete['id'] );
$array[$key]['exists'] = $exists;
}
$this->load->view('some_view', $array);
Now, in your view you will get an exists element for every iteration. Hope it helps you.
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 an Entity Category, which is linked to itself in order to form a tree (a category can have a category as a parent and a category can have a bunch of categories as children). These are marked as private inside the Entity and not exposed to the serializer.
When I do $category->getChildren()->toArray(), I get an array of the children, but when I do $this->getDoctrine()->getRepsitory('PmbLicensing:Category')->findByParent($category)->toArray(), I get an error that toArray() is not defined. I need to use the latter because the top level categories have their parent set to null, so I cannot use the former method. How do I convert the collection of categories obtained in the latter method to an array?
Also, when trying to trouble shoot, I often would like to print out variables, but when I do something like print_r($categories);, print_r((array)$categories); or var_dump($categories); the call just runs for about two minutes and then returns null. I assume it is because of the relational mapping that goes into an infinate loop, but how do I stop this from happening?
Edit: I want to convert the object (or collection of objects) to an array, because I want to build a recursive function where the children categories of the supplied category can be retrieved up to n-depth. If the supplied category can be null, in order to retrieve from the main level of categories (with parent set to null). Here is my function:
private function getRecursiveChildren(Category $category = null, $depth, $iteration)
{
$children = $this->getDoctrine()->getRepository('PmbLicensingBundle:Category')->findByParent($category);
// \Doctrine\Common\Util\Debug::dump($children); die();
if ($depth > $iteration)
foreach ($children as $child) {
$child['children'] = $this->getRecursiveChildren($child, $depth, $iteration+1);
}
return $children;
}
On the line that has $child['children'], is says that I cannot use an object as an array.
If you need the results as an array you can return them from the database as arrays.
In your CategoryRepository class:
public function findArrayByParent($categoryId)
{
// it's a good adivce from #i.am.michiel to pass only the `id` here.
// You don't need the whole category object.
$query = $this->getEntityManager()->createQuery('...')
->setParameters(array('categoryId' => $categroyId));
return $query->getArrayResult();
}
They are never converted to objects after being retrieved from the DB so you also save time and memory.
Actually your
$children = $this->getDoctrine()->getRepository('PmbLicensingBundle:Category')
->findByParent($category);`
already returns an array so you don't have to (and can't) use ->toArray().
When you loop through your categories with
foreach ($children as $child)
$child["..."] = ...
You are treating an obect $child like an array with ["..."]. That's what your error message is about.
If you can, you should probably use doctrine and let it fill the related child and parent categories. See the Doctrine Documentation on this. Then you have automatically all your Children and can access them like $category->getChildren() (This one will return an ArrayCollection). This will save you a lot of work.
Your call simply returns no categories. Btw, I think you should pass the id of the category, not the entity.
$this->getDoctrine()
->getRepository('PmbLicensing:Category')
->findByParent($category->getId());
And why use the toArray() function? ArrayCollection already are arrays with a few additionnal methods? You should be able to use an ArrayCollection whenever you used an array.