"IN" and "NOT IN" in CakePHP3 [duplicate] - php

This question already has answers here:
Access variables from parent scope in anonymous PHP function
(2 answers)
Closed 5 years ago.
There is an example in the Cookbook:
$query = $cities->find()
->where(function ($exp, $q) {
return $exp->notIn('country_id', ['AFG', 'USA', 'EST']);
});
In SQL this should be aequivalent to:
WHERE country_id NOT IN ('AFG', 'USA', 'EST')
Now, I'm trying to use a variable here. Sadly, this won't work:
$query = $cities->find()
->where(function ($exp, $q, $variable) {
return $exp->notIn('country_id', $variable);
});
Any ideas?

I always find the easiest way to use IN and NOT IN is as follows in CakePHP
$query = $cities->find()
->where(['country_id IN' => $variable])
More information on auto generating in clauses is at the following link in the book. You can also use it to cast values to the type of the column automatically. To me it is more readable as well.
https://book.cakephp.org/3.0/en/orm/query-builder.html#automatically-creating-in-clauses

It works with "use", see: PHP: Anonymous Functions
$query = $cities->find()
->where(function ($exp, $q) use ($variable) {
return $exp->notIn('country_id', $variable);
});

Related

how to use WHERE clause and WITH in Laravel

I'm working on a small project using laravel and i would like to know how can i use WHERE clause for apartment this is my code
$buildings = Building::with('apartment')->get();
i have already tried :
$buildings = Building::with('apartment')->where('name','=',5)->get();
but it applies for Building not for apartment.
how can i apply WHERE clause for apartment ?
You can apply a Closure to with(...) if you pass in an array using the following syntax:
Model::with(['relation_name' => function ($query) { ... }])
In your case, what you're looking for is:
$buildings = Building::with(['apartment' => function ($apartments) {
$apartments->where('name', 5); // if you don't pass an operator, it's assumed to be '='.
}])->get();
You can also write it like this using PHP 7.4 shorthand closures.
$buildings = Building::with(['apartment' => fn($apartments) => $apartments->where('name', 5)])->get();
https://laravel.com/docs/7.x/eloquent-relationships#constraining-eager-loads
Try this
$buildings = App\Building::with(['apartment' => function ($query) {
$query->where('name', 5); .
}])->get();

array for multiple where_in condition in codeigniter [duplicate]

This question already has an answer here:
Codeigniter model with multiple update conditions using manual where statement
(1 answer)
Closed 5 years ago.
$this->db->where('column_field1',$value1);
$this->db->where('column_field2',$value2);
For above two query we can write a single query as:
$arr = array('column_field1'=>'value1', 'columne_field2'=>'value2');
function select($arr){
.. .. ..
... .. . ..
$this->db->where($arr);
}
is there any solution for the where_in query:
function($value1, $value2){
$this->db->where_in('column_field1',$value1);
$this->db->where_in('column_field2',$value2);
}
as I have tried but didn't work:
arr = array('column_field1'=>$arr,'column_field2'=>arr2);
function select_in($arr)
{
$this->db->select('*');
$this->db->from('table');
$this->db->where_in($arr);
$query = $this->db->get();
return $query;
}
I want to combine the where_in condition so that i can store multiple column_field and array for it.
$this->db->where_in($arr);
where $arr contains pair of column_filed and array_of_value:
$arr = $array('column_field'=>$arr_of_value);
function select_in($arr)
{
$this->db->select('*');
$this->db->from('table');
$this->db->where($arr); // change here
$query = $this->db->get();
return $query;
}
If you want multiple where In then you need to write it twice....It's not possible in single statement.
$this->db->where_in('field1',$cond1);
$this->db->where_in('field2' , $cond2);
Note: Where_in is similar to where id IN (1,2,3...)but in your case you are doing multiple where condition.
Creating custom method is a reasonable solution for this, you can either extend database's active record class or write custom function which takes array and call where_in like below
function multiple_where_in($array){
foreach($array as $key => $data){
$this->db->where_in($key, $data);
}
}
And call like below
function select_in($arr)
{
$this->db->select('*');
$this->db->from('your_table');
$this->multiple_where_in($arr); // call local function created above
$query = $this->db->get();
return $query;
}
// create array like below, fieldname and field_values inside array
$arr = array(
'column_field1'=>array('value1','value2'),
'columne_field2'=>array('value2','value3')
);
// call your select method
$this->select_in($arr);
You can try this solution for your problem.
$this->db->select('*');
$this->db->from('table');
if(!empty($cond1) && !empty($cond2)){
$this->db->where("field1 IN (".$cond1.") AND field2 IN (".$cond2.") ",null,false);
}
$query = $this->db->get();
return $query;
I hope this will helps you. Thanks!

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

Splitting a big nested query in Laravel

I have a big query which has a nested query. I want to know how to write it so that it's not cluttered. What I tried was creating query objects
//get the latest joined employee per department
$q1 = Employee::where('job', 'assistant')
->groupBy('dept_id')
->select(DB::raw('MAX(empid) as empid'));
//fetch his course ID
$q2 = Employee::whereIn('empid', function($query){
$query->$q1;
})
->where('university', 'LIKE', '%UCLA%')
->select('course_id')
->distinct()
->get()->lists('course_id');
I am getting this error
[Symfony\Component\Debug\Exception\FatalThrowableError]
Cannot access empty property
How should I do it?
You need to inherit your variable from your parent scope in your anonymous function. It's possible with use, like so:
function($query) use ($q1) {
// use $q1 here
}
Read about use (Example #3 Inheriting variables from the parent scope) here: http://www.php.net/manual/en/functions.anonymous.php
You should do it in this way:
$q1 = Employee::where('job', 'assistant')
->groupBy('dept_id')
->select(DB::raw('MAX(empid) as empid'));
$q2 = Employee::whereIn('empid', function($query) use($q1) {
$query->where('id', $q1); // <---- Do it like this
})
->where('university', 'LIKE', '%UCLA%')
->select('course_id')
->distinct();
Hope this helps!

CakePhp - how to access variables inside find->innerJoinWith? [duplicate]

This question already has answers here:
PHP variables in anonymous functions
(2 answers)
Closed 7 years ago.
I am trying to query for users that are assigned to a certain project in CakePHP. How could I basically achieve this:
$projectId = //Project ID query result.
$users = $this->Tickets->Users
->find('list', ['limit' => 200])
->innerJoinWith(
'ProjectsUsers', function($q){
return $q->where(['ProjectsUsers.project_id' => $projectId]);
}
);
This code works when not using variables (eg. replacing $projectId with 8) but when I try to use variables I get: Undefined variable: projectId
How can I pass variables into innerJoinWith?
If you mean how to inherit a variable from the parent scope, you'd do it like this.
$users = $this->Tickets->Users
->find('list', ['limit' => 200])
->innerJoinWith(
'ProjectsUsers', function($q) use($variableToPass) {
return $q->where(['ProjectsUsers.project_id' => $variableToPass]);
}
);

Categories