I have the following function that does not work and I'm having the hardest time trying to figure it out. I'm 12 and just learning, so forgive me:
function get_answer() {
$answer = $this->db->query("SELECT COUNT(questions) FROM possible_quest WHERE questions='something'");
return $answer;
}
When I run the following SQL query in phpmyadmin, it returns the expected result
SELECT COUNT(questions) FROM possible_quest WHERE questions='something'
How do I get this working in CodeIgniter using my function above?
The PHP error I get is
A PHP Error was encountered
Severity: 4096
Message: Object of class CI_DB_mysql_result could not be converted to string
Could be:
function get_answer()
{
$query = $this->db->query("SELECT COUNT(questions) AS count FROM possible_quest WHERE questions='something'");
$count = $query->row(); // returns an object of the first row
return $count->count;
// OR
$count = $query->row_array(); // returns an asociative array of the result
return $count['count'];
}
Another thing: if you want to pass 'something' as a variable, you can use parametrized query, like
$sql = "SELECT COUNT(questions) AS count FROM possible_quest WHERE questions = ?";
$query = $this->db->query($sql, array($something));
which has the benefit of escaping automatically your variable, so you don't worry about sql injections.
You need to setup to the count.
Heres what you need to do is
$answer = $this->db->query("SELECT COUNT(questions) as count FROM possible_quest WHERE questions='something'")->first_row()->count;
//$answer is now setup to be count
One line. Thats the beauty of CI
You're getting that error because
return $answer;
should be
return $answer->result();
The error you are getting is related to the fact that $this->db->query returns a result object, so you cannot use $answer directly as a string.
I suggest that you use print_r($answer) to see what could be going wrong with your conversion of objects to strings, if you have such a function in your model.
CodeIgniter has functions for building queries and returning the count:
function get_answer() {
$this->db->from("possible_quest");
$this->db->where("questions", "something");
return $this->db->count_all_results();
}
NOTE: The name of the function 'get_answer' doesn't match what you're actually doing. It looks like you're getting a count of questions, not an answer, so you should name it to something that makes more sense, like 'get_question_count'.
I recommend you to use an Active Record with method chaining when possible:
public function getAnswer() {
return
$this->db->
select('id')->
where('questions', 'something')->
get('possible_quest')->row()->count
;
}
or
public function getAnswer() {
return
$this->db->
select('id')->
from('possible_quest')->
where('questions', 'something')->
get()->row()->count
;
}
It's secure, easy to use, easy to understand and read. Don't listen to people saying that a single-line code is something good because a good code should be readable.
Related
How can i get mysql query of a laravel query
Convert:
App\User::where('balance','>',0)->where(...)->get();
To:
SELECT * FROM users WHERE `balance`>0 and ...
use toSql() method of laravel to get the query to be executed like
App\User::where('balance','>',0)->where(...)->toSql();
But Laravel will not show you parameters in your query, because they are bound after preparation of the query. To get the bind parameters, use this
$query=App\User::where('balance','>',0)->where(...);
print_r($query->getBindings() );
enable the query log as DB::enableQueryLog() and then output to the screen the last queries ran you can use this,
dd(DB::getQueryLog());
you can add this function to your helpers
function getRealQuery($query, $dumpIt = false)
{
$params = array_map(function ($item) {
return "'{$item}'";
}, $query->getBindings());
$result = str_replace_array('\?', $params, $query->toSql());
if ($dumpIt) {
dd($result);
}
return $result;
}
and use like this:
getRealQuery(App\User::where('balance','>',0)->where(...),true)
Method 1
To print a single query, use toSql() method of laravel to get the query to be executed like
App\User::where('balance','>',0)->where(...)->toSql();
Method 2
Laravel can optionally log in memory all queries that have been run for the current request. But in some cases, such as when inserting a large number of rows, this can cause the application to use excess memory, so you should avoid this.
To enable the log, you may use the enableQueryLog method as
DB::connection()->enableQueryLog();
To get an array of the executed queries, you may use the getQueryLog method as
$queries = DB::getQueryLog();
you can get more details here Laravel Enable Query Log
Method 3
Another approach to display all queries used in Laravel without enabling the query log install the LaravelDebugBar from here Laravel Debug Bar.
It is a package that allows you to quickly and easily keep tabs on your application during development.
To print the raw sql query, try:
DB::enableQueryLog();
// Your query here
$queries = DB::getQueryLog();
print_r($queries);
Reference
Here is a helper function who tells you the last SQL executed.
use DB;
public static function getLastSQL()
{
$queries = DB::getQueryLog();
$last_query = end($queries);
// last_query is the SQL with with data binding like
// {
// select ? from sometable where field = ? and field2 = ? ;
// param1,
// param2,
// param3,
// }
// which is hard to read.
$last_query = bindDataToQuery($last_query);
// here, last_query is the last SQL you have executed as normal SQL
// select param1 from sometable where field=param2 and field2 = param3;
return $last_query
}
Here is the bindDataToQuery function, who fill the '?' blanks with real params.
protected static function bindDataToQuery($queryItem){
$query = $queryItem['query'];
$bindings = $queryItem['bindings'];
$arr = explode('?',$query);
$res = '';
foreach($arr as $idx => $ele){
if($idx < count($arr) - 1){
$res = $res.$ele."'".$bindings[$idx]."'";
}
}
$res = $res.$arr[count($arr) -1];
return $res;
}
It is so strange that the laravel haven't support any way to get the raw sql easily, it is now version 6 after all...
Here's a workaround I used by myself to quickly get the raw sql with parameters without installing any extension...
Just deliberately make your original sql WRONG
Like change
DB::table('user')
to
DB::table('user1')
where the table "user1" does not exist at all!
Then run it again.
Sure there will be an exception reported by laravel.
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'user1' doesn't exist (SQL: ...)
And now you can see the raw sql with parameters is right after the string "(SQL:"
Change back from the wrong table name to the right one and there you go!
In Laravel 5.4 (I didn't check this in other versions), add this function into the
"App"=>"Providers"=>"AppServiceProvider.php" .
public function boot()
{
if (App::isLocal()) {
DB::listen(
function ($sql) {
// $sql is an object with the properties:
// sql: The query
// bindings: the sql query variables
// time: The execution time for the query
// connectionName: The name of the connection
// To save the executed queries to file:
// Process the sql and the bindings:
foreach ($sql->bindings as $i => $binding) {
if ($binding instanceof \DateTime) {
$sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
} else {
if (is_string($binding)) {
$sql->bindings[$i] = "'$binding'";
}
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);
$query = vsprintf($query, $sql->bindings);
// Save the query to file
/*$logFile = fopen(
storage_path('logs' . DIRECTORY_SEPARATOR . date('Y-m-d') . '_query.log'),
'a+'
);*/
Log::notice("[USER] $query");
}
);
}
}
After that install,
https://github.com/ARCANEDEV/LogViewer
and then you can see every executed SQL queries without editing the code.
To get mysql query in laravel you need to log your query as
DB::enableQueryLog();
App\User::where('balance','>',0)->where(...)->get();
print_r(DB::getQueryLog());
Check reference : https://laravel.com/docs/5.0/database#query-logging
Instead of interfering with the application with print statements or "dds", I do the following when I want to see the generated SQL:
DB::listen(function ($query) {
Log::info($query->sql, $query->bindings);
});
// (DB and Log are the facades in Illuminate\Support\Facades namespace)
This will output the sql to the Laravel log (located at storage/logs/laravel.log). A useful command for following writes to this file is
tail -n0 -f storage/logs/laravel.log
A simple way to display all queries used in Laravel without any code changes at all is to install the LaravelDebugBar (https://laravel-news.com/laravel-debugbar).
As part of the functionality you get a tab which will show you all of the queries that a page has used.
Try this:
$results = App\User::where('balance','>',0)->where(...)->toSql();
dd($results);
Note: get() has been replaced with toSql() to display the raw SQL query.
A very simple and shortcut way is below
Write the name of column wrong like write 'balancedd' in spite of 'balance' and the query will be displayed on error screen when you execute code with all the parameters and error that column not found.
DB::enableQueryLog();
(Query)
$d= DB::getQueryLog(); print"<pre>"; print_r ($d); print"</pre>";
you will get the mysql query that is just run.
There is actually no such thing in Laravel and even PHP, since PHP internally sends the parameters with query string to the database where it (possibly) become parsed into raw query string.
The accepted answer is actually optimistic solution, kind of "optionally works".
This is the one thing that I am trying absolutely first time. I have made few websites in PHP and MySQL as DB but never used functions to get data from database.
But here is the thing that I am trying all new now as now I want to achieve reusability for a bog project. I wanted to get the order details from DB (i.e. MySQL) through PHP Function. I am bit confused that how to print values returned by a PHP function.
Function wrote by me is as below:
function _orderdetails(){
$sql = "Select * from orders WHERE 1";
$result = DB::instance()->prepare($sql)->execute()->fetchAll();
return $result;
}
Please let me know how i can print these values and value returned by above function is an array.
I tried by calling function directly through print_r(_orderdetails());
Please let me know:
Efficient way of iterating through this function to Print Values.
Is there any other approach that can be better worked upon?
You cannot chain fetchAll() to execute() like this.
Besides, for a query that takes no parameters, there is no point in using execute(). So change your function like this
function _orderdetails(){
$sql = "Select * from orders WHERE 1";
return DB::instance()->query($sql)->fetchAll();
}
and so you'll be able to iterate results the most natural way
foreach (_orderdetails() as $order) {
echo $order['id'] . '<br />';
}
You can also use ->fetch();
Instead of ->fetchAll();
There some other functions that also work as a worker to iterate through the next row in the table.
You can check PDO for more functions at:
http://php.net/manual/en/book.pdo.php
In your PHP code that will call this function use the following
print_r(_orderdetails());
//to get all the result set... I mean all the values coming from this function.
You can also use the function and use -> after the function call, then put the variable name as follows:
To iterate through the values of this function:
$value_arr = _orderdetails();
foreach ($valur_arr as $value) {
echo $value . '<br />';
}
This way you will echo 1 column from the database table you are using.
Hi I'm new to CodeIgniter and I just want to know How will I query from my MySql Db, a Select Statement with a where clause, I know it can be searched from the net but whenever I try something I get errors, It's really frustrating. The string in the Where clause will be coming from a User Input. Thanks guys!
You can do as Mehedi-PSTU stated, however it seems as though you're a little new to this, so here's some extra information:
I'll copy Mehedi-PSTU for the most part here.
$this->get->where('column_name', $equals_this_variable);
$query = $this->db->get('table_name');
This will store the query object in the variable $query.
if you wanted to convert that to a usable array, you just perform to following.
$results = $query->result_array();
Or you can loop through it like this:
foreach($query->result_array() as $result){
// Perform some task here.
}
A better or even full understanding can probably come from:
http://ellislab.com/codeigniter/user-guide/database/active_record.html
Try something like this
$this->db->where('db_attr', $var);
return $this->db->get('table');
Try this one.
$id = 'your id';
$this->db->select("*");
$this->db->from("table_name");
$this->db->where('id','$id');
$query = $this->db->get();
return $query->result_array();
In Codeigniter with Method Chaining Style :-
$data['getData'] = $this->db->get_where('table_name',array('column_name'=>$var))->result_array();
In Zend app, I use Zend\Db\TableGateway and Zend\Db\Sql to retrieve data data from MySQL database as below.
Model -
public function getCandidateEduQualifications($id)
{
$id = (int) $id;
$rowset = $this->tableGateway->select(function (Sql\Select $select) use ($id)
{
$select->where
->AND->NEST->equalTo('candidate_id', $id)
->AND->equalTo('qualification_category', 'Educational');
});
return $rowset;
}
View -
I just iterate $rowset and echo in view. But it gives error when try to echo two or more times. Single iteration works.
This result is a forward only result set, calling rewind() after
moving forward is not supported
I can solve it by loading it to another array in view. But is it the best way ? Is there any other way to handle this ?
$records = array();
foreach ($edu_qualifications as $result) {
$records[] = $result;
}
EDIT -
$resultSet->buffer(); solved the problem.
You receive this Exception because this is expected behavior. Zend uses PDO to obtain its Zend\Db\ResultSet\Resultset which is returned by Zend\Db\TableGateway\TableGateway. PDO result sets use a forward-only cursor by default, meaning you can only loop through the set once.
For more information about cursors check Wikipedia and this article.
As the Zend\Db\ResultSet\Resultset implements the PHP Iterator you can extract an array of the set using the Zend\Db\ResultSet\Resultset:toArray() method or using the iterator_to_array() function. Do be careful though about using this function on potentially large datasets! One of the best things about cursors is precisely that they avoid bringing in everything in one go, in case the data set is too large, so there are times when you won't want to put it all into an array at once.
Sure, It looks like when we use Mysql and want to iterate $resultSet, this error will happen, b/c Mysqli only does
forward-moving result sets (Refer to this post: ZF2 DB Result position forwarded?)
I came across this problem too. But when add following line, it solved:
$resultSet->buffer();
but in this mentioned post, it suggest use following line. I just wonder why, and what's difference of them:
$resultSet->getDataSource()->buffer();
This worked for me.
public function fetchAll()
{
$select = $this->tableGateway->getSql()->select();
$resultSet = $this->tableGateway->selectWith($select);
$resultSet->buffer();
$resultSet->next();
return $resultSet;
}
$sql = new Zend\Db\Sql($your_adapter);
$select = $sql->select('your_table_name');
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
$resultSet = new ResultSet();
$resultSet->initialize($results);
$result = $resultSet->toArray();
I have the following problem:
public function row2Partner($row){
echo $row->PartnerID;
}
public function main(){
$query = "SELECT PartnerID, PartnerName FROM Partner";
$result = mysql_query($query);
$this->row2Partner(mysql_fetch_object($result));
}
This gives me the error in row2Partner():
Trying to get property of non-object
But $row is an Object! And if I do
echo $row->PartnerID in the main function, it works.
Any ideas?
Thx,
Martin
If your result returns more than one row, your object is going to be multi-dimensional. I'm pretty sure you can do something like this if you just want to echo the first one:
public function row2Partner($row){ echo $row[0]->PartnerID; }
If you are looking for only one result, I would also limit my query to just one...
SELECT PartnerID, PartnerName FROM Partner LIMIT 1
If you want to echo out all your rows (in the case of multiple) results, you can do this:
public function row2Partner($row){
foreach($row as $result) {
echo $result->PartnerID;
}
}
Hope that helps.
PS
Just as a sidenote, I tend to like to use associative arrays when dealing with MySQL results--it just makes more sense to me. In this case, you would just do this instead:
mysql_fetch_assoc($result)
Are you sure that mysql_query() has executed the query successfully, and also that there is actually a row being returned? It might be worth checking it, e.g.
//check query executed ok
if ($result = mysql_query($query)) {
//check there is actually a row
if ($row = mysql_fetch_object($result)) {
$this->row2Partner($row);
} else {
//no data
}
} else {
//error
die(mysql_error());
}
Best thing I can think of is that you may need to pass by reference rather than by value. Change your function declaration to
public function row2Partner(&$row)
Hope that helps,
David