কীভাবে লারাভেল 5 এ ক্যুরিয়ারটি কার্যকর করা যায়? ডিবি :: getQueryLog () খালি অ্যারে রিটার্নিং


171

আমি কোনও প্রশ্নের জন্য লগটি দেখার চেষ্টা করছি, তবে DB::getQueryLog()কেবল একটি খালি অ্যারেটি ফিরিয়ে দিচ্ছি :

$user = User::find(5);
print_r(DB::getQueryLog());

ফলাফল

Array
(
)

আমি এই প্রশ্নের জন্য লগ দেখতে পারেন?


ল্যারাভেল ডিবাগবার অনুসন্ধানগুলি লগ করার জন্য দুর্দান্ত সরঞ্জাম। এটিতে আরও অনেক দুর্দান্ত বৈশিষ্ট্য রয়েছে।
টটিমেডলি

উত্তর:


256

ডিফল্টরূপে, কোয়েরি লগটি লারাভেল 5 এ অক্ষম করা হয়েছে: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448

আপনি কল করে ক্যোয়ারী লগ সক্ষম করতে হবে:

DB::enableQueryLog();

বা ইভেন্ট শ্রোতার নিবন্ধন করুন:

DB::listen(
    function ($sql, $bindings, $time) {
        //  $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
        //  $bindings - [5]
        //  $time(in milliseconds) - 0.38 
    }
);  

কিছু টিপস

একাধিক ডিবি সংযোগ

আপনার যদি একাধিক ডিবি সংযোগ থাকে তবে আপনাকে অবশ্যই সংযোগটি নির্দিষ্ট করতে হবে must

এর জন্য ক্যোয়ারী লগ সক্ষম করতে my_connection:

DB::connection('my_connection')->enableQueryLog();

এর জন্য ক্যোয়ারী লগ পাওয়ার জন্য my_connection:

print_r(
   DB::connection('my_connection')->getQueryLog()
);

2. কোয়েরি লগ সক্ষম করতে কোথায়?

এইচটিটিপি অনুরোধের লাইফসাইকের জন্য, আপনি handleকিছু BeforeAnyDbQueryMiddleware মিডলওয়্যারের পদ্ধতিতে ক্যোয়ারী লগ সক্ষম করতে পারেন এবং তারপরে terminateএকই মিডওয়্যারের পদ্ধতিতে সম্পাদিত প্রশ্নগুলি পুনরুদ্ধার করতে পারেন ।

class BeforeAnyDbQueryMiddleware
{
    public function handle($request, Closure $next)
    {
        DB::enableQueryLog();
        return $next($request);
    }

    public function terminate($request, $response)
    {
        // Store or dump the log data...
        dd(
            DB::getQueryLog()
        );
    }
}

কোনও মিডলওয়্যারের চেইন কারিগর কমান্ডগুলির জন্য চলবে না, সুতরাং সি এল এল এক্সিকিউশনের জন্য আপনি artisan.startইভেন্ট শ্রোতার কাছে ক্যোয়ারী লগ সক্ষম করতে পারেন ।

উদাহরণস্বরূপ আপনি এটি bootstrap/app.phpফাইলটিতে রাখতে পারেন

$app['events']->listen('artisan.start', function(){
    \DB::enableQueryLog();
});

3. স্মৃতি

লারাভেল সমস্ত প্রশ্নের স্মৃতিতে রাখে। সুতরাং কিছু ক্ষেত্রে যেমন বিপুল সংখ্যক সারি সন্নিবেশ করানোর সময়, বা প্রচুর অনুসন্ধানের সাথে দীর্ঘমেয়াদী কাজ করার ফলে অ্যাপ্লিকেশনটি অতিরিক্ত মেমরি ব্যবহার করতে পারে।

বেশিরভাগ ক্ষেত্রে আপনার কেবলমাত্র ডিবাগিংয়ের জন্য ক্যোয়ারী লগের প্রয়োজন হবে এবং যদি এটি হয় তবে আমি আপনাকে এটি কেবলমাত্র উন্নয়নের জন্য সক্ষম করার প্রস্তাব দিই।

if (App::environment('local')) {
    // The environment is local
    DB::enableQueryLog();
}

তথ্যসূত্র


6
যদি আপনার সিস্টেম একাধিক ডিবি সংযোগ ব্যবহার করে, আপনাকে এটি নির্দিষ্ট করতে হবে, অন্যথায় এটি খালি অ্যারেটি ফিরে আসতে পারে:\DB::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
ডায়ানা আর

আপনার মন্তব্যটি আপনার উত্তর @ ডায়ানাআর হিসাবে পোস্ট করুন।
নরেন্দ্রসিংহ সিসোদিয়া


এলোভেন্ট "নেমকন্ট্রোলার :: তৈরি ();" বক্তব্য?
রুবান রুজ

