【问题标题】:Laravel extend a vendor class installed from composerLaravel 扩展了从 composer 安装的供应商类
【发布时间】:2015-10-04 19:25:18
【问题描述】:

您好,我正在使用以下软件包 https://github.com/jayhealey/Robots 为我的应用程序中的每个环境添加不同的 robots.txt 文件。但是,这缺少我在我的应用程序上使用的一种方法,即抓取延迟,即

Crawl-delay: 3600

现在我从这个包的 composer install 中获得了以下文件夹:

vendor/healey/robots/src/Healey/Robots/Robots.php 开始如下:

<?php namespace Healey\Robots;

class Robots
{....}

现在我希望能够扩展这个类,这样我就可以成功地使用其中的方法,但显然不想在供应商目录中添加该函数,因为这是不可取的。所以我创建了以下类:

app/lib/Helpers/AppRobots.php

这有以下内容:

<?php
use Healey\Robots\Robots;
class AppRobots extends Robots {

    /**
     * Add crawl Delay to robots.txt.
     *
     * @param string $delay
     */
    public function crawlDelay($delay)
    {
        $this->addLine("Crawl-delay: $delay");
    }

}

现在在 routes.php 我有以下内容:

Route::get('robots.txt', function() {
    // If on the live server, serve a nice, welcoming robots.txt.
    if (App::environment() == 'production')
    {
        \Robots::addUserAgent('*');
        \AppRobots::crawlDelay('3600');

    } else {
        // If you're on any other server, tell everyone to go away.
        \Robots::addDisallow('*');
    }
    return Response::make(Robots::generate(), 200, array('Content-Type' => 'text/plain'));
});

现在这会引发以下错误:

不应静态调用非静态方法 AppRobots::crawlDelay()

所以我将方法更改为静态如下:

public static function crawlDelay($delay)
{
    $this->addLine("Crawl-delay: $delay");
}

但是这会引发以下错误:

当不在对象上下文中时使用 $this,所以我将其更新为使用以下方法:

/**
 * Add crawl Delay to robots.txt.
 *
 * @param string $delay
 */
public static function crawlDelay($delay)
{
    $robots = new \Robots();
    $robots->addLine("Crawl-delay: $delay");
}

现在我得到Call to undefined method Healey\Robots\RobotsFacade::addLine()

这是 RobotsFacade 文件 (vendor/healey/robots/src/Healey/Robots/RobotsFacade.php)

<?php namespace Healey\Robots;

use Illuminate\Support\Facades\Facade;

class RobotsFacade extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'robots'; }
}

这是服务提供商 (vendor/healey/robots/src/Healey/Robots/RobotsServiceProvider.php)

<?php namespace Healey\Robots;

use Illuminate\Support\ServiceProvider;

class RobotsServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = false;

    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        $this->package('healey/robots');
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app['robots'] = $this->app->share(function($app)
        {
            return new Robots();
        });

        $this->app->booting(function()
        {
            $loader = \Illuminate\Foundation\AliasLoader::getInstance();
            $loader->alias('Robots', 'Healey\Robots\RobotsFacade');
        });
    }

}

有什么想法可以成功扩展这个类,以便我可以根据需要添加额外的方法吗?

更新

app/lib/CustomRobotsServiceProvider.php

<?php 
namespace MyApp\Healey\Robots;
use Illuminate\Support\ServiceProvider;
class CustomRobotsServiceProvider extends ServiceProvider
{
  public function boot()
  {
  }

  public function register()
  {
    $this->app['robots'] = $this->app->share(function($app)
    {
        return new AppRobots();
    });
  }
}

app/lib/Helpers/AppRobots.php

<?php
namespace MyApp\Healey\Robots;
use MyApp\Healey\Robots\CustomRobotsServiceProvider;
use Healey\Robots\Robots as Robots;
class AppRobots extends Robots {

    /**
     * Add crawl Delay to robots.txt.
     *
     * @param string $delay
     */
    public static function crawlDelay($delay)
    {
        $robot = new Robots();
        $robot->addLine("Crawl-delay: $delay");
    }

}

providers 数组中的app.php,我有以下内容:

    'Healey\Robots\RobotsServiceProvider',
    'MyApp\Healey\Robots\CustomRobotsServiceProvider'

在别名数组中我有以下内容:

     'Robots'         => 'Healey\Robots\Robots',

但是,这不是使用此方法添加 Crawl Delay 线:

        \Robots::crawlDelay('3600');

知道为什么这条线没有被写入 robots.txt 路由吗?它可以正常使用该方法,但未成功添加此行。

【问题讨论】:

    标签: laravel-4 extend


    【解决方案1】:

    您需要创建自己的服务提供者并覆盖那里的“机器人”服务,以便它使用您的类,而不是基础类。

    1. 创建服务提供者

      use Illuminate\Support\ServiceProvider;
      class CustomRobotsServiceProvider extends ServiceProvider
      {
        public function boot()
        {
        }
      
        public function register()
        {
          $this->app['robots'] = $this->app->share(function($app)
          {
              return new AppRobots();
          });
        }
      }
      
    2. 在你的 config/app.php 中注册服务提供者

      'providers' => array(
         ... some other providers
         'Your\Namespace\CustomRobotsServiceProvider'
      ),
      

    确保您的提供程序在 RobotsServiceProvider 之后注册,以便您的服务覆盖原始服务,而不是相反。

    【讨论】:

    • 感谢您的帮助。但我现在收到此错误Call to undefined method MyApp\Healey\Robots\AppRobots::addUserAgent()。我已经用我的代码更新了我的问题
    • 您的 AppRobots 类需要扩展原来的 Robots 类。
    • 感谢我刚刚意识到并更新了这个问题。它没有将它写入文件,当我点击应用程序 url 时,我只得到这个 User-agent: * 但我也期待 Crawl-delay: 3600
    • 首先,通过外观 Robots 访问所有方法并删除您的类的别名。更改它,让我知道它是否仍然损坏
    • 我已经这样做了,没有返回错误,但是新方法没有附加到 robots.txt 路由中。任何想法为什么??
    猜你喜欢
    • 2019-02-18
    • 2018-03-29
    • 1970-01-01
    • 2019-04-05
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    相关资源
    最近更新 更多