how to use common function in helper and component In Cakephp

依然范特西╮ 提交于 2019-11-29 10:12:44

Well, you will have to rewrite something, it's not going to solve itself.

CakePHP is still PHP, so you can easily apply common patterns to keeps things DRY. The most straight forward way would probably be to move the shared functionality into an utility class that your component and helper can both use internally while leaving their public API unchanged.

Some of CakePHPs helpers do something similar, check for example the time helper.

Traits might be an option too, depending on the amount of functionality being shared and how much it is tied to the use in a component/helper.

I wanted to use a component inside a helper. So i came out with the following solution.

<?php

App::uses('AppHelper', 'View/Helper');
App::import('Component', 'MyComponent');

class MyHelperHelper extends AppHelper {

    private $MyComponent = null;

    public function __construct(View $View, $settings = array()) {
        $collection = new ComponentCollection();
        $this->MyComponent = new MyComponentComponent($collection);
        parent::__construct($View, $settings);
    }

    public function myCustomFunction() {
        return $this->MyComponent->myCustomFunction();
    }

}

I would go with a class in Lib folder. It is pretty clear how to deal with a library class that has only static methods. So, I omit this case. A workable solution for instantiating the class could be to create it in the controller and put it into the registry. If you really need to access CakeRequest, CakeResponse and CakeSession (take a note that CakeSession has many static methods, so you often do not need an instance of that class) from that class you can set it from the controller:

$MyLib = new MyLib();
$MyLib->setRequest($this->request); // optional
ClassRegistry::addObject('MyLib', $MyLib);

Then from the view or any other place you would just get an instance of MyLib from the registry:

ClassRegistry::getObject('MyLib');

or simply

$list = ClassRegistry::getObject('MyLib')->UsaStateList();

So, your class would be something like this:

// /Lib/MyLib.php
class MyLib {
    public function setRequest(CakeRequest request) {...}
    public function UsaStateList() {...}
}

ok you want to use a single function in component and helper, I can think of 3 things you can do:

  1. Calling a function from the component in your helper.
  2. Calling a function from a helper in your component.
  3. Create a model or use an existing model where you put the function, and you can use this function in your component or your help.

Option numbre 3: In your helper and component, you need import a model, assuming that your function be in a model "StateList":

how you call the funcion of the model "StateList" in your helper, so:

App::import("Model", "StateList");  
$model = new StateList();  
$model->UsaStateList();

how you call the funcion of the model "StateList" in your component, so:

$model = ClassRegistry::init('StateList');
$model->UsaStateList();

ans if you want use the same function in a controller just:

$this->loadModel('StateList');
$this->StateList->UsaStateList();

Simple Answer

For common functions across your application, add a Lib or Utility class.

app/Lib/MyClass.php

class MyClass {

    public static function usaStateList() {
        // ...
    }
}

Then add this at the top of whichever file you want access to the function:

App::uses('MyClass', 'Lib');

And call your function wherever you like:

$myClass = new MyClass();
$states = $myClass::usaStateList();

Better Answer

It looks to me like your specific problem is that you want to be able to get a list of US states in both your controller and your view. The best way to do this is to have a database table of US states.

  1. Create a table in your database called us_states.

    Example SQL:

    CREATE TABLE `us_states` (
        `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        `name` VARCHAR(20) NOT NULL,
        `abbreviation` CHAR(2) NOT NULL
    ) ENGINE = MYISAM 
    
  2. Insert all the states as data in that table. You can find SQL dumps on the Internet which already have that for you (e.g. Like this one).

  3. Create a UsState model in CakePHP.

    /**
     * Model for US States
     *
     * @package app.Model
     */
    class UsState extends AppModel {
    
        /**
         * Default sort order
         *
         * @var string|array
         */
        public $order = 'UsState.name';
    }
    

What you can then do is access the states from your controller just by using the model.

    /**
     * Your Controller
     *
     * @package app.Controller
     */
    class YourController extends AppController {

        public function index() {

            // Get a list of US states
            $this->loadModel('UsState');
            $states = $this->UsState->find('all');
        }

    }

And if you want to access those states in your View, then you should pass along that data as you normally would any other variables.

I imagine you would want to do that so you can have a select menu of US states, perhaps.

        public function index() {

            // Get a list of US states
            $this->loadModel('UsState');
            $states = $this->UsState->find('all');

            // Make the states into an array we can use for a select menu
            $stateOptions = array();
            foreach ($states as $state) {
                $stateOptions[$state['id']] = $state['name'];
            }

            // Send the options to the View
            $this->set(compact('stateOptions'));
        }

And in your view you can display a select menu for that like this:

    echo $this->Form->select('us_state_id', $stateOptions);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!