2
নোট করুন যে লারাভেল 5.4 এ DB::listenকলব্যাক ফাংশনটির আলাদা স্বাক্ষর রয়েছে। এটি এর মতো আরও: DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
র‌্যাক 1010

45

যদি আপনি সত্যই যত্নবান হন তবে দ্রুত ডিবাগিংয়ের উদ্দেশ্যে প্রকৃত ক্যোয়ারী (শেষ এক রান):

DB::enableQueryLog();

# your laravel query builder goes here

$laQuery = DB::getQueryLog();

$lcWhatYouWant = $laQuery[0]['query']; # <-------

# optionally disable the query log:
DB::disableQueryLog();

বাইন্ডিং সহ পুরো ক্যোয়ারী পেতে একটি চেষ্টা print_r()করুন $laQuery[0]। ( $lcWhatYouWantউপরের ভেরিয়েবলের সাথে ভেরিয়েবলগুলি প্রতিস্থাপন করা হবে ??)

আপনি যদি মূল মাইএসকিএল সংযোগ ব্যতীত অন্য কিছু ব্যবহার করেন তবে আপনার পরিবর্তে এগুলি ব্যবহার করতে হবে:

DB::connection("mysql2")->enableQueryLog();

DB::connection("mysql2")->getQueryLog();

(আপনার সংযোগের নাম যেখানে "mysql2" রয়েছে)


1
যদিও এই কোড যায়? (৫.৪) আমি কন্ট্রোলার, মডেল এবং মিডলওয়্যারের সন্ধান করেছি, ডিবি ত্রুটি হওয়ার আগে এটি কোথায় চালানো হবে তা নিশ্চিত নই।
ব্লেম

কার্যকর হওয়া বন্ধ করে দেওয়া ক্যোয়ারী চালানোর সময় যদি আপনি একটি ত্রুটি পেয়ে থাকেন তবে ত্রুটিটি আপনাকে সমস্যাটি কী তা বলা উচিত। আপনার যদি ত্রুটিগুলি বন্ধ থাকে তবে আপনি ত্রুটি লগ ইন / স্টোরেজ / লগ / লারাভেল বা এর মতো কিছু পরীক্ষা করতে পারেন। (আমি এই মুহুর্তে আমার কম্পিউটারে নেই) আপনি যদি বলছেন যে আমার উত্তরটিতে প্রস্তাবিত কোডটি চালাতে আপনি একটি ত্রুটি পেয়ে যাচ্ছেন তবে নিশ্চিত হয়ে নিন যে আপনি যেখানেই কোড চালাচ্ছেন সেখানে আপনি ডিবি ফ্যাসাদকে অন্তর্ভুক্ত করছেন। আপনি কী করার চেষ্টা করছেন তা নিশ্চিত নন, তবে আপনি উল্লেখ করেছেন এমন বিকল্পগুলির মধ্যে সবচেয়ে সঠিক হিসাবে নিয়ামক মনে হচ্ছে। (আমি সাধারণত পৃথক সহায়ক শ্রেণিতে কোয়েরি চালাচ্ছি)
স্কেয়েট

14

এটি রুটস.এফপি ফাইলটিতে রাখুন:

\Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query) {
    echo'<pre>';
    var_dump($query->sql);
    var_dump($query->bindings);
    var_dump($query->time);
    echo'</pre>';
});

এই পৃষ্ঠায় সোশ্যাল কোড, মিশুরগুই দ্বারা জমা দেওয়া । মন্তব্যে লারাভেল 5.2 এর জন্য আপনি এই ফিক্স-কোডটি পাবেন।


কিছুটা নোংরা, তবে $ ক্যোয়ারী-> বাইন্ডিংগুলি এবং $ ক্যোয়ারী-> টাইম ইঙ্গিতগুলির জন্য +1
পাওলো স্টেফান

ঝরঝরে! এটি ব্যবহার করে ফলাফলটি ভিউতে দেখায়, ঠিক যেখানে ক্যোয়ারী ঘটছে!
চার্লস উড

14

আপনাকে প্রথমে ক্যোয়ারী লগিং সক্ষম করতে হবে

DB::enableQueryLog();

তারপরে আপনি সহজভাবে ক্যোয়ারী লগগুলি পেতে পারেন:

dd(DB::getQueryLog());

অ্যাপ্লিকেশন শুরুর আগে আপনি ক্যোয়ারী লগিং সক্ষম করে রাখুন, এটি আপনি মিমডওয়ারওয়্যারের আগে করতে পারেন এবং আফটারমিডলওয়ারে চালিত ক্যোয়ারীগুলি পুনরুদ্ধার করতে পারলে ভাল হয়।


11

স্পষ্টতই লারাভেল 5.2 এর সাথে বন্ধটি DB::listenকেবলমাত্র একটি একক প্যারামিটার গ্রহণ করে।

