如何在Cakephp中使用helper和component中的公共函数

如何在Cakephp中使用helper和component中的公共函数,cakephp,cakephp-2.0,cakephp-2.3,Cakephp,Cakephp 2.0,Cakephp 2.3,我们熟悉CakePHP中的组件和助手 /** * Model for US States * * @package app.Model */ class UsState extends AppModel { /** * Default sort order * * @var string|array */ public $order = 'UsState.name'; } 我有一个ABC组件和XYZ助手,它们都有相同的功能(大约

我们熟悉CakePHP中的组件和助手

/**
 * Model for US States
 *
 * @package app.Model
 */
class UsState extends AppModel {

    /**
     * Default sort order
     *
     * @var string|array
     */
    public $order = 'UsState.name';
}
我有一个ABC组件和XYZ助手,它们都有相同的功能(大约2000行,总共4000行)。 有任何方法可以在控制器和.CTP文件中使用相同的函数。两次使用相同的函数是不好的

有什么方法可以不用重写就在Helper/Component中使用Component/Helper函数吗

在组件和助手中使用相同的方法>>

组件

类DATAComponent扩展组件{

public $components = array('Session', 'THmail');

public function UsaStateList()
{ /********/}
助手

class LabHelper extends AppHelper {
    public function UsaStateList()
    { /********/}
}

嗯,你必须重写一些东西,它不会自行解决

CakePHP仍然是PHP,因此您可以轻松地应用通用模式来保持干爽。最直接的方法可能是将共享功能移动到一个实用程序类中,您的组件和助手都可以在内部使用,同时保持其公共API不变

一些CakePHPs助手也做类似的事情,例如检查时间助手


也可能是一种选择,这取决于共享的功能数量以及它与组件/助手中的使用的关联程度。

我想在助手中使用组件。因此,我提出了以下解决方案

<?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();
    }

}

好的,如果您想在component and helper中使用一个函数,我可以想到三件事:

  • 从助手中的组件调用函数
  • 从组件中的帮助器调用函数
  • 在放置函数的位置创建模型或使用现有模型,您可以在组件或帮助中使用此函数
  • 选项3: 在助手和组件中,假设函数位于模型“状态列表”中,则需要导入模型:

    如何在助手中调用模型“StateList”的函数,因此:

    App::import("Model", "StateList");  
    $model = new StateList();  
    $model->UsaStateList();
    
    如何在组件中调用模型“StateList”的函数,因此:

    $model = ClassRegistry::init('StateList');
    $model->UsaStateList();
    
    ans如果您想在控制器中使用相同的功能,只需:

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

    我将使用Lib文件夹中的类。很清楚如何处理只有静态方法的库类。因此,我省略了这种情况。实例化类的可行解决方案是在控制器中创建它并将其放入注册表。如果确实需要访问CakereRequest、CakerResponse和CakeSession(请注意,CakeSession有许多静态方法,因此您通常不需要该类的实例)从该类中,您可以从控制器设置它:

    $MyLib = new MyLib();
    $MyLib->setRequest($this->request); // optional
    ClassRegistry::addObject('MyLib', $MyLib);
    
    然后从视图或任何其他位置,您只需从注册表中获取MyLib的实例:

    ClassRegistry::getObject('MyLib');
    
    或者干脆

    $list = ClassRegistry::getObject('MyLib')->UsaStateList();
    
    所以,你的课程应该是这样的:

    // /Lib/MyLib.php
    class MyLib {
        public function setRequest(CakeRequest request) {...}
        public function UsaStateList() {...}
    }
    
        echo $this->Form->select('us_state_id', $stateOptions);
    

    简单答案

    对于应用程序中的通用函数,请添加Lib或Utility类

    app/Lib/MyClass.php

    然后将其添加到要访问该函数的任何文件的顶部:

    App::uses('MyClass', 'Lib');
    
    并随时调用函数:

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

    更好的答案

    在我看来,您的具体问题是,您希望能够在控制器和视图中获得美国国家的列表。最好的方法是拥有美国国家的数据库表

  • 在数据库中创建一个名为us_states的表

    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 
    
  • 在该表中插入所有状态作为数据。您可以在Internet上找到已经为您准备好的SQL转储(例如)

  • 在CakePHP中创建UsState模型

    /**
     * Model for US States
     *
     * @package app.Model
     */
    class UsState extends AppModel {
    
        /**
         * Default sort order
         *
         * @var string|array
         */
        public $order = 'UsState.name';
    }
    
  • 然后,您可以通过使用模型从控制器访问状态

        /**
         * 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');
            }
    
        }
    
    如果您想访问视图中的这些状态,那么应该像通常传递任何其他变量一样传递这些数据

    我想你可能会想这样做,这样你就可以选择美国各州了

            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'));
            }
    
    在您的视图中,您可以显示如下所示的选择菜单:

    // /Lib/MyLib.php
    class MyLib {
        public function setRequest(CakeRequest request) {...}
        public function UsaStateList() {...}
    }
    
        echo $this->Form->select('us_state_id', $stateOptions);
    

    我注意到投票结果显示我的答案已经过时,并发现了悬赏。这可能并不明显,但这个答案早在悬赏之前就被添加了,也就是说,@trante寻找的不是详细的、规范的答案(但不确定他/她到底在寻找什么)。
    $model=new StateList();
    不好。
    $model=ClassRegistry::init('StateList');
    在任何地方都是好的。如果您在帮助程序中使用组件,那么您就错了。组件用于控制器,帮助程序用于视图。