laravel-soar
                                
                                 laravel-soar copied to clipboard
                                
                                    laravel-soar copied to clipboard
                            
                            
                            
                        SQL optimizer and rewriter for laravel. - laravel 的 SQL 优化器和重写器。

laravel-soar
SQL optimizer and rewriter for laravel. - laravel ç SQL ä¼åå¨åéåå¨ã
ç®ä½ä¸æ | ENGLISH
åè½
- æ¯æå¯åå¼ç®æ³è¯å¥ä¼å建议ãç´¢å¼ä¼å建议
- æ¯æ EXPLAIN ä¿¡æ¯ä¸°å¯è§£è¯»
- èªå¨çæ§è¾åº SQL ä¼å建议
- Debug barãSoar barãJSONãClockworkãConsoleãDumpãLogãèªå®ä¹è¾åºå¨(å¤ç§åºæ¯è¾åº)
- æ¯ææ¥è¯¢æå»ºå¨çæ SQL ä¼å建议
ç¸å ³é¡¹ç®
- https://github.com/XiaoMi/soar
- https://github.com/guanguans/soar-php
- https://github.com/huangdijia/laravel-web-soar
- https://github.com/wilbur-yu/hyperf-soar
- https://github.com/guanguans/think-soar
- https://github.com/Tinywan/webman-soar
ç¯å¢è¦æ±
- laravel >= 6.10
å®è£
$ composer require guanguans/laravel-soar --dev -vvv
é ç½®
注åæå¡
laravel
$ php artisan vendor:publish --provider="Guanguans\\LaravelSoar\\SoarServiceProvider"
lumen
å°ä»¥ä¸ä»£ç æ®µæ·»å å° bootstrap/app.php æä»¶ä¸ç Register Service Providers é¨åä¸ï¼
$app->register(\Guanguans\LaravelSoar\SoarServiceProvider::class);
使ç¨
示ä¾ä»£ç 
详æ
<?php
namespace App\Admin\Controllers;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class SoarController extends Controller
{
    public function sqlScore()
    {
        // å建表
        DB::select(
            <<<SQL
CREATE TABLE `users` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email_verified_at` timestamp NULL DEFAULT NULL,
  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SQL
        );
        // æå
¥æ°æ®
        User::query()->insert([
            'name'              => 'soar',
            'email'             => '[email protected]',
            'email_verified_at' => now(),
            'password'          => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
            'remember_token'    => Str::random(10),
        ]);
        // æ´æ°æ°æ®
        User::query()->update([
            'name'     => 'name',
            'password' => 'password',
        ]);
        // æ¥è¯¢æ°æ®
        User::query()->where('name', 'soar')->groupBy('name')->having('created_at', '>', now())->get();
        // å é¤æ°æ®
        User::query()->where('name', 'soar')->delete();
        // å é¤è¡¨
        DB::select('DROP table `users`;');
        // return response()->json(['message' => 'ok']); // JSON ååº
        return response('ok'); // HTML ååº
    }
}
èªå¨çæ§è¾åº SQL ä¼å建议
Json ååº
{
    "message": "ok",
    "soar_scores": [
        {
            "Summary": "[âââââ|0å|3.56ms|select * from `users` where `name` = 'soar' group by `name` having `created_at` > '2022-04-19 18:24:33']",
            "HeuristicRules": [
                {
                    "Item": "CLA.008",
                    "Severity": "L2",
                    "Summary": "请为 GROUP BY æ¾ç¤ºæ·»å  ORDER BY æ¡ä»¶",
                    "Content": "é»è®¤ MySQL ä¼å¯¹ 'GROUP BY col1, col2, ...' è¯·æ±æå¦ä¸é¡ºåºæåº 'ORDER BY col1, col2, ...'ã妿 GROUP BY è¯å¥ä¸æå® ORDER BY æ¡ä»¶ä¼å¯¼è´æ è°çæåºäº§çï¼å¦æä¸éè¦æåºå»ºè®®æ·»å  'ORDER BY NULL'ã",
                    "Case": "select c1,c2,c3 from t1 where c1='foo' group by c2",
                    "Position": 0
                },
                {
                    "Item": "CLA.013",
                    "Severity": "L3",
                    "Summary": "ä¸å»ºè®®ä½¿ç¨ HAVING åå¥",
                    "Content": "å°æ¥è¯¢ç HAVING å奿¹å为 WHERE ä¸çæ¥è¯¢æ¡ä»¶ï¼å¯ä»¥å¨æ¥è¯¢å¤çæé´ä½¿ç¨ç´¢å¼ã",
                    "Case": "SELECT s.c_id,count(s.c_id) FROM s where c = test GROUP BY s.c_id HAVING s.c_id <> '1660' AND s.c_id <> '2' order by s.c_id",
                    "Position": 0
                },
                {
                    "Item": "COL.001",
                    "Severity": "L1",
                    "Summary": "ä¸å»ºè®®ä½¿ç¨ SELECT * ç±»åæ¥è¯¢",
                    "Content": "å½è¡¨ç»æåæ´æ¶ï¼ä½¿ç¨ * éé
ç¬¦éæ©ææåå°å¯¼è´æ¥è¯¢çå«ä¹åè¡ä¸ºä¼åçæ´æ¹ï¼å¯è½å¯¼è´æ¥è¯¢è¿åæ´å¤çæ°æ®ã",
                    "Case": "select * from tbl where id=1",
                    "Position": 0
                },
                {
                    "Item": "ERR.002",
                    "Severity": "L8",
                    "Summary": "MySQL execute failed",
                    "Content": "Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'optimizer_220419182434_gwyshx8la4boulhu.users.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by",
                    "Case": "",
                    "Position": 0
                },
                {
                    "Item": "GRP.001",
                    "Severity": "L2",
                    "Summary": "ä¸å»ºè®®å¯¹ç弿¥è¯¢åä½¿ç¨ GROUP BY",
                    "Content": "GROUP BY ä¸çåå¨åé¢ç WHERE æ¡ä»¶ä¸ä½¿ç¨äºç弿¥è¯¢ï¼å¯¹è¿æ ·çåè¿è¡ GROUP BY æä¹ä¸å¤§ã",
                    "Case": "select film_id, title from film where release_year='2006' group by release_year",
                    "Position": 0
                },
                {
                    "Item": "RES.001",
                    "Severity": "L4",
                    "Summary": "éç¡®å®æ§ç GROUP BY",
                    "Content": "SQLè¿åç忢ä¸å¨èå彿°ä¸ä¹ä¸æ¯ GROUP BY 表达å¼çåä¸ï¼å æ¤è¿äºå¼çç»æå°æ¯éç¡®å®æ§çãå¦ï¼select a, b, c from tbl where foo=\"bar\" group by aï¼è¯¥ SQL è¿åçç»æå°±æ¯ä¸ç¡®å®çã",
                    "Case": "select c1,c2,c3 from t1 where c2='foo' group by c2",
                    "Position": 0
                }
            ],
            "IndexRules": [
                {
                    "Item": "IDX.001",
                    "Severity": "L2",
                    "Summary": "为laravelåºçusers表添å ç´¢å¼",
                    "Content": "为ånameæ·»å ç´¢å¼;为åcreated_atæ·»å ç´¢å¼; ç±äºæªå¼å¯æ°æ®éæ ·ï¼ååå¨ç´¢å¼ä¸ç顺åºéè¦èªè¡è°æ´ã",
                    "Case": "ALTER TABLE `laravel`.`users` add index `idx_name_created_at` (`name`(191),`created_at`) ;\n",
                    "Position": 0
                }
            ],
            "Explain": [],
            "Backtraces": [
                "#13 /app/Admin/Controllers/HomeController.php:74",
                "#55 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:45",
                "#76 /public/index.php:55",
                "#77 /server.php:21"
            ]
        },
        {
            "Summary": "[â
â
â
â
â|75å|64.5ms|CREATE TABLE `users` (\n  `id` bigint unsigned NOT NULL AUTO_INCREMENT,\n  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\n  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\n  `email_verified_at` timestamp NULL DEFAULT NULL,\n  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\n  `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n  `created_at` timestamp NULL DEFAULT NULL,\n  `updated_at` timestamp NULL DEFAULT NULL,\n  PRIMARY KEY (`id`),\n  UNIQUE KEY `users_email_unique` (`email`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;]",
            "HeuristicRules": [
                {
                    "Item": "CLA.011",
                    "Severity": "L1",
                    "Summary": "å»ºè®®ä¸ºè¡¨æ·»å æ³¨é",
                    "Content": "ä¸ºè¡¨æ·»å æ³¨éè½å¤ä½¿å¾è¡¨çæä¹æ´æç¡®ï¼ä»è为æ¥åçç»´æ¤å¸¦æ¥æå¤§ç便å©ã",
                    "Case": "CREATE TABLE `test1` (`ID` bigint(20) NOT NULL AUTO_INCREMENT,`c1` varchar(128) DEFAULT NULL,PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8",
                    "Position": 0
                },
                {
                    "Item": "COL.004",
                    "Severity": "L1",
                    "Summary": "è¯·ä¸ºåæ·»å é»è®¤å¼",
                    "Content": "è¯·ä¸ºåæ·»å é»è®¤å¼ï¼å¦ææ¯ ALTER æä½ï¼è¯·ä¸è¦å¿è®°å°ååæ®µçé»è®¤å¼åä¸ãåæ®µæ é»è®¤å¼ï¼å½è¡¨è¾å¤§æ¶æ æ³å¨çº¿åæ´è¡¨ç»æã",
                    "Case": "CREATE TABLE tbl (col int) ENGINE=InnoDB;",
                    "Position": 0
                },
                {
                    "Item": "COL.005",
                    "Severity": "L1",
                    "Summary": "åæªæ·»å æ³¨é",
                    "Content": "å»ºè®®å¯¹è¡¨ä¸æ¯ä¸ªåæ·»å æ³¨éï¼æ¥æç¡®æ¯ä¸ªåå¨è¡¨ä¸çå«ä¹åä½ç¨ã",
                    "Case": "CREATE TABLE tbl (col int) ENGINE=InnoDB;",
                    "Position": 0
                },
                {
                    "Item": "COL.011",
                    "Severity": "L0",
                    "Summary": "å½éè¦å¯ä¸çº¦ææ¶æä½¿ç¨ NULLï¼ä»
å½åä¸è½æç¼ºå¤±å¼æ¶æä½¿ç¨ NOT NULL",
                    "Content": "NULL å0æ¯ä¸åçï¼10ä¹ä»¥ NULL è¿æ¯ NULLãNULL å空å符串æ¯ä¸ä¸æ ·çãå°ä¸ä¸ªåç¬¦ä¸²åæ å SQL ä¸ç NULL èåèµ·æ¥çç»æè¿æ¯ NULLãNULL å FALSE 乿¯ä¸åçãANDãOR å NOT è¿ä¸ä¸ªå¸å°æä½å¦ææ¶å NULLï¼å
¶ç»æä¹è®©å¾å¤äººæå°å°æã彿¨å°ä¸å声æä¸º NOT NULL æ¶ï¼ä¹å°±æ¯è¯´è¿åä¸çæ¯ä¸ä¸ªå¼é½å¿
é¡»åå¨ä¸æ¯ææä¹çãä½¿ç¨ NULL æ¥è¡¨ç¤ºä»»æç±»åä¸åå¨ç空å¼ã 彿¨å°ä¸å声æä¸º NOT NULL æ¶ï¼ä¹å°±æ¯è¯´è¿åä¸çæ¯ä¸ä¸ªå¼é½å¿
é¡»åå¨ä¸æ¯ææä¹çã",
                    "Case": "select c1,c2,c3 from tbl where c4 is null or c4 <> 1",
                    "Position": 49
                },
                {
                    "Item": "KWR.003",
                    "Severity": "L1",
                    "Summary": "ä¸å»ºè®®ä½¿ç¨å¤æ°åååæè¡¨å",
                    "Content": "表ååºè¯¥ä»
ä»
表示表éé¢çå®ä½å
容ï¼ä¸åºè¯¥è¡¨ç¤ºå®ä½æ°éï¼å¯¹åºäº DO ç±»å乿¯åæ°å½¢å¼ï¼ç¬¦å表达习æ¯ã",
                    "Case": "CREATE TABLE tbl ( `books` int )",
                    "Position": 0
                },
                {
                    "Item": "SEC.002",
                    "Severity": "L0",
                    "Summary": "ä¸ä½¿ç¨ææåå¨å¯ç ",
                    "Content": "ä½¿ç¨ææåå¨å¯ç æè
ä½¿ç¨ææå¨ç½ç»ä¸ä¼ éå¯ç é½æ¯ä¸å®å
¨çã妿æ»å»è
è½å¤æªè·æ¨ç¨æ¥æå
¥å¯ç çSQLè¯å¥ï¼ä»ä»¬å°±è½ç´æ¥è¯»å°å¯ç ãå¦å¤ï¼å°ç¨æ·è¾å
¥çå符串以ææç形弿å
¥å°çº¯SQLè¯å¥ä¸ï¼ä¹ä¼è®©æ»å»è
åç°å®ã妿æ¨è½å¤è¯»åå¯ç ï¼é»å®¢ä¹å¯ä»¥ãè§£å³æ¹æ¡æ¯ä½¿ç¨åååå¸å½æ°å¯¹åå§å¯ç è¿è¡å å¯ç¼ç ãå叿¯æå°è¾å
¥å符串转åæå¦ä¸ä¸ªæ°çãä¸å¯è¯å«çå符串ç彿°ã对å¯ç å å¯è¡¨è¾¾å¼å ç¹éæºä¸²æ¥é²å¾¡âåå
¸æ»å»âãä¸è¦å°ææå¯ç è¾å
¥å°SQLæ¥è¯¢è¯å¥ä¸ãå¨åºç¨ç¨åºä»£ç ä¸è®¡ç®åå¸ä¸²ï¼åªå¨SQLæ¥è¯¢ä¸ä½¿ç¨åå¸ä¸²ã",
                    "Case": "create table test(id int,name varchar(20) not null,password varchar(200)not null)",
                    "Position": 0
                },
                {
                    "Item": "STA.003",
                    "Severity": "L1",
                    "Summary": "ç´¢å¼èµ·åä¸è§è",
                    "Content": "建议æ®éäºçº§ç´¢å¼ä»¥idx_为åç¼ï¼å¯ä¸ç´¢å¼ä»¥uk_为åç¼ã",
                    "Case": "select col from now where type!=0",
                    "Position": 0
                }
            ],
            "IndexRules": [],
            "Explain": [],
            "Backtraces": [
                "#9 /app/Admin/Controllers/HomeController.php:46",
                "#51 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:45",
                "#72 /public/index.php:55",
                "#73 /server.php:21"
            ]
        },
        {
            "Summary": "[â
â
â
â
â|80å|21.9ms|update `users` set `name` = 'name', `password` = 'password', `users`.`updated_at` = '2022-04-19 18:24:33']",
            "HeuristicRules": [
                {
                    "Item": "CLA.015",
                    "Severity": "L4",
                    "Summary": "UPDATE æªæå® WHERE æ¡ä»¶",
                    "Content": "UPDATE ä¸æå® WHERE æ¡ä»¶ä¸è¬æ¯è´å½çï¼è¯·æ¨ä¸æåè¡",
                    "Case": "update tbl set col=1",
                    "Position": 0
                }
            ],
            "IndexRules": [],
            "Explain": {
                "Item": "EXP.000",
                "Severity": "L0",
                "Summary": "Explainä¿¡æ¯",
                "Content": [
                    "| id | select\\_type | table | partitions | type | possible_keys | key | key\\_len | ref | rows | filtered | scalability | Extra |",
                    "|---|---|---|---|---|---|---|---|---|---|---|---|---|",
                    "| 1  | UPDATE | *users* | NULL | index | NULL | PRIMARY | 8 | NULL | 1 | â ï¸ **100.00%** | O(n) | NULL |",
                    "",
                    ""
                ],
                "Case": [
                    "### Explainä¿¡æ¯è§£è¯»",
                    "",
                    "#### Typeä¿¡æ¯è§£è¯»",
                    "",
                    "* **index**: å
¨è¡¨æ«æ, åªæ¯æ«æè¡¨çæ¶åæç
§ç´¢å¼æ¬¡åºè¿è¡è䏿¯è¡. 主è¦ä¼ç¹å°±æ¯é¿å
äºæåº, 使¯å¼éä»ç¶é常大.",
                    ""
                ],
                "Position": 0
            },
            "Backtraces": [
                "#10 /app/Admin/Controllers/HomeController.php:70",
                "#52 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:45",
                "#73 /public/index.php:55",
                "#74 /server.php:21"
            ]
        },
        {
            "Summary": "[â
â
â
â
â
|90å|4.5ms|delete from `users` where `name` = 'soar']",
            "HeuristicRules": [
                {
                    "Item": "SEC.003",
                    "Severity": "L0",
                    "Summary": "使ç¨DELETE/DROP/TRUNCATEçæä½æ¶æ³¨æå¤ä»½",
                    "Content": "卿§è¡é«å±æä½ä¹åå¯¹æ°æ®è¿è¡å¤ä»½æ¯ååæå¿
è¦çã",
                    "Case": "delete from table where col = 'condition'",
                    "Position": 0
                }
            ],
            "IndexRules": [
                {
                    "Item": "IDX.001",
                    "Severity": "L2",
                    "Summary": "为laravelåºçusers表添å ç´¢å¼",
                    "Content": "为ånameæ·»å ç´¢å¼; ç±äºæªå¼å¯æ°æ®éæ ·ï¼ååå¨ç´¢å¼ä¸ç顺åºéè¦èªè¡è°æ´ã",
                    "Case": "ALTER TABLE `laravel`.`users` add index `idx_name` (`name`(191)) ;\n",
                    "Position": 0
                }
            ],
            "Explain": {
                "Item": "EXP.000",
                "Severity": "L0",
                "Summary": "Explainä¿¡æ¯",
                "Content": [
                    "| id | select\\_type | table | partitions | type | possible_keys | key | key\\_len | ref | rows | filtered | scalability | Extra |",
                    "|---|---|---|---|---|---|---|---|---|---|---|---|---|",
                    "| 1  | DELETE | *users* | NULL | ALL | NULL | NULL | NULL | NULL | 1 | â ï¸ **100.00%** | O(n) | Using where |",
                    "",
                    ""
                ],
                "Case": [
                    "### Explainä¿¡æ¯è§£è¯»",
                    "",
                    "#### Typeä¿¡æ¯è§£è¯»",
                    "",
                    "* **ALL**: æåçæ
åµ, ä»å¤´å°å°¾å
¨è¡¨æ«æ.",
                    "",
                    "#### Extraä¿¡æ¯è§£è¯»",
                    "",
                    "* **Using where**: WHEREæ¡ä»¶ç¨äºçéåºä¸ä¸ä¸ä¸ªè¡¨å¹é
çæ°æ®ç¶åè¿åç»å®¢æ·ç«¯. é¤éæ
æåçå
¨è¡¨æ«æ, å¦åè¿æ¥ç±»åæ¯ALLæè
æ¯index, ä¸å¨Extraåçå¼ä¸æ²¡æUsing Where, å该æ¥è¯¢å¯è½æ¯æé®é¢ç.",
                    ""
                ],
                "Position": 0
            },
            "Backtraces": [
                "#10 /app/Admin/Controllers/HomeController.php:76",
                "#52 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:45",
                "#73 /public/index.php:55",
                "#74 /server.php:21"
            ]
        },
        {
            "Summary": "[â
â
â
â
â
|100å|15.57ms|insert into `users` (`name`, `email`, `email_verified_at`, `password`, `remember_token`) values ('soar', '[email protected]', '2022-04-19 18:24:33', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'HecXUdevky')]",
            "HeuristicRules": [],
            "IndexRules": [],
            "Explain": {
                "Item": "EXP.000",
                "Severity": "L0",
                "Summary": "Explainä¿¡æ¯",
                "Content": [
                    "| id | select\\_type | table | partitions | type | possible_keys | key | key\\_len | ref | rows | filtered | scalability | Extra |",
                    "|---|---|---|---|---|---|---|---|---|---|---|---|---|",
                    "| 1  | INSERT | *users* | NULL | ALL | NULL | NULL | NULL | NULL | 0 | 0.00% | O(n) | NULL |",
                    "",
                    ""
                ],
                "Case": [
                    "### Explainä¿¡æ¯è§£è¯»",
                    "",
                    "#### Typeä¿¡æ¯è§£è¯»",
                    "",
                    "* **ALL**: æåçæ
åµ, ä»å¤´å°å°¾å
¨è¡¨æ«æ.",
                    ""
                ],
                "Position": 0
            },
            "Backtraces": [
                "#10 /app/Admin/Controllers/HomeController.php:66",
                "#52 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:45",
                "#73 /public/index.php:55",
                "#74 /server.php:21"
            ]
        }
    ]
}
Soar bar

