将自定义函数添加到 Laravel 查询生成器

2023-12-21

我正在尝试添加USE INDEX()到 Laravel 中的查询生成器。我尝试遵循类似的步骤link https://medium.com/@justin.park001/laravel-techniques-extending-the-query-builder-2f4aca7956a2并取得了一定的成功,但我无法管理最后一点,而且我不确定我的临时代码是否创建了一个巨大的后门。

目标:我练习的目标是将索引添加到查询生成器,如下所示:

DB::table('users')->where('id',1)->**useIndex**('users')->get()->first();

这里有一个选项useIndex指定我将用于此查询的索引。

我已经做了什么:创建了一个名为Connection in App/Override

   <?php
    
    namespace App\Override;
    class Connection extends \Illuminate\Database\MySqlConnection {
        //@Override
        public function query() {
            return new QueryBuilder(
                $this,
                $this->getQueryGrammar(),
                $this->getPostProcessor()
            );
        }
    }

创建了一个名为CustomDatabaseServiceProvider在应用程序/提供商中。这里我只是操纵了registerConnectionServices功能。我进一步评论Illuminate\Database\DatabaseServiceProvider::class,并添加了 App\Providers\CustomDatabaseServiceProvider::class, to app.php在配置目录中。

<?php

namespace App\Providers;

use App\Override\Connection;
use Illuminate\Database\DatabaseManager;
use Illuminate\Database\Query\Grammars\Grammar;
use Illuminate\Database\Schema;
use Illuminate\Contracts\Queue\EntityResolver;
use Illuminate\Database\Connectors\ConnectionFactory;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\QueueEntityResolver;
use Illuminate\Support\ServiceProvider;

class CustomDatabaseServiceProvider extends ServiceProvider
{
    /**
     * The array of resolved Faker instances.
     *
     * @var array
     */
    protected static $fakers = [];

    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        Model::setConnectionResolver($this->app['db']);

        Model::setEventDispatcher($this->app['events']);
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        Model::clearBootedModels();

        $this->registerConnectionServices();

        $this->registerEloquentFactory();

        $this->registerQueueableEntityResolver();
    }

    /**
     * Register the primary database bindings.
     *
     * @return void
     */
    protected function registerConnectionServices()
    {
        // The connection factory is used to create the actual connection instances on
        // the database. We will inject the factory into the manager so that it may
        // make the connections while they are actually needed and not of before.
        $this->app->singleton('db.factory', function ($app) {
            return new ConnectionFactory($app);
        });

        // The database manager is used to resolve various connections, since multiple
        // connections might be managed. It also implements the connection resolver
        // interface which may be used by other components requiring connections.
        $this->app->singleton('db', function ($app) {
            $dbm = new DatabaseManager($app, $app['db.factory']);
            //Extend to include the custom connection (MySql in this example)
            $dbm->extend('mysql', function ($config, $name) use ($app) {
                //Create default connection from factory
                $connection = $app['db.factory']->make($config, $name);
                //Instantiate our connection with the default connection data
                $new_connection = new Connection(
                    $connection->getPdo(),
                    $connection->getDatabaseName(),
                    $connection->getTablePrefix(),
                    $config
                );
                //Set the appropriate grammar object
//                $new_connection->setQueryGrammar(new Grammar());
//                $new_connection->setSchemaGrammar(new Schema\());
                return $new_connection;
            });
            return $dbm;
        });

        $this->app->bind('db.connection', function ($app) {
            return $app['db']->connection();
        });
    }

    /**
     * Register the Eloquent factory instance in the container.
     *
     * @return void
     */
    protected function registerEloquentFactory()
    {
        $this->app->singleton(FakerGenerator::class, function ($app, $parameters) {
            $locale = $parameters['locale'] ?? $app['config']->get('app.faker_locale', 'en_US');

            if (!isset(static::$fakers[$locale])) {
                static::$fakers[$locale] = FakerFactory::create($locale);
            }

            static::$fakers[$locale]->unique(true);

            return static::$fakers[$locale];
        });

        $this->app->singleton(EloquentFactory::class, function ($app) {
            return EloquentFactory::construct(
                $app->make(FakerGenerator::class), $this->app->databasePath('factories')
            );
        });
    }

    /**
     * Register the queueable entity resolver implementation.
     *
     * @return void
     */
    protected function registerQueueableEntityResolver()
    {
        $this->app->singleton(EntityResolver::class, function () {
            return new QueueEntityResolver;
        });
    }
}

