Get a list of database statements executed in Laravel API - laravel

To see if there's an n + 1 problem in my Laravel API, I want to see how many and which query statements were executed.
I use barryvdh/laravel-debugbar to see the query statements on web.php routes but this doesn't provide me the wanted info on api.php routes.

You can create a ServiceProvider that "listens" to all the queries being executed. You can print them on screen, write them to a log file, whatever you want.
Check https://laravel.com/docs/8.x/database#listening-for-query-events for the docs on Laravel 8.
Literal copy/paste example from the docs:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
DB::listen(function ($query) {
// Print it, log it, whatever :)
// $query->sql
// $query->bindings
// $query->time
});
}
}

Related

How to overcome repeative blade component queries in laravel

As in laravel we make blade component to reuse that on multiple pages. so for example we have a cardcomponent that has a query in render function
User::count();
and we use that card component on almost every page so whenever a page is loaded the above query is executed again and again. is there a way to overcome it?
You can put the query in the AppServiceProvider as shown in the documentation here https://laravel.com/docs/9.x/views#sharing-data-with-all-views. The result will be available in all views and the query should only be executed once.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
View::share('key', 'value');
}
}
Alternatively you can use a blade component: https://laravel.com/docs/9.x/blade#components

How can I get the ID of logged in user and use it in my AppServiceProvider file in Laravel 7?

I'm working on my application using Laravel 7. I have used View Composer in my AppServiceProvider to get the count for a number of items in my database table. I have used where clause to get count for a specific logged in user. The problem is that I'm not sure how I can get the ID of currently logged in User and use in my AppServiceProvider. I have tried doing it but I'm getting Undefined variable: userId error. Please help. Thanks.
AppServiceProvider:
<?php
namespace App\Providers;
use App\Models\Project;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Auth;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
$userId = Auth::id();
View::composer('client_panel.layouts.menu', function ($view) {
$view->with('newprojects', Project::where([
['status','=','1'],
['created_by','=', $userId]
])->count());
});
}
}
The error is because of , you cant call outside variable directly inside callback's. So you have to pass using use params. function ($view)($userId){
But I don't think auth user will available in service provider's So
call inside View composer.
View::composer('client_panel.layouts.menu', function ($view) {
$view->with('newprojects', Project::where([
['status','=','1'],
['created_by','=',Auth::user()->id]
])->count());
});

DB::enableQueryLog() return undifiend method

I want to log query and get it's sql so I tried:
DB::enableQueyLog();
Auth::user()->books();
dd(DB::getQueryLog());
but I get error:
Call to undefined method Illuminate\Database\MySqlConnection::enableQueyLog()"
also tried what suggested in laravel 5.8 docs but nothing get output to screen and when I open the log file there is no sql in it.
please how to log the query and get it is raw sql?
Update:
I have tried to do the following:
in AppServiceProvider.php
namespace App\Providers;
use Illuminate\Support\Facades\File;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\DB;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
//
DB::listen(function ($query) {
$query->sql;
$query->bindings;
// $query->time
});
}
}
and in my controller:
Auth::user()->books();
dd(DB::getQueryLog());
now I get:
[]
and no sql command that is executed.
please kindly help me
You misspelled the method name.
DB::enableQueryLog();
Please first enable query log using below code
DB::connection()->enableQueryLog();
then after you can use below method
$queries = DB::getQueryLog();

Problems creating a ComposerServiceProvider in Laravel 5.4

Im working on a Laravel 5 app and im trying to set up a ComposerServiceProvider to pass data to a couple of views (im trying now to add it to the layout/app.blade.php).
I did this following the documentation but the data im trying to add is still undefined..
In my config/app.php I added to the providers:
App\Providers\ComposerServiceProvider::class,
On ComposerServiceProvider.php
boot method:
View::composer(['layouts.app'], 'App\ViewComposers\LayoutAppComposer');
On the new created LayoutAppComposer.php
compose(View $view) method:
$metaTitle = 'MetaTitle';
$view->with('metaTitle', $metaTitle)
But When i access the url I still get:
Undefined variable: metaTitle (View: .../resources/views/layouts/app.blade.php)
Am I missing something here??
ServiceProvider
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
View::composer(['layouts.app'], 'App\ViewComposers\LayoutAppComposer');
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
}
}
LayoutAppComposer
<?php
namespace App\ViewComposers;
use Illuminate\Support\Facades\Session;
use Illuminate\View\View;
class LayoutAppComposer {
protected $metaTitle;
public function __construct($metaTitle)
{
$this->metaTitle = $metaTitle;
}
/**
* Bind data to the view.
*
* #param View $view
* #return void
*/
public function compose(View $view) {
$this->metaTitle = 'MetaTitle';
$view->with('metaTitle', $this->metaTitle);
}
}
Try changing:
$metaTitle = 'MetaTitle';
$view->with('metaTitle', $metaTitle)
to
$this->metaTitle = 'metaTitle';
$view->with('metaTitle', $this->metaTitle)
setup $this->metaTitle as a protected class member and assign it in the composer constructor. it may be that $metaTitle is getting garbage collected before you use it since this being resolved at the service provider level.
Since you're registering the composer with your app layout, instead you may need to use the wildcard character in place of app.layout like such:
View::composer('*', function ($view) {
//
});
To resolve $metaTile for the View Composer, try binding in your AppServiceProvider:
$this->app->bind('metaTitle', 'the string i want displayed across all views');

Laravel Architecture - Event vs. Controller

My question is related more about the architecture of an Laravel application. I'm developing an application and I have some problems about the positioning of my codes. Let's assume I have a controller to control the comments of my post, but now, after a while, I need to add an action each time a comment is registered, in this case, I create an event or simply add this new action to my controller action?
Thank you.
As Bogdan's says, you should read Model Events.
A sample approach could be the next.
Create a service provider:
php artisan make:provider CommentServiceProvider
Then a sample CommentServiceProvider class:
<?php
namespace App\Providers;
use App\Comment;
use Illuminate\Support\ServiceProvider;
class CommentServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Comment::creating(function ($comment) {
//... do stuff here
});
}
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
}
}

Resources