Laravel:如何从视图中调用在base_controller中定义的函数

15

在使用 Laravel 框架时,我该如何在视图中调用在 base_controller 中定义的函数。例如:

class Base_Controller extends Controller {

    public static function format_something()
    {
         return something;
    }
}

如何在视图文件中调用format_something()函数?

通常我遇到的错误看起来像这样: 在View类上未定义方法[link_to_action]。

可能是一个愚蠢的问题,但提前感谢您!

编辑

好的!首先,正确的做法是在libraries文件夹中进行此类操作。 其次,问题在于您的类不能有下划线。

所以在application/libraries中,我创建了名为AppHelper.php的文件,并声明了相应的类。

class AppHelper {

    public static function format_something()
    {
        return something;
    }
}

并且可以这样调用:

$formated = AppHelper::format_something;

感谢Boofus McGoofus提供的帮助和好的论坛资源。

3个回答

21

对我来说有效的方法是:

创建一个名为“helpers”或其他名称的目录和文件:

// app/helpers/AppHelper.php

class AppHelper {

    public static function format_something()
    {
        return something;
    }
}
在 composer.json 中添加路径。
// composer.json

    "autoload": {
        "classmap": [
                    "app/helpers"   // <-------- add this line
        ]
    },

运行:(重新加载自动加载)

composer dump-autoload

现在您可以进行调用:

$formated = AppHelper::format_something();

这个方法也非常有用,特别是如果你在项目中使用了Composer。(顺便提一下,这个帖子是关于L3的)。 - Jim
4
使用这种技术,我可以在控制器中调用该方法,但不能在模板中调用。最终我想要的是在视图模板中执行{{Notifier::alert('info', 'My info message')}}。我该如何实现? - John Corry
严格按照这个做了,但是出现了“找不到'AppHelper'类”的错误。 - Edmund Sulzanok

10

此答案是为Laravel 3编写的。对于Laravel 4及以上版本,使用Composer的自动加载器的Lajdák Marek的答案更好。

format_something()这样的函数不应该放在控制器中。控制器只应该收集来自各种来源的数据并将其传递给视图。它的工作主要是路由。

我在应用程序文件夹中创建了一个名为“helpers”的文件夹,用于存放所有我的小助手函数。为了确保我的所有控制器、视图和模型都可以访问它们,我在我的start.php文件中包含了以下内容:

foreach(glob(path('app').'helpers/*.php') as $filename) {
    include $filename;
}

我觉得可能有更好的方法,但到目前为止这种方式对我有用。


所以我创建了一个名为App_Helpers.php的库文件,其中包含名为App_Helpers的类。根据我的判断,start.php中的自动加载程序默认加载库文件夹,但我的应用程序似乎仍然不知道App_Helpers :: format_something()是什么? - Jim
1
@Jim - 我认为答案在这里:http://forums.laravel.com/viewtopic.php?pid=18328#p18328 - 类库类名中不要使用下划线。 - J.T. Grimes
如果您将文件添加到库文件夹中,它不会自动加载吗? - mattl
它确实可以,但出于我在该项目中的个人原因,我想要独立的函数而不是对象,并且(据我回忆)自动加载器更喜欢类而不是函数列表。 - J.T. Grimes
这对我不起作用 - 它将函数加载到HTML中(在任何其他内容之前的顶部),但它将其注释掉 - 这意味着它不起作用。 - bagnap

3
你可以从Laravel框架本身中获取灵感。
我将以Laravel框架中的url助手为例,参考您的格式化器示例。
首先创建自己的helpers.php文件:
<?php

if (! function_exists('format_that')) {
    /**
     * Generate something
     *
     * @param  string  $text
     * @return string
     */
    function format_that($text)
    {
        return app('formatter')->format_that($text);
    }
}

add it添加到你的composer.json文件中:

"autoload": {
      "files": [
          "app/helpers/helpers.php"
      ]
}

运行以下命令以重新创建自动加载PHP文件:
$ composer dumpautoload

创建您的服务提供商app/Providers/FormatterServiceProvider.php:
<?php

namespace Illuminate\Routing;

use Illuminate\Support\ServiceProvider;
use App\Helpers\FormatGenerator;

class FormatterServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app['formatter'] = $this->app->share(function ($app) {
            return new FormatGenerator($app['request']);
        });
    }
}

注册你的服务提供者。Laravel框架会调用register方法,但你只需要将它添加到应用程序配置文件config/app.php中:

 'providers' => [


      /*
       * Application Service Providers...
       */
      App\Providers\AppServiceProvider::class,
      // other providers...
      App\Providers\FormatterServiceProvider::class,

 ]

最后,创建您的实际生成器类 app/Helpers/FormatGenerator.php
<?php

namespace App\Helpers;

use Illuminate\Http\Request;

class FormatGenerator
{

    protected $request;

    /**
     * Create a new URL Generator instance.
     *
     * @param  \Illuminate\Routing\RouteCollection  $routes
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function format_that($text){
        if ($request->path() == "home"){
            return mb_strtoupper($text);
        }
        else{
            return $text;
        }
    }

}

你可以选择创建门面app/Facade/Formatter.php,以便能够执行Formatter::format_that($text):
<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

/**
 * @see \App\Helpers\FormatGenerator
 */

class Formatter extends Facade
{
    protected static function getFacadeAccessor() { return 'formatter'; }
}

你可以问自己:
  • 为什么需要外观模式? 通过简单调用 Formatter::format_that($text) 而不是 app('formatter')->format_that($text),你可以在其他地方重复使用组件。这真的很方便。
  • 为什么需要服务提供者? 依赖注入。如果你需要使用 Request 或想要构建一个复杂的对象,服务提供者会为你处理并在 $app 对象中使其可用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接