最后创建了一个名为QueryBuilder在应用程序/覆盖中。这是有问题的类:

<?php

namespace App\Override;

use Illuminate\Support\Facades\Cache;

class QueryBuilder extends \Illuminate\Database\Query\Builder
{
    private $Index = [];

    public function useIndex($index = null)
    {
        $this->Index = $index;
        return $this;
    }

    //@Override
    public function get($columns = ['*'])
    {
        if ($this->Index) {
            //Get the raw query string with the PDO bindings
            $sql_str = str_replace('from `' . $this->from . '`', 'from `' . $this->from . '` USE INDEX (`' . $this->Index . '`) ', $this->toSql());
            $sql_str = vsprintf($sql_str, $this->getBindings());
            return parent::get($sql_str);
        } else {
            //Return default
            return parent::get($columns);
        }
    }
}

这里的问题是:

  1. 输出不包含 USE INDEX
  2. 使用 str_replace 操作查询安全吗?

查询生成器是可宏的,因此在您的服务提供商中您可以执行以下操作:

Illuminate\Database\Query\Builder::macro(
    'tableWithIndex',
    function ($table, $index) {
        $table = $this->grammar->wrapTable($table);
        $index = $this->grammar->wrap($index);
        return $this->fromRaw("$table USE INDEX ($index)");
    }
);

然后你可以使用这个:

DB::tableWithIndex('users', 'users');

宏观内$this将引用查询构建器实例

