How to write global functions in Yii2 and access t

2019-04-24 00:12发布

问题:

Yii1.1 had a CComponent class that had a CBaseController which was the base class for CController. There was a /protected/components/Controller.php class which enabled any function in that class to be accessed in any view.

Yii2 no longer possess the CComponent class. The Yii2 guide indicates that "Yii 2.0 breaks the CComponent class in 1.1 into two classes: yii\base\Object and yii\base\Component". Does anyone know how to write global functions in Yii2 and them in any view, just like it was in Yii1.1 using /protected/components/Controller.php?

A couple of similar topics discuss custom answers, but I would like to know whether there is an official way of doing that, not the custom way.

回答1:

Follow Step:
1) create following directory "backend/components"
2) create "BackendController.php" controller in "components" folder

<?php    
    namespace backend\components;
    use Yii;

    class BackendController extends \yii\web\Controller
    {
        public function init(){
            parent::init();

        }
        public function Hello(){
            return "Hello Yii2";
        }
    }

3) all backed controller extend to "BackendController" (like).

<?php
namespace backend\controllers;

use Yii;
use backend\components\BackendController;

class SiteController extends BackendController
{

    public function beforeAction($event)
    {
        return parent::beforeAction($event);
    }

    public function actionIndex(){
        /* You have to able for call hello function to any action and view */
        //$this->Hello(); exit;

        return $this->render('index');
    }
}

4) create your action view page "index.php" (like)

<?php
print $this->Hello();
?>


回答2:

Controller functions are not accessible in the views.

In Yii1 the view attached to the controller whereas in Yii2 the view attaches to the View class (this was one of the core changes in Yii2). This separates the controller and view logic but also makes it harder for global functions, as you have noticed.

Yii2, itself, has also needed global functions. They have made "helpers", there are in fact a number of helpers: https://github.com/yiisoft/yii2/tree/master/framework/helpers each providing their own set of global functions for use.

If you haven't guessed yet, this is the best way to do globals in Yii2. It is also the standard compliant way as well (PSR-2 or whatever) and is considered better coding than normal globals.

So, you should actually be making your own custom helpers with your globals in, for example:

class MyHelpers
{
    public static function myGlobalToDoSomethingAwesome()
    {
        return $awesomeness;
    }
}

and just reference that in your view/controller like you would any helper:

use common\components\MyHelpers;
MyHelpers::myGlobalToDoSomethingAwesome();


回答3:

One option is to create a file (probably in your components directory) that has your functions in it:

function myFunction($parameters)
{
    // Do stuff and return stuff
}

and then include it in your index.php file:

require_once(__DIR__ . "../components/MyGlobalFunctions.php');

The disadvantage is that this is now outside the OOP scope of the application. I used this method to create a dd() (dump and die) function like Laravel has.



回答4:

You can also make components in YII2

Create a directory and a file same as in YII1 in frontend or backend and write below code in it

frontend/components/Controller.php

/**
 * Description of Controller
 *
 * @author mohit
 */

namespace frontend\components;
use Yii;
class Controller extends \yii\web\Controller{
    //put your code here

    public function beforeAction($action) {
        parent::beforeAction($action);
        if(true)
            return true;
        else
            return false;

    }
}

After that use it in every controller by extending this class like this-

namespace frontend\controllers;
use Yii;
use frontend\components\Controller;
class SomeController extends Controller
{
    // code
}


回答5:

As, question is already answered. But, still I would like to answer it for future uses.

I'm using yii2-app-basic. [NOTE : Directory structure may differ for yii2-app-advanced.]

My Directory Structure:

->Root Folder
    ->assets
    ->commands
    .
    .
    ->controllers
        ->SiteController.php
        ->CommonController.php (New common controller created)
    ->mail
    .
    .
    ->modules
        ->users
            ->controllers
                ->UsersController.php
            ->models
                ->Users.php
            ->views
                ->index.php
            ->Users.php
    .
    .
    .

CommonController.php [Common controller(see in directory structure) which will be extended in all controller, if needed.]

<?php
namespace app\controllers;

use Yii;
use yii\web\Controller;

class CommonController extends Controller
{
    .
    .
    // I used this function for checking login access of user
    public function checkLoginAccess() {
        //Write your own custom code
        // For example
        $loginAccess = "No";
        if($loginAccess == "No") {
            Yii::$app->user->logout();
        }
    }
}

UsersController.php

<?php
namespace app\modules\users\controllers;

use Yii;
.
.
use app\controllers\CommonController;

//Extend CommonController 
class UsersController extends CommonController 
{
  // Inside init() function, use checkLoginAccess() method to be called
  public function init() {
    parent::init();
    if(!Yii::$app->user->isGuest) {
      $this->checkLoginAccess();
    }
  }
    .
    .
    .
}

So, Whenever this UsersController.php controller will come into an account, first init() method will be called, And in init() method CommonController method checkLoginAccess() will get call automatically. So, whenever a member having no login acess, he/she will be automatically logged out.

Hope it will help. Any Problem/Question, feel free to ask.



回答6:

Easily you can create a component:

<?php

namespace frontend\components;

use yii\base\Component;

class MyComponent extends Component
{
    public function hello()
    {
        return "Hello, World!";
    }
}

Register it as a component in your frontend/config/main.php file:

return [
    'id' => 'app-frontend',
    'basePath' => dirname(__DIR__),
    // Some code goes here
    'components' => [
        // some code here
        'memem' => [
            'class' => 'frontend\components\MyComponent'
        ],
    ],
];

and finally use it where you need:

<?php

/* @var $this \yii\web\View */
/* @var $content string */

use yii\helpers\Html;
use yii\widgets\Breadcrumbs;
?>
<?php $this->beginPage()?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="<?=Yii::$app->charset?>">
  <meta name="usage" value="<?=Yii::$app->memem->hello()?>">


回答7:

I have not started Yii2 but you should be able achieve similar functionality using static functions.

Create a class, let say "MyGlobalFunctions.php" with following contents

<?php
class MyGlobalFunctions{
    public static function myFunction($args){
       // logic here
     return someValu here
    }
}

in your views you can call this function as

MyGloabalFunctions::myFunction($args);


回答8:

I am new to Yii and tried this as solution for example messages that are shown in layout i created a baseController in frontend/components (all controllers extends this BaseController) and do the always needed stuff in the init section. and set the data to the view/layout with $this->view->params in view or layout use the data with $this->params i dont know if this is the best practice .. sorry for my bad english, i hope it helps

 namespace frontend\components;
    use Yii;
    use frontend\models\UserMessages;

    class BaseController extends \yii\web\Controller
    {
        public function init(){
            parent::init();

            // user nachrichten
            if (!Yii::$app->user->isGuest) {
                    $messages = UserMessages::find()
                    ->where(['user_recipient_id' => Yii::$app->user->identity->id])
                    ->orderBy('date_created')
                    ->all();
                    $this->view->params['userMessages'] = $messages;
            }
        }
    }