সুতরাং, আপনি যদি DB::listenলারাভেল 5.2 এ ব্যবহার করতে চান তবে আপনার কিছু করা উচিত:

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+'
        );
        fwrite($logFile, date('Y-m-d H:i:s') . ': ' . $query . PHP_EOL);
        fclose($logFile);
    }
);

পুরোনো Laravel জন্য, আমি আমার সমাধান যোগ stackoverflow.com/a/44920198/3823826
Csongor Halmai


5

পছন্দ মত toSql()পরিবর্তে ব্যবহার করুন get():

$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from `users` order by `name` asc'

2

(ল্যারাভেল ৫.২) আমি খুঁজে পাচ্ছি যে সহজ উপায় হল স্ক্যালের অনুসন্ধানগুলি নিরীক্ষণের জন্য একটি কোড লাইন যুক্ত করা:

\DB::listen(function($sql) {var_dump($sql); });

1

স্পষ্টতই লারাভেল ৫.২ দিয়ে অবিরত অবস্থায়, ডিবিতে বন্ধ হওয়া: শুনুন কেবলমাত্র একটি একক প্যারামিটার পাওয়া যায় ... উপরের প্রতিক্রিয়া: আপনি এই কোডটি মিডওয়্যারের স্ক্রিপ্টে রেখে এই রুটগুলিতে ব্যবহার করতে পারেন।

উপরন্তু:

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('sql');
$log->pushHandler(new StreamHandler(storage_path().'/logs/sql-' . date('Y-m-d') . '.log', Logger::INFO));

// add records to the log
$log->addInfo($query, $data);

মিডওয়্যারের মধ্যে কোন অংশ স্থাপন করা উচিত? কোন পথে?
ব্যবহারকারী 1016265

1

এই কোডটি এর জন্য:

  • লারাভেল 5.2
  • মাইএসকিএল ডাটাবেসে স্টেটমেন্টগুলি লগ ইন করুন

এখানে কোডটি দেওয়া হয়েছে, যা @ মিলজের উত্তরের উপর ভিত্তি করে:

    DB::listen(function($sql) {
        $LOG_TABLE_NAME = 'log';
        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);
        if(stripos($query, 'insert into `'.$LOG_TABLE_NAME.'`')===false){
            $toLog = new LogModel();
            $toLog->uId = 100;
            $toLog->sql = $query;
            $toLog->save();
        }
    });

মূলটি হ'ল if(stripos...লাইন, যা insert into logডাটাবেসে স্ক্যাল স্টেটমেন্ট সন্নিবেশ করানো পুনরুদ্ধার করে।


0

আমি মনে করি এই নিবন্ধটিতে উত্তরটি রয়েছে: https://arjunphp.com/laravel-5-5-log-eloquent-queries/

ক্যোয়ারী লগিং অর্জনের জন্য দ্রুত এবং সহজ।

যদি আপনার ইচ্ছা হয় যোগ আছে AppServiceProviderমধ্যে bootপদ্ধতি একটি কলব্যাক ডিবি প্রশ্নের শোনার জন্য:

namespace App\Providers;

use DB;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        DB::listen(function($query) {
            logger()->info($query->sql . print_r($query->bindings, true));
        });
    }
}

0

মনে করুন আপনি নীচের বিবৃতিগুলির এসকিউএল কোয়েরিটি মুদ্রণ করতে চান।

$user = User::find(5);

আপনার কেবল নিম্নলিখিত হিসাবে করা দরকার:

DB::enableQueryLog();//enable query logging

$user = User::find(5);

print_r(DB::getQueryLog());//print sql query

এটি লারাভেলে শেষ সম্পাদিত ক্যোয়ারী প্রিন্ট করবে।


-3

লারাভেল 5 এর পরে এবং কেবলমাত্র ডিবি :: getQueryLog () ব্যবহার করে, তা করবে না। এর মান দ্বারা ডিফল্ট

 protected $loggingQueries = false;

এটি পরিবর্তন করুন

protected $loggingQueries = true; 

লগিংয়ের প্রশ্নের জন্য নীচের ফাইলটিতে file

/vendor/laravel/framework/src/illuminate/Database/Connection.php 

এবং তারপরে DB::getQueryLog()আপনি যেখানে কোয়েরিটি মুদ্রণ করতে চান তা আমরা ব্যবহার করতে পারি ।


1
vendorফাইলগুলি সম্পাদনা করা এটি একটি খারাপ ধারণা । সেগুলি অবশ্যই মূল রাখতে হবে।
shukshin.ivan

@ shukshin.ivan হ্যাঁ একজনকে অবশ্যই বিক্রেতার ফাইলগুলি সম্পাদনা করতে হবে না তবে আমাদের কাছে এই কোডটি আপাতত সম্পাদনা করার সঠিক কোয়েরিটি পেতে হলে আমরা এটি আবার পরিবর্তন করতে পারি।
রূপালী পেমারে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.