RedBeanPHP fetchAll only returning one row - php

I am making a call to the database to fetch some data. I have tried the request in SQL, and it works fine. I have coded the query using PDO, and it works fine. But using RedBeanPHP with the same query only returns one result.
$app->get('/shoutbox/new/:msgid', function ($msgid) use ($app) {
$messages = R::findAll('shoutbox_message', ' WHERE message_id > ? LIMIT 10', array($msgid));
$app->response()->header('Content-Type', 'application/json');
var_dump($messages);
echo json_encode(R::exportAll($messages));
});
I have used var_dump($messages) to verify there's only one message being returned.
I found a similar problem here, but the OP solved it without explaining how: sql query using redbeans php
Any advice?

You are using R::findAll which is used for when you do not want to add any conditions. However, you have a WHERE condition in your query. You want to use the R::find method instead.
I'm not sure what value is being passed is in your $msgid parameter or what the resulting $messages should contain, but the query would look like this.
$messages = R::find('shoutbox_message', ' message_id = ? LIMIT 10', array($msgid) );

Related

Write a query manually into the laravel

I have a little problem, I want to try to take the data with a custom query on laravel but when I try foreach I can't get the data. anyone can help me
This script on the controller :
$data = DB::Statement('SELECT NM_PERUSAHAAN,
count(*) as total_count,
sum(FLAG_TERIMA) as approved,
sum(1 - FLAG_TERIMA) as not_approved
from MSTBEASISWAS
group by NM_PERUSAHAAN;');
foreach ($data as $datas) {
echo $datas;
}
Error :
Here is the difference
DB::raw()
It generates a raw and sanitized SQL string, to be passed to other query/statements, preventing SQL injections. Is to be used with all of the and never alone. And you should never send a not sanitized string to your query/statements.
DB::select(DB::raw('select * from whatever'));
DB::select()
Is for simple selects:
DB::select(DB::raw('select * from whatever'));
DB::statement()
I think it work with selects, but should be used for non SQL query commands:
DB::statement(DB::raw('update whatever set valid = true;'));
DB::unprepared()
All SQL commands in Laravel are prepared by default, but sometimes you need to execute a command in an unprepared mode, because some commands in some database cannot be ran in prepared mode. Here's an issue I opened about this:
https://github.com/laravel/framework/issues/53
DB::unprepared(DB::raw('update whatever set valid = true;'));
Ref: Difference between Laravel's raw SQL functions
The DB::statement() method is used to execute SQL statements without returning result instead return true/false.
You're trying to use this boolean as a query result that why you've this message back from the foreach loop, if you want to run a select statement, you could use DB::select(), e.g :
DB::select('select query here');
Hope this helps.
You can write custom query like:
$data = DB::select(DB::raw('your query here'));
You can do as follows :
$data = DB::select($your_select_query);
The "statement" method of the DB facade returns a boolean value, which tells you whether the query execution was successful or not. Therefore foreach can not process it and throws an exception.
You can understand this by looking at the 2nd line of the exception stack trace.
array('data' => true)
So, to run a raw query string use the following code:
DB::select(DB::raw('SELECT NM_PERUSAHAAN,
count(*) as total_count,
sum(FLAG_TERIMA) as approved,
sum(1 - FLAG_TERIMA) as not_approved
from MSTBEASISWAS
group by NM_PERUSAHAAN;'));
DB::statement will not return data. if you are performing queries which don't return data, then using a SELECT query will result errors. For example, if you want to start the auto-increment ID of a MySQL table to something other than zero, we can use the statement method.
for the above query you have to use DB::select.
$data=DB::Statement('SELECT NM_PERUSAHAAN,
count(*) as total_count,
sum(FLAG_TERIMA) as approved,
sum(1 - FLAG_TERIMA) as not_approved
from MSTBEASISWAS
group by NM_PERUSAHAAN;');

Using two columns in where Laravel ORM

I have two columns in my table: max and current. I want to build simple scope
public function scopeNotMax($query)
{
return $query->where('max', '>', 'current');
}
But Laravel gives me that query:
SELECT * FROM table WHERE `max` > 'current'
I don't want this result and I know that I can use in this place whereRaw() or DB::raw(). But I can't find another way to say "hey, this is column, not string!'. Can I do it? Or I must use raws? I want to avoid it.
There is no other way.
where() method in this case add third parameter (value) to bindings and passes it ot PDO library. So it will be escaped.
Alternatively You can pass as third parameter a Closure, but then laravel will form a sub-select for You, which doesn't helps much.
Looks like whereRaw() is made for this kind of sitiuation.
Did you give a try with this ? return $query->where('max > current');
you can use whereRaw():
->whereRaw('table_1.name = table_2.name');
You exmaple code:
->whereRaw('max>current');

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.

Using DB::select() in Laravel with LIKE clause and a variable column name

In the docs,
$results = DB::select('select * from users where id = ?', array(1));
The Problem
I have a variable $column and $value and I want them to search the database based on what column like this:
$results = DB::select('select * from users where ? LIKE "%?%"', array($column, $value));
But this throws an error:
SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter $2 (SQL: SELECT * FROM test WHERE refno LIKE '%te%')
I tried hard-coding the value like this:
$results = DB::select('select * from users where ? LIKE "%te%"', array($column));
but it returns a blank array.
How do I do this? Please help.
EDIT:
The query is actually long (with multiple joins). So I prefer not to use the Query Builder style if possible. But if it's not possible, then I will just use Query Builder.
Info:
Laravel v4.2
PostgreSQL
It could be done in more Query Builder style, like that:
$results = DB::table('users')
->where($column, 'LIKE', '%' . $value . '%')
->get();
EDIT
The only reliable way how to do it with DB::select() is:
$results = DB::select("select * from users where ? LIKE '%?%'", array($column, $value));
It produces the right query, I checked it against the database, but also a blank array, or wrong results. Even if this method somehow worked, you still have to escape table and columns names manually, which is tedious and apparently does not work with ?. If you lets say had a $column named values this method would break, since values is a reserved word (at least in MySQL).
The Query Builder method is highly advised, because it also automatically adds SQL escapes to table and column names. Also it is is more portable across DB drivers. It also supports joins with ease. No need to use the method you wants.
the only way i find working
$phone = '%'.$phone.'%';
$seachbyphone = DB::select('SELECT * FROM user WHERE phoneno LIKE ?',[$phone]);
try this:
use App\User; //don't forget add this to header
$result = User::where('columnName', 'LIKE', "%$value%")->get();
LIKE '%?%'" is incorrect. It must be ? only as sql query only expects ? =>vacancy/placeholder for value. Not any single comma or wildcard.
So You need to add % sign with value not with ? =>(placeholder), and its safe as well.
That's why we need
$results = DB::select("select * from users where ? LIKE ?, [$column, '%'.$value.'%'.]);
I would not recommend DB::select() to anyone, even though you have perfectly valid SQL that works directly in the database engine Laravel produces peculiar errors with made-up error descriptions. Instead use DB::table('my_table')->select('...') instead.

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