why foreach print just one value in laravel? - php

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.

Related

how to map collection in php laravel

i want return data if a < b then a = b, if using foreach i have to make empty array first and parsing data to te empty array, how if record i much, that take time
public function getDepreciation(){
$values = $this->repository->getDepreciation();
$data = [];
foreach($values as $value){
if($value->depresiation_per_month > $value->balance_value){
$value->depresiation_per_month = $value->balance_value;
}
array_push($data,$value->depresiation_per_month,$value->balance_value);
}
return $data;
}
is there is simple code than my above, since i have to make relist many array
You can convert this array in a Collection then handle it easier by using the transform method.
First you have to create the collection using your array Create Collection
$values = collect($values);
Then you can iterate over the collection using the transform method and apply your logic Transform Method
Finally you have to convert your collection into an array using the toArray method toArray Method
I hope this works for you

Comparing associative arrays inside foreach loop laravel PHP

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.

Object returning three value instead of one. Laravel

I have used following code:
public function verify($id,$sid)
{
$sfees = sfee::where('student_id', $sid)->first(['mfee_id']);//mfee_id is the column I'm trying to recover
foreach ($sfees as $sfee) {
echo $sfee;
}
The problem is that it is returning three 1. While it was supposed to return only one.
If i echo $sfees before foreach it returns only one value: {"mfee_id":1}.
What is the problem? Can anyone help me?
You are asking for one model, you don't need to try and iterate it, its a single model (object). (first() can return null though, so you should check)
$sfees->mfee_id;
If you just want the value of that column for that one record:
$mfee_id = sfee::where('student_id', $sid)->value('mfee_id');
Laravel 5.2 Docs - Query Builder - Retrieving Results - Retrieving A Single Row / Column From A Table
You should use return statement for returning from function, not echo.
public function verify($id,$sid)
{
$sfees = sfee::where('student_id', $sid)->first(['mfee_id']);//mfee_id is the column I'm trying to recover
return $some_variable;
}
Your problem is that that your trying to itterate over a single model. That's cause that you itterate over attributes and you get odd result the only think that you need is to do like this:
public function verify($id,$sid)
{
$sfees = sfee::where('student_id', $sid)->first(['mfee_id']);//mfee_id
echo $sfees->mfee_id;
}
$sfees in this example is a single model not a collection of models becasuse you've used first to get it.

PHP Iterator Custom Sort Order (Laravel 4)

I have a "Post" object, accessed via the IOC container. Various errors tell me this object's type ends up as a "Collection", which implements several interfaces, including IteratorAggregate and ArrayAccess.
I want to display a user-defined group of posts according to a specific order, e.g.:
$desired=array("69","63","70");//these represent post id's
Just sorting an array in this manner seems complex, but I want to sort my collection. I have been researching various combinations of usort(), uksort(), Eloquent's sortBy(), array_multisort()... but the most obvious solutions result in orders like 3,2,1 or 1,2,3, not 2,1,3.
The closest I have gotten to this goal is to fetch the ones I want,
//BlogController
private function myposts($desired){
$posts=$this->post->whereIn('id',$desired)->get();
...
"convert" the Collection object to an array,
$posts=$posts->toArray();
and treat the array with a custom function: source
function sortArrayByArray($array,$orderArray) {
$ordered = array();
foreach($orderArray as $key) {
if(array_key_exists($key,$array)) {
$ordered[$key] = $array[$key];
unset($array[$key]);
}
}
return $ordered + $array;
}
$sorted=sortArrayByArray($array1,$desired);
I can then vardump the array in the correct order, but since it is now an array, I can't access the $posts object in my view. Can I convert the array back into a post object?
This whole approach feels wasteful anyway, converting to an array and back... is it? Is there a more straightforward way of sorting the contents of a "Collection"?
This is a little better, perhaps (a native php function):
array_multisort($desired,$posts,SORT_STRING);
//only works with string keys
//$desire=(1,2,3) will not work!
Again, this works for arrays, but attempting directly on the "posts" object fails...
Finally, I discovered using a Presenter: https://github.com/robclancy/presenter#array-usage which works in the view, after one of the above is completed in the controller:
#foreach($posts as $post)
<?php $post=new PostPresenter($post) ?>
{{View::make('site.post.article')->with(compact('post'))}}
#endforeach
This finally works, but it still feels like a long way to do it. Is there a better way to accomplish this task? Performance concerns or best practices with one method vs. another? Thanks in advance for anyone able to help.
You can use the Collections own sort method and pass in a callback. The callback compares every two values in your collection tells the sort method which one is "higher". The sort method then sorts them accordingly. If you want a specific value order you just create mapping and sort by that. For more info check uasort
$posts->sort(function($a, $b){
$desired=array("69" => 0,"63" => 1,"70" =>2);
if(!array_key_exists($a,$desired) || !array_key_exists($b,$desired) || $a == $b){
return 0
}
else{
return ($desired[$a] < $desired[$b]) ? -1 : 1;
}
});
Alternatively to #tim's answer, you can re-assign the sorted array to a new Collection object:
$postsArray = $this->posts->toArray();
// Do some sorting/processing, then:
$newCollection = new \Illuminate\Database\Eloquent\Collection( $postsArray );

Cleanest way of dealing with different argument types

I have the following piece of code, which generates six drop-down elements:
for($i = 0; $i < 6; $i++)
{
$RelatedProductsHtmlList .= $this->getRelatedProductHtmlDropdown($Products[$i], $allAvailibleProducts, $i);
}
In this code, the argument $Products[$i] is passed, which is a ORM object with information for setting the default selected value of the drop-down list that is generated. I have the problem that $Products is not always an array. Sometimes only contains one value, in which case it's not an array, but a single ORM object.
What is the cleanest thing to do? Convert $Products to an array with only one element? Always pass the entire $Products variable en determine in the function if it's an array? Or determine if $Products is an array before calling the function and set the function argument accordingly?
You have two options: fix it before calling the method or inside the method itself.
Example:
if(!is_array($products)) {
$products = array($product));
}
If you ask me, I would add this code to the top of the method itself as this would ease the function call and reduce redundant code.
I would suggest to allow to pass array and a single object into a function. You will avoid multiple checks in different parts of code. You can do it this way:
/**
#param array | ProductClass $Products
...
*/
public function getRelatedProductHtmlDropdown($Products, $allAvailibleProducts, $i)
{
if (!is_array($Products)) $Products = array($Products);
....
}

Categories