Background:
Inside large controllers I will have a number of different functions being called, to create a user, to update their order, to schedule in an event. Each of these operations are handled by a function in the model layer... here is an example of one of those functions:
$user_id = 1;
$data = array('name' => 'Billy');
if (updateUser($user_id, $data) === false) {
// handle error?
}
// continue with rest of controller
Problem:
I finally took a reality check today and realised that I have no good reason for coding like this...
If updateUser() returns false then something has seriously gone wrong with my Database Abstraction Layer that has prevented me from updating data in my database. This should never happen and therefore there are no practical errors to show my users anyway (that would allow them to take appropriate actions).
Basically my app is fundamentally broken at that point.
Question:
Should I bother to check functions that should never return false? If so how? Or should I just call them like this without any checks?
updateUser($foo)
createBooking($bar)
scheduleEvent($qux)
When something happens inside a function that should never happen, throw an exception.
And then you can handle (catch) all exceptions where you want to do that. For example by showing a friendly message to the user and logging all details for yourself so that you know what went wrong and where.
Then you can get rid of the if statements and only use these when there are valid / normal options.
I have a problem, when I try to run this function in my model it does nothing. The print statement prints out.
DELETE FROM child_participantsWHERE Child_Name='test'
andParent_username='tester2'
Which when I run from command line works correctly(the record exists and is deleted). But when I try it from my web application it gives me no error but does not actually delete anything. I know i am passing data correctly because I receive it in my controller and model. What gives?
function remove_child($username, $participant_name)
{
$where = "`Child_Name`='$participant_name' and`Parent_username`='$username'";
$this->db->where($where, null, false);
$this->db->delete($this->child_table);
echo $this->db->last_query();
}
From the documentation:
If you use multiple function calls they will be chained together with AND between them:
Try changing:
$where = "`Child_Name`='$participant_name' and`Parent_username`='$username'";
to
$this->db->where('Child_Name', $participant_name);
$this->db->where('Parent_username', $username);
// translates to WHERE Child_Name='XXX' and Parent_username='XXX'
Hope this helps!
Do you get the same results when you break it out into two where method calls? I would do this over how you are using the where method.
$this->db->where('Child_Name',$participant_name);
$this->db->where('Parent_username',$username);
$this->db->delete($this->child_table);
also, turn on the profiler to see all the queries that are being run to make sure there are not other parts of code we cannot see that might be interfering or a transaction not being committed
$this->output->enable_profiler(TRUE);
Another suggestion is the practice of soft deletes so that way your data is not truly gone and also minimizes how much you need to rely on reconstructing your log file. Also to make simple CRUD operations faster you can use a very simple extension of the base model. One that I have used by recommendation is https://github.com/jamierumbelow/codeigniter-base-model
Check that does your user has delete privilege in the database. if it has than change your
code like this:
function remove_child($username, $participant_name)
{
$this->db->trans_start();
$this->db->where('Child_Name',$participant_name);
$this->db->where('Parent_username',$username);
$this->db->delete($this->child_table);
$this->db->trans_complete();
return TRUE;
}
i hope that this will solve your problem.
I am working on vtiger customization.
I changed the UI but i want to know where the mysql query executes.
Is there any common function to execute all query?.
I got one function which call by all pages that is $this->database->Execute($sql);
can anyone tell me the exact function of query or how the flow works.
Thanks in advance
Queries in vtiger may go through different pathes, but if you use mysql, the last place of all is:
{path of Vtiger}\adodb\drivers\adodb-mysql.inc.php
function _query($sql,$inputarr)
You can even log all queries
function _query($sql,$inputarr)
{
$hl = fopen("my_log.sql","a+");
fwrite($hl, "--------"."\n".$sql."\n");
fclose($hl);
return mysql_query($sql,$this->_connectionID);
}
my_log.sql will be created in vtiger root directory. Also vtiger has it's own log, but I prefer mine.another points to mention:
Mainly vtiger uses it built-in function named pquery. I suggest do not
go through this function to understand it. Most of the times the chain of a called pquery function has more than 3 members. But I think it worth to
find out how it does the queries. Simply you write the inputs an
pquery does the job!
How can I retrieve the raw executed SQL query in Laravel 3/4 using Laravel Query Builder or Eloquent ORM?
For example, something like this:
DB::table('users')->where_status(1)->get();
Or:
(posts (id, user_id, ...))
User::find(1)->posts->get();
Otherwise, at the very least how can I save all queries executed to laravel.log?
Laravel 4+
Note for Laravel 5 users: You'll need to call DB::enableQueryLog() before executing the query. Either just above the line that runs the query or inside a middleware.
In Laravel 4 and later, you have to call DB::getQueryLog() to get all ran queries.
$queries = DB::getQueryLog();
$last_query = end($queries);
Or you can download a profiler package. I'd recommend barryvdh/laravel-debugbar, which is pretty neat. You can read for instructions on how to install in their repository.
Laravel 3
In Laravel 3, you can get the last executed query from an Eloquent model calling the static method last_query on the DB class.
DB::last_query();
This, however, requires that you enable the profiler option in application/config/database.php. Alternatively you could, as #dualed mentioned, enable the profiler option, in application/config/application.php or call DB::profile() to get all queries ran in the current request and their execution time.
You can enable the "Profiler" in Laravel 3 by setting
'profiler' => true,
In your application/config/application.php and application/config/database.php
This enables a bar at the bottom of each page. One of its features is listing the executed queries and how long each one took.
For Eloquent you can just do:
$result->getQuery()->toSql();
But you need to remove the "->get()" part from your query.
I would recommend using the Chrome extension Clockwork with the Laravel package https://github.com/itsgoingd/clockwork. It's easy to install and use.
Clockwork is a Chrome extension for PHP development, extending
Developer Tools with a new panel providing all kinds of information
useful for debugging and profiling your PHP scripts, including
information on request, headers, GET and POST data, cookies, session
data, database queries, routes, visualisation of application runtime
and more. Clockwork includes out of the box support for Laravel 4 and
Slim 2 based applications, you can add support for any other or custom
framework via an extensible API.
Since the profiler is not yet out in Laravel 4, I've created this helper function to see the SQL being generated:
public static function q($all = true)
{
$queries = DB::getQueryLog();
if($all == false) {
$last_query = end($queries);
return $last_query;
}
return $queries;
}
NOTE: Set the $all flag to false if you only want the last SQL query.
I keep this sort of functions in a class called DBH.php (short for Database Helper) so I can call it from anywhere like this:
dd(DBH::q());
Here is the output I get:
In case you are wondering, I use Kint for the dd() formatting.
http://raveren.github.io/kint/
For Laraver 4 it's
DB::getQueryLog()
Here is a quick Javascript snippet you can throw onto your master page template.
As long as it's included, all queries will be output to your browser's Javascript Console.
It prints them in an easily readable list, making it simple to browse around your site and see what queries are executing on each page.
When you're done debugging, just remove it from your template.
<script type="text/javascript">
var queries = {{ json_encode(DB::getQueryLog()) }};
console.log('/****************************** Database Queries ******************************/');
console.log(' ');
queries.forEach(function(query) {
console.log(' ' + query.time + ' | ' + query.query + ' | ' + query.bindings[0]);
});
console.log(' ');
console.log('/****************************** End Queries ***********************************/');
</script>
Laravel 5
Note that this is the procedural approach, which I use for quick debugging
DB::enableQueryLog();
// Run your queries
// ...
// Then to retrieve everything since you enabled the logging:
$queries = DB::getQueryLog();
foreach($queries as $i=>$query)
{
Log::debug("Query $i: " . json_encode($query));
}
in your header, use:
use DB;
use Illuminate\Support\Facades\Log;
The output will look something like this (default log file is laravel.log):
[2015-09-25 12:33:29] testing.DEBUG: Query 0: {"query":"select * from
'users' where ('user_id' = ?)","bindings":["9"],"time":0.23}
***I know this question specified Laravel 3/4 but this page comes up when searching for a general answer. Newbies to Laravel may not know there is a difference between versions. Since I never see DD::enableQueryLog() mentioned in any of the answers I normally find, it may be specific to Laravel 5 - perhaps someone can comment on that.
You can also listen for query events using this:
DB::listen(function($sql, $bindings, $time)
{
var_dump($sql);
});
See the information from the docs here under Listening For Query Events
Using the query log doesnt give you the actual RAW query being executed, especially if there are bound values.
This is the best approach to get the raw sql:
DB::table('tablename')->toSql();
or more involved:
$query = Article::whereIn('author_id', [1,2,3])->orderBy('published', 'desc')->toSql();
dd($query);
If you are using Laravel 5 you need to insert this before query or on middleware :
\DB::enableQueryLog();
Or as alternative to laravel 3 profiler you can use:
https://github.com/paulboco/profiler
or
https://github.com/barryvdh/laravel-debugbar
in Laravel 4 you can actually use an Event Listener for database queries.
Event::listen('illuminate.query', function($sql, $bindings)
{
foreach ($bindings as $val) {
$sql = preg_replace('/\?/', "'{$val}'", $sql, 1);
}
Log::info($sql);
});
Place this snippet anywhere, e.g. in start/global.php. It'll write the queries to the info log (storage/log/laravel.log).
Event::listen('illuminate.query', function($sql, $param)
{
\Log::info($sql . ", with[" . join(',', $param) ."]<br>\n");
});
put it in global.php it will log your sql query.
The Loic Sharma SQL profiler does support Laravel 4, I just installed it. The instructions are listed here. The steps are the following:
Add "loic-sharma/profiler": "1.1.*" in the require section
in composer.json
Perform self-update => php composer.phar self-update in the console.
Perform composer update => php composer.phar update loic-sharma/profiler in the console as well
`
Add 'Profiler\ProfilerServiceProvider', in the provider array in
app.php
Add 'Profiler' => 'Profiler\Facades\Profiler', in the
aliasses array in app.php as well
Run php artisan config:publish loic-sharma/profiler in the console
Last query print
$queries = \DB::getQueryLog();
$last_query = end($queries);
// Add binding to query
foreach ($last_query['bindings'] as $val) {
$last_query['query'] = preg_replace('/\?/', "'{$val}'", $last_query['query'], 1);
}
dd($last_query);
L4 one-liner
(which write query):
$q=\DB::getQueryLog();dd(end($q));
Laravel 3
Another way to do this is:
#config/database.php
'profiler' => true
For all Queries result:
print_r(DB::profiler());
For last Result:
print_r(DB::last_query());
To get the last executed query in laravel,We will use DB::getQueryLog() function of laravel it return all executed queries. To get last query we will use end() function which return last executed query.
$student = DB::table('student')->get();
$query = DB::getQueryLog();
$lastQuery = end($query);
print_r($lastQuery);
I have taken reference from http://www.tutsway.com/how-to-get-the-last-executed-query-in-laravel.php.
There is very easy way to do it, from your laravel query just rename any column name, it will show you an error with your query.. :)
In Laravel 8.x you can listen to the event by registering your query listener in a service provider as documented in laravel.com website.
//header
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
public function boot()
{
DB::listen(function ($query) {
Log::debug("SQL : " . $query->sql);
});
}
You can then see all the queries in the laravel.log file inside storage\logs\laravel.log
I want to cache a query in CodeIgniter. What I did for my test is make a controller, that I named show.php:
class Show extends CI_Controller{
public function __construct()
{
parent::__construct();
$this->load->model('rejaal_show');
}
public function _remap($method = '',$param = array())
{
$method = intval($method);
$this->output->cache(5);
var_dump ($this->rejaal_show->temp($method));
}
}
And a model that I named rejaal_show.php:
public function temp($id)
{
$this->db->cache_on();
$this->db->where('id',$id);
$query = $this->db->get('system_store_table');
return $query->result();
}
When I call http://localhost/rejaal/show/1 for the first time, it will show a result, but when I call it for the second time, it does not show anything.
I should delete the query cache file to show it again? How should I solve this problem?
With special thanks for your attention.
Can you confirm that you have set $db['default']['cachedir'] to the path of a writable folder in application/config/database.php and that when the query is first run it creates a cache file in there?
The only other reason I can think of for it failing is by your use of the _remap override. I have not used db caching using _remap, but know that CodeIgniter creates a folder called controller+action in your cache folder, and might not be handled very well if using remap? Someone correct me if I am wrong about this.
In the CodeIgniter User Guide page for Web Page Caching, it says:
Because of the way CodeIgniter stores content for output, caching will only work if you are generating display for your controller with a view.
Do your var_dump inside a view.