请注意,我将它们合二为一,因为您可能有多个from调用相同的查询,试图弄清楚什么去了哪里会很混乱

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将自定义函数添加到 Laravel 查询生成器 的相关文章

  • 由于重复捕获组而不是捕获重复组,正则表达式不匹配

    我有以下正则表达式 A G A G 具有以下表达式 A BsCb 我期望 3 个匹配结果 A Bs Cb 但测试在https regex101 com https regex101 com 只给我最后一场比赛Cb 并告诉我重复捕获组只会捕获
  • 服务器响应中的“连接:保持活动状态”

    我正在尝试建立从 Silverlight 应用程序到 Apache 服务器托管的 PHP 页面的 HTTP 持久连接 即无需为每个 HTTP 请求创建新的 TCP 连接 为此 我需要网络服务器发送其 HTTP 响应 并将 Connectio
  • 有没有办法在不使用 foreach 或其他函数的情况下在 PHP 中内爆关联数组的键和值?

    我有一个像这样的关联数组 myarray array a gt 1 b gt 2 c gt 3 我想显示数组键和值 如下所示 a is 1 b is 2 c is 3 我不想使用 print r 或 var dump 来执行此操作 我也不想
  • ajax 会增加还是降低安全性?

    我正在创建一个网站 到目前为止它是纯 PHP 的 我在想 既然很少有人没有启用 JavaScript 我想知道为什么 也许我应该将我的网站创建为一个完全 PHP 的网站 而不使用任何 AJAX 难道是我想错了 可以肯定的是 如果我实施一些
  • Laravel 5.6 - 注册表无法正常工作并且不显示任何错误

    在我最近的一个项目中 定制登记表不管用 当我单击注册按钮时 它会重新加载注册表单 不会打印任何错误 并且不会将数据插入数据库中 这是注册表的外观 这里是移民文件代码 public function up Schema create user
  • Mongodb $push 嵌套数组

    我想向我的嵌套数组添加新数据 我的文档是 username erkin email email protected cdn cgi l email protection password b playlists id 58 name asd
  • 获取目录中最后修改的文件

    有没有办法只选择目录中的最后一个文件 扩展名jpg png gif 或者我是否必须解析整个目录并使用进行检查filemtime 是的 你必须通读它们 但由于目录访问已被缓存 因此您不必真正担心它 files array merge glob
  • Lumen 微框架 => php artisan key:generate

    我正在尝试 PHP 微框架 Lumen 来自 Laravel 我的第一步就是调查 env example文件并复制一份以供我使用 env文件 就像 Laravel 中一样 有一个变量 APP KEY 现在我尝试了简单的命令php artis
  • 计算轮班工作时间并检测

    我有个问题 我的英语很差 我需要用PHP做一个加班计算 已经有一个代码可以实现这一点 但当工作时间超过2天时 计算就会出错 工作开始 2018 09 09 13 43 工作结束 2018 09 11 07 13 结果 07 18 04 00
  • 如何使用额外标记输出 wp_list_categories

    我目前正在使用下面的脚本在无序列表中输出我的所有 WordPress 类别 如何获得带有额外标记的输出 ul ul 例如 ul li Category 1 rsaquo li li Category 2 rsaquo li ul 代替 ul
  • Laravel Passport,通过密码客户端进行多个连接

    我无法理解如何使用 Laravel Passport 通过密码客户端为同一用户实现多个连接 我有一个移动应用程序 需要与基于 Laravel 的 API 进行通信 我的用户在首次启动应用程序时必须输入他们的login and passwor
  • 如何使用多个数据库设置 symfony 3 学说迁移?

    我在验证和更新模式时努力让 symfony doctrine 排除数据库视图 我第一次尝试没有教条迁移 看到这个问题 https stackoverflow com questions 46775200 symfony 3 doctrine
  • 将自定义参数传递给 Symfony2 中的自定义 ValidationConstraint

    我正在 Symfony2 中创建一个表单 表格只包含一个book字段允许用户在列表中进行选择Books实体 我需要检查是否选择了Book属于Author我的控制器里有 public class MyFormType extends Abst
  • PHP URL 验证

    我知道有无数的线程问这个问题 但我一直无法找到一个可以帮助我解决这个问题的线程 我基本上试图解析大约 10 000 000 个 URL 的列表 确保它们根据以下标准有效 然后获取根域 URL 此列表包含您能想象到的几乎所有内容 包括类似的内
  • 使用 PHP 修剪字符串开头的任何零

    用户将在字段中填写与其帐户相关的数字 不幸的是 一些用户会在号码开头添加零来组成六位数字 例如 000123 001234 而其他用户则不会 例如 123 1234 我想 修剪 前面带有零前缀的用户的数字 因此如果用户输入 000123 它
  • 将价格格式设置为逗号分隔

    在我的数据库中 我有类似的值 256 23 200 33 89 33 133 45 我必须将这些值乘以千 然后将结果格式化为价格 逗号分隔 256 23 x 1000 256230 I want to show this as 256 23
  • 打印表数据mysql php

    我在尝试打印表格的一些数据时遇到问题 我是 php mysql 的新手 但我认为我的代码是正确的 这里是 h1 Lista de usu rios h1
  • 如果文件名减去扩展名,.htaccess url 重写行为将被覆盖。与网址相同

    我正在尝试整理 URL 并从中删除 php 扩展名等 我位于网站的基本文件夹中 因此没有可以优先处理的父 htaccess 文件或其他文件 这是我的 htaccess 代码 RewriteEngine On RewriteRule give
  • 如何根据另一个下拉列表中的选择动态填充下拉列表中的选项?

    我有一个表 其中包含类别信息 例如产品 我已将它们列在下拉菜单中 现在 我需要做的是 在下一个下拉菜单中列出所选类别的子类别 我希望 javascript 是必需的 但我对 javascript 还不太熟悉 将非常感谢您的帮助 你应该使用
  • PHP 用星号替换所有字符

    假设我有一个字符串形式的密码 password thisisaplaintextpassword 我怎样才能把它变成下面的样子 password 我想通过电子邮件向用户发送他们的帐户详细信息 但不想发送整个内容 Use 字符串重复 http

