Using Array in '->where()' for Laravel Query Building - php

I am trying to get all values of a column, and then use it in another query. I used lists and got the values as an array but, I couldn't find the way to check that variable (array containing each id) in other query
$subscribes = Subscribe::where('from_id', $currentUser)->lists('id')
// dd($subscribes), logs values as array.
$videos = Photo::where('id', $subscribes)->get();
This doesn't work because $subscribes is an array.
Should I use a for loop and send another query for each id? Or is there a practical way that I am missing out? What is the proper way of using it?

Use whereIn method:
$videos = Photo::whereIn('id', $subscribes)->get();
http://laravel.com/docs/5.1/queries (scroll down / search 'whereIn')

Apply whereIn method
if(is_array($subscribes) && count($subscribes) > 0){
$videos = Photo::whereIn('id', $subscribes)->get();
}

Related

Laravel convert resultset to array

Database table SITE has many columns. One of them is site_id. I need all the site_ids as an array since it has to be fed to a method which accepts only a string array.
What I tried so far is:
$sites = DB::select('select site_id from site_tab');
$sites_arr = $sites->toArray();
But this doesn't produce the result I want. I need $sites_arr to be like ['A','B','C',...]
Please suggest a way to get this done. A solution based on Eloquent is also OK for me.
Thanks
Try this:
DB::table('site_tab')->pluck('site_id')->toArray();
reference pluck
referen toArray
If you open a manual, you will see that
The select method will always return an array of results
So, there's no need to use ->toArray(), as result is already an array.
To get values as array of names you can do:
$site_ids = DB::table('site_tab')->pluck('site_id');
Using ->toArray() here is optional, as you can iterate over $site_ids (which is a Collection) with a foreach too.

Using aliases with eloquent

When I tried using alias using select with eloquent, it has given me weird results
my code:
$caseStudy = CaseStudy::find($id)->select('title_case as title','description_case as description')->get();
It returned collection. My question is to find model and change the column names. How to do it?
The find function can take an array as a second parameter.
In this array you can list the fields you need.
$caseStudy = CaseStudy::find($id, ['title_case as title','description_case as description']);
This way you should be able to access your aliases:
$caseStudy->title
Instead of:
$caseStudy->title_case
try using this
$caseStudy = CaseStudy::select(DB::raw('title_case as title','description_case as description'))->find($id)->get();

how to get the where clause in string format using CakePHP3 ORM?

In CakePHP3, there is a ORM that helps with building queries.
From the documentation, I can see that
$query = $articles->find(); // build a query that has not run yet
$query->where(['id' => 1]); // Return the same query object
So in this case, I want the string
WHERE `articles`.`id` = 1
After much googling, I found out that there is a way to return just the where clause of a query object.
$query->where(['id' => 1])->clause('where'); // Return the where clause in the form of a QueryExpression
More googling leads me to find out how to get the QueryExpression to spit out string representation
$query->where(['id' => 1])->clause('where')->sql($valueBinder); // Return the where clause in string format
Here is my problem. I don't know what the $valueBinder is supposed to look like. I don't know how to initialize it.
I am also happy not to use ValueBinder as long as I can get the where clause in string format using CakePHP 3 ORM and in the right SQL dialect. Please assume I am using MySQL.
Please advise.
EDIT
I tried to use $query->valueBinder() as the $valueBinder.
It is empty and does not contain the associated c:0 to the value 1.
To directly answer your question, you can get the SQL for any clause this way:
$binder = new \Cake\ORM\ValueBinder();
$query->clause('where')->sql($binder);
That will return the SQL with the correct placeholders, not with the values to be used. The values live in the $binder variable and are used for statement objects.
As I can see, you only wanted to preserve the internal structure of the where clause to pass it to another query in a different request. Your solution is fine, but I'd like to add that you can also encode a full conditions tree from an existing query:
$where = serialize($query->clause('where'));
$anotherQuery->where(unserialize($where)); // A query in another request
In any case, you need to be careful with what you are unserializing as taking it directly from user input will certainly lead to security problems.
You can choose to omit this param if you like. Please see http://api.cakephp.org/3.0/class-Cake.Database.Query.html#_sql
In addition, you can use the Query member function traverse($visitor, $parts) to isolate the where clause. $visitor is a function that takes a value and a clause. You define the behavior of $visitor. $parts is an array of clause names. I suggest passing array('where') into this param.
My workaround is that I store the conditions in json string format.
Using the same example, what I do is
$data['conditions'] = json_encode(['Articles.id' => 1]); // encode into JSON string
$this->DynamicRules->patchEntity($dynamicRule, $data); // use in edit action of DynamicRulesController
then when I need to reuse the conditions, I do:
$articlesTable = TableRegistry::get('Articles');
$query = $articlesTable->find(); // new query for Articles
$rule = json_decode($dynamicRule->conditions, true); // get back the conditions in associative array format
$query->where($rule); // re-assign the conditions back
This got me what I ultimately wanted.

fetch a single postgres record as an associative array without using while loop

If I have a statement that I know will return only one result:
$emp_query = "SELECT * FROM table WHERE id = 'employee_id' LIMIT 1"
Is there any way I can access the result of pg_query($con, $csr_query); as an associative array without using a pg_fetch_assoc and a while loop? A while loop seems unnecessary when I know I'm retrieving only one record. Maybe there is some way in PDO as well, I'm just setting it up this way first because I'm more comfortable with the simple way. Thanks.
Something like pg_fetch_result:
http://www.php.net/manual/en/function.pg-fetch-result.php

How to determine whether a particular resource has data

I am trying to figure out the proper way to get file location data (for display/editing) from MySQL with PHP. So far I've got these three parts. $resfile is a resource getting the actual array. Would I then test with an if statement, or would I have to use a while loop to iterate over the array (which, as far as I know, should only have ONE value)
First part:
$resfile = mysql_query('SELECT file_loc WHERE org_id = '.$org);
Do I use this?
if (!$resfile) {
}
Or this?
while ($filerow = mysql_fetch_array($resfile)) {
}
Or both?
The mySQL library has a function for counting the rows of a result set:
if (mysql_num_rows($resfile) > 0) .......
You need to use both. If the query returns false, then there was an error executing your query. If there is no data returned in the query, (it will still return true) then you need to use fetch_array to get the data.

Categories