Laravel : Calling functions defined in base_contro

2020-05-27 03:17发布

问题:

In using the laravel framework, how can I call a function defined in base_controller, in a view. For exacmple:

class Base_Controller extends Controller {

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

How can i call format_something() in a view file?

Usually the error I get looks something like this: Method [link_to_action] is not defined on the View class.

Probably a silly question, but thanks in advance!

Edit

Okay! First the correct place to do something like this is in the libraries folder. Second, problem is that your class cannot have underscores.

So in application/libraries I made file AppHelper.php with class

class AppHelper {

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

And can call it like:

$formated = AppHelper::format_something;

Thanks for the help and the good forum find Boofus McGoofus.

回答1:

This answer was written for Laravel 3. For Laravel 4 and after, Lajdák Marek's answer using Composer's autoloader is better.

Functions like format_something() don't belong in the controller. The controller should just be about collecting data from various sources and passing it to the view. It's job is mostly just routing.

I've created a folder called "helpers" in the application folder for all my little helpery functions. To make sure all my controllers, views, and models have access to them, I've included the following in my start.php file:

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

I suspect that there's a better way to do that, but so far it has worked for me.



回答2:

For me is working:

Create directory "helpers" or whatever and file:

// app/helpers/AppHelper.php

class AppHelper {

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

Add path to composer.json

// composer.json

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

Run: (reload the autoload)

composer dump-autoload

Now you can call:

$formated = AppHelper::format_something();


回答3:

You can inspire yourself from Laravel framework itself.

I will take your example of a formatter and refer to url helper in Laravel Framework.

Start by creating your own helpers.php file:

<?php

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

And add it to your composer.json file:

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

Run this command to recreate the autoload php file:

$ composer dumpautoload

Create your service provider 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']);
        });
    }
}

Register your service provider. Laravel framework invokes register method but you only need to add it to your app config file config/app.php:

 'providers' => [


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

 ]

Finally, create your actual generator 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;
        }
    }

}

You can optionally create a Facade app/Facade/Formatter.php, to be able to do 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'; }
}

You could ask yourself:

  • Why the facade? You can reuse the component somewhere else by simply calling Formatter::format_that($text) instead of app('formatter')->format_that($text). Sugar syntax really.
  • Why the Service provider? Dependence injections. If you need to use Request or want to build a complex object, the Service provider will take care of that for you and make it available in your $app object.