随机推荐

  • 将 RMagick 与 Ocra 捆绑在一起

    我正在尝试使用 Ocra 创建 Ruby 脚本的可移植版本 该脚本取决于rmagick这还需要安装 ImageMagick 生成的可执行文件在我的计算机上可以运行 但在其他所有计算机上都会失败 除非最终用户手动安装 ImageMagick
  • 取消引用双指针

    我有一段代码片段 我无法理解它是如何工作的 因为有一行执行了双重取消引用 代码如下所示 void afunction int x x malloc 2 sizeof int x 12 x 1 13 int main int v 10 afu
  • 比较 MSE 损失和交叉熵损失的收敛性

    For a very simple classification problem where I have a target vector 0 0 0 0 and a prediction vector 0 0 1 0 2 1 would
  • 强制编译器遵循 C99 标准

    当我在我的项目上编码时 我发现我已经使用了一段时间的匿名结构实际上只在 C11 中可用 而不是我想要针对的标准 C99 中可用 给出以下代码 struct data int a struct int b int c int main str
  • 将 INFO 和 ERROR 日志与 java.util.logging 分开

    我正在为 Java 应用程序配置日志记录 我的目标是两个日志 一个用于所有消息 另一个仅用于高于特定级别的消息 该应用程序使用java util logging 类 我按原样使用它 所以我只能通过logging properties fil
  • 经典 ASP - SQL Server 不存在或访问被拒绝

    我正在尝试连接到本地主机上的 SQL Server Express DB 但收到以下错误消息 用于 SQL Server 的 Microsoft OLE DB 提供程序 0x80004005 DBNETLIB ConnectionOpen
  • 注入时 Jquery 对话框无法正确显示

    我正在制作一个 Chrome 扩展 并尝试在用户单击页面上的元素时注入 Jquery 当我尝试通过 Jquery 创建对话框时 var box document createElement div box id box box title
  • 如何从 vue 中的所有子复选框组件中收集选定的复选框?

    我有一个表 其中行元素全部由子组件填充 每个子组件中都有一个复选框 现在我想立即获取所有选中的复选框 我可以使用首选项发出作为两种方式绑定并更新父级上的数组或对象 但我想知道是否有更好的方法 这是模板部分的简短示例 table thead
  • 如何设置 IIS 以使应用程序保持活动状态?

    我认为我的网络应用程序会在一段时间后关闭 如果我大约 5 分钟内没有使用该应用程序 它会返回一个新会话 会话超时设置为 720 分钟 因此这不会成为问题 可能是应用程序池中的设置或类似的设置 我认为这是某种资源管理 我使用的是IIS 7 0
  • 在 bash 中使用 IFS 使用 \r\n 分割字符串

    我想在 bash 中拆分包含 r n 的字符串 但回车符和 n 会出现问题 谁能给我关于不同 IFS 的提示 我也尝试过 IFS input projects google tests inbox document 01 r nprojec
  • 通过管道将 JSON 转换为 ForEach 时的奇怪行为

    为什么以下不迭代元素System object 返回的数组ConvertFrom Json ConvertFrom Json 1 2 3 ForEach Object 但这确实 ConvertFrom Json 1 2 3 ForEach
  • 如何将开发者工具嵌入到 GeckoFx 网络浏览器中?

    我正在构建一个以开发人员为主题的C NET Windows 窗体应用程序中的浏览器并希望让用户能够使用 Chrome 或 Firefox DevTools 编辑 调试他们正在查看的当前页面 我在网上找到了几个存储库 但似乎没有一个是我想要的
  • 删除未连接到分支的提交

    我想合并来自另一个存储库的一些更改 因此我添加了远程 获取并合并 但我没想到会添加另一个分支的提交 我支持合并中的一项提交 并手动添加更改的文件并推送该提交 所以现在我在一个分支中有两个断开连接的提交树 像这样的事情 A B C D mas
  • 可拉伸的标头,如 StackExchange

    我怎样才能用CSS做一个像这样的网站布局webmaster stackexchange com该网站位于中心 页眉和页脚与用户的窗口分辨率一样长 而内容位于中心 请检查图像fs 您不明白我的意思 谢谢 您的帮助 http imageshac
  • 如何将 ASM 程序包含到我的 Turbo Basic 程序中?

    我找到了这个 ASM 例程来按下按键 用于按下按键的 ASM 例程 http www fysnet net kbuffio htm现在我想将其包含到 Turbo Basic 例程中 但不知道如何执行此操作 这里有人能告诉我这是怎么做的吗 谢
  • 在 Laravel 中使用不同的多列

    我的表结构如下 date seller unit price total 05 06 17 abc 14 700 9800 05 06 17 pqr 12 600 7200 05 06 17 abc 10 520 5200 06 06 17
  • 使用 javascript 或 datejs 比较两个日期(日期差异)

    我试图比较芬兰时间形式的两个日期 如下所示 dd mm YYYY 或 d m YYYY 或 dd m YYYY 或 d mm YYYY 我很难找到如何做到这一点 我当前的代码将无法工作
  • 如何在运行时更改 EasingDoubleKeyFrame 值?

    我正在尝试做一个翻译转换动画片 在动画中 我需要我的对象保留在窗口的中心 我知道 WPF 动画是 Freezable 的 我正在使用转换器 但它会在启动时初始化值 有没有办法设置的值缓动双关键帧在运行时 这是我的 XAML 代码
  • 在 IEnumerable c# mvc 中设置选择值 [重复]

    这个问题在这里已经有答案了 我有一个IEnumerable
  • 将自定义函数添加到 Laravel 查询生成器

    我正在尝试添加USE INDEX 到 Laravel 中的查询生成器 我尝试遵循类似的步骤link https medium com justin park001 laravel techniques extending the query