Query builder: passing argument to anonymous function - php

I got a problem in passing variable to query builder closure, here is my code:
function get_usersbyname($name){
dd($name);
$resultset = DB::table('users')->where(function($query){
$query->where('username', 'LIKE', $name);
});
....
}
if I run it, it returns an error "undefined name variable", but I already passed $name variable and checked its existence.
Also I cann't find any resouce explains how to pass variable to query builder anonymous function.
Could you help me with this problem?

You need to the tell the anonymous function to use that variable like...
Because that variable is outside the scope of the annonymous function it needs to be passed in using the use keyword as shown in the example below.
function get_usersbyname($name){
dd($name);
$resultset = DB::table('users')->where(function($query) use ($name) {
$query->where('username', 'LIKE', $name);
});
....
}

Related

passed variable in nested where query in laravel 9

I am trying to use variable to nested where() query in laravel 9 but i get an error that variable Undefined
my code:
public function edit($id)
{
$category = Category::findOrFail($id);
$parents = Category::
where('status' , 'active')
->where('id' , '<>' , $id)
->where(function($query){
return $query
->whereNull('parent_id')
->orWhere('parent_id', '<>', $id);
})->get();
}
the error:
Undefined variable $id
$parents = Category::
where('status' , 'active')
->where('id' , '<>' , $id)
->where(function($query) use ($id) { <-- problem is here
return $query
->whereNull('parent_id')
->orWhere('parent_id', '<>', $id);
})->get();
in this section of your code: ->where(function($query){ you need use keyword to pass value inside this inner function as below:
->where(function($query) use ($id) { .. };
the detail for this action is:
The closure is a function assigned to a variable, so you can pass it around
A closure is a separate namespace, normally, you can not access variables defined outside of this namespace. There comes the use keyword:
use allows you to access (use) the succeeding variables inside the closure.
use is early binding. That means the variable values are COPIED upon DEFINING the closure. So modifying $id inside the closure has no external effect, unless it is a pointer like an object is.
You can pass in variables as pointers like in case of &$id. This way, modifying the value of $total DOES HAVE an external effect, the original variable's value changes.
Variables defined inside the closure are not accessible from outside the closure either.
Closures and functions have the same speed. Yes, you can use them all over your scripts.
for more info read this.

Passing conditional param to Eager Loading in larave ends with error

my code is as followed:
return User::whereHas('roles', function ($role, $query) {
return $role;
$query->whereId($role);
})->get();
what I am trying is to pass role id here to query builder.
it ends up with following error:
Symfony\Component\Debug\Exception\FatalThrowableError
Too few arguments to function App\Http\Controllers\UserController::App\Http\Controllers\{closure}(), 1 passed in /Users/x/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php on line 962 and exactly 2 expected
I think this is what you want:
A closure is a function that is evaluated in its own environment, which has one or more bound variables that can be accessed when the function is called.
The use() keyword let's you import variables from outside the function environment, inside the function.
return User::whereHas('roles', function ($query) use ($role) {
return $query->whereId($role);
})->get();

How Laravel anonymous function know it's parameter

Consider this code:
$fn = FormNilai::whereHas('mataPelajaranLokalGuru',function($mlg) {
$mlg->where('guru_id','=',$this->uid);
})->get();
How is $mlg always treated as FormNilai instance? how is the scenario? I read a lot about dependency injection but still don't get the point.
Dependency Injection is a different part. As per your code example, You need to the tell the anonymous function to use that variable like...
$uid = $this->uid;
$fn = FormNilai::whereHas('mataPelajaranLokalGuru',function($mlg) use($uid)
{
$mlg->where('guru_id','=',$uid);
})->get();
As that variable uid is outside the scope of the anonymous function it needs to be passed in using the use keyword as shown in the above code.
You can get more idea on use with example here
The parameter $mlg isn't treated as FormNilai instance, it's just treated as an instance of Illuminate\Database\Eloquent\Builder.
You can see that how it works in the source codes.
Illuminate/Database/Eloquent/Builder.php#L934
Example:
Define an anonymous function accepts an regular argument:
$example = function ($arg) {
var_dump($arg);
};
$example("hello");
You can change the argument name to any string, just like $myArgument.
And the the output would not been changed whatever the argument name is.
Laterally i've realize that laravel support php anonymous style so we can implement such a javascript function usage but surely it hard for me to do for first time
For simple usage, they display an example like this
$users = User::with(array('posts' => function($query)
{
$query->where('title', 'like', '%first%');
}))->get();
What if the user wanted to make the third parameter is filled with variable. When i check it out with replacing those '%first%' word with any global variable, it ruins the structure, and it happend to me.
$title = 'heirlom of marineford';
$users = User::with(array('posts' => function($query)
{
$query->where('title', 'like', $title);
}))->get();
After searching to PHP documentation, i found that the technique to passing parameter to that anonymous function by extending function block with use() so the function would assume to use all variable that defined by the use() section
$title = 'heirlom of marineford';
$users = User::with(array('posts' => function($query) use($title)
{
$query->where('title', 'like', $title);
}))->get();
I hope that could help you

Undefined Variable Multiple Query Scopes Laravel

This work perfect:
public function scopeHBO($query)
{
return $query ->where('network', '=', "hbo");
}
Call in Controller: It Works!
$events = Schedule::HBO()->orderBy('searchdate')->get();
When I add another Query Scope like so:
public function scopeHBO($query)
{
return $query
->where('network', '=', "hbo")
->where('searchdate', '>=', 'NOW()');
}
OR:
public function scopeDate($query)
{
return $query->where('searchdate', '>= ', 'NOW()');
}
Then call in the controller:
$events = Schedule::HBO()->Date()->orderBy('searchdate')->get();
I get an error: Undefined variable: event. I tried with with Raw MySql in the same model and it works. Whenever i add a query scope, does not matter what it is.. i get that same error Undefined variable: event.
NOW() is a function, so you need to use a raw query:
where('searchdate', '>=', DB::raw('NOW()'))
Then you can use the scopes. (Do note that I think scopeDate must be called as date(), not Date() - not 100 % sure on that though.)
This sounds less like a generic problem with Laravel, and more like a problem with you specific application.
My guess (which is a wild guess), is that adding that second where clause in your scope method
return $query
->where('network', '=', "hbo")
->where('searchdate', '>=', 'NOW()');
ended up creating a SQL query that returned 0 rows. Then, somewhere in your other code you're doing something like
foreach($events as $event)
{
//...
}
//referencing final $event outside of loop
if($event) { ... }
As I said, this is a wild guess, but the problem doesn't seem to be your query code, the problem seems to be the rest of your code that relies on the query returning a certain number of, or certain specific, rows/objects.

laravel how to pass the paramters to the query scope?

look at code first:
$bookname = 'www';
User::with(array('roles' => function($query) {
$query->where('bookname' => $bookname);
}))->find(1);
but it lead an error"undefined variable $bookname"..how to fix this?thanks
Wrong syntax.
$bookname = 'www';
User::with(array('roles' => function($query) use ($bookname) {
$query->where('bookname', '=', $bookname);
}))->find(1);
To use the $bookname inside of the anonymous function you need to pass it using use statement. In addition where() function inside your anonymous function takes 3 parameters:
column name, comparing operator, search value.

Categories