Debug bar

Clockwork

Console

Dump

Log

èªå®ä¹è¾åºå¨
- å®ç°è¯¥æ¥å£
<?php
namespace Guanguans\LaravelSoar\Contracts;
use Illuminate\Support\Collection;
interface Output
{
    public function output(Collection $scores, $dispatcher);
}
- config/soar.phpä¸é ç½®è¾åºå¨å³å¯
<?php
return [
	...
    'output' => [
        // \Guanguans\LaravelSoar\Outputs\ClockworkOutput::class,
        // \Guanguans\LaravelSoar\Outputs\ConsoleOutput::class,
        // \Guanguans\LaravelSoar\Outputs\DumpOutput::class => ['exit' => false],
        \Guanguans\LaravelSoar\Outputs\JsonOutput::class,
        \Guanguans\LaravelSoar\Outputs\LogOutput::class => ['channel' => 'daily'],
        \Guanguans\LaravelSoar\Outputs\DebugBarOutput::class,
        \Guanguans\LaravelSoar\Outputs\SoarBarOutput::class,
    ],
	...
];
Soar å®ä¾åæ¹æ³
详æ
soar();      // è·å Soar å®ä¾
app('soar'); // è·å Soar å®ä¾
/**
 * Soar é¨é¢.
 *
 * @method static string score(string $sql)            // SQL è¯å
 * @method static array arrayScore(string $sql)        // SQL æ°ç»æ ¼å¼è¯å
 * @method static string jsonScore(string $sql)        // SQL json æ ¼å¼è¯å
 * @method static string htmlScore(string $sql)        // SQL html æ ¼å¼è¯å
 * @method static string mdScore(string $sql)          // SQL markdown æ ¼å¼è¯å
 * @method static string explain(string $sql)          // explain 解读信æ¯
 * @method static string mdExplain(string $sql)        // markdown æ ¼å¼ explain 解读信æ¯
 * @method static string htmlExplain(string $sql)      // html æ ¼å¼ explain 解读信æ¯
 * @method static null|string syntaxCheck(string $sql) // è¯æ³æ£æ¥
 * @method static string fingerPrint(string $sql)      // SQL æçº¹
 * @method static string pretty(string $sql)           // æ ¼å¼å SQL
 * @method static string md2html(string $sql)          // markdown 转 html
 * @method static string help()                        // Soar 帮å©
 * @method static null|string exec(string $command)    // æ§è¡ä»»æ Soar å½ä»¤
 * @method static string getSoarPath()                 // è·å Soar è·¯å¾
 * @method static array getOptions()                   // è·å Soar é
ç½®é项
 * @method static Soar setSoarPath(string $soarPath)   // 设置 Soar è·¯å¾
 * @method static Soar setOption(string $key, $value)  // 设置 Soar é
ç½®é项
 * @method static Soar setOptions(array $options)      // æ¹é设置 Soar é
ç½®é项
 *
 * @see \Guanguans\SoarPHP\Soar
 * @see \Guanguans\LaravelSoar\Soar
 */
class Soar{}
æ¥è¯¢æå»ºå¨æ¹æ³
详æ
namespace Illuminate\Database\Eloquent {
    /**
     * @method string toRawSql()
     * @method void   dumpRawSql()
     * @method void   ddRawSql()
     * @method array  toSoarArrayScore()
     * @method void   dumpSoarArrayScore()
     * @method void   ddSoarArrayScore()
     * @method string toSoarJsonScore()
     * @method void   dumpSoarJsonScore()
     * @method void   ddSoarJsonScore()
     * @method string toSoarHtmlScore()
     * @method void   echoSoarHtmlScore()
     * @method void   exitSoarHtmlScore()
     * @method string toSoarHtmlExplain()
     * @method void   echoSoarHtmlExplain()
     * @method void   exitSoarHtmlExplain()
     *
     * @see \Guanguans\LaravelSoar\Support\Macros\QueryBuilderMacro
     */
    class Builder
    {
    }
}
æµè¯
$ composer test
åæ´æ¥å¿
请åé CHANGELOG è·åæè¿æå ³æ´æ¹çæ´å¤ä¿¡æ¯ã
è´¡ç®æå
请åé CONTRIBUTING æå ³è¯¦ç»ä¿¡æ¯ã
å®å ¨æ¼æ´
请æ¥çæä»¬çå®å ¨æ¿çäºè§£å¦ä½æ¥åå®å ¨æ¼æ´ã
è´¡ç®è
åè®®
MIT 许å¯è¯ï¼MITï¼ãæå ³æ´å¤ä¿¡æ¯ï¼è¯·åè§åè®®æä»¶ã