#cakephp #cakephp-2.0 #cakephp-2.3
#cakephp #cakephp-2.0 #cakephp-2.3
Вопрос:
Мы знакомы с компонентами и помощниками в CakePHP.
У меня есть компонент ABC и помощник XYZ, и оба имеют одинаковую функцию (всего около 2000 строк, всего 4000 строк). есть какой-либо способ использовать ту же функцию в контроллере и .Файлы CTP. нехорошо использовать одну и ту же функцию 2 раза.
любой метод, чтобы я мог использовать функцию компонента / помощника в помощнике / компоненте без перезаписи?
тот же метод в компоненте и помощнике >>
Компонент
класс DATAComponent расширяет компонент {
public $components = array('Session', 'THmail');
public function UsaStateList()
{ /********/}
Помощник
class LabHelper extends AppHelper {
public function UsaStateList()
{ /********/}
}
Ответ №1:
Ну, вам придется что-то переписать, это не решит само по себе.
CakePHP по-прежнему является PHP, поэтому вы можете легко применять общие шаблоны, чтобы все оставалось СУХИМ. Вероятно, самым простым способом было бы переместить общую функциональность в служебный класс, который ваш компонент и помощник могут использовать внутри, оставив их общедоступный API неизменным.
Некоторые помощники CakePHPs делают что-то подобное, проверьте, например, time helper .
- http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html
- http://book.cakephp.org/2.0/en/core-utility-libraries/time.html#CakeTime
Черты также могут быть вариантом, в зависимости от объема совместно используемой функциональности и того, насколько она привязана к использованию в компоненте / помощнике.
Комментарии:
1. Я заметил, что на мой довольно старый ответ поступает больше голосов, и заметил награду. Это может быть неочевидно, но этот ответ был добавлен задолго до щедрости, т. Е. Это не тот подробный канонический ответ, который ищет @trante (хотя не уверен, что именно он / она ищет).
Ответ №2:
Я хотел использовать компонент внутри помощника. Итак, я пришел к следующему решению.
<?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();
}
}
Комментарии:
1. Если вы используете компоненты в помощниках, вы неправильно используете Cake MVC. Компоненты предназначены для контроллеров, а помощники — для представлений.
Ответ №3:
Простой ответ
Для общих функций в вашем приложении добавьте библиотеку или служебный класс.
app/Lib/MyClass.php
class MyClass {
public static function usaStateList() {
// ...
}
}
Затем добавьте это в начало любого файла, к которому вы хотите получить доступ к функции:
App::uses('MyClass', 'Lib');
И вызывайте свою функцию везде, где вам нравится:
$myClass = new MyClass();
$states = $myClass::usaStateList();
Лучший ответ
Мне кажется, что ваша конкретная проблема заключается в том, что вы хотите иметь возможность получать список состояний US как в вашем контроллере, так и в вашем представлении. Лучший способ сделать это — иметь таблицу базы данных состояний США.
-
Создайте таблицу в своей базе данных с именем 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
-
Вставьте все состояния в виде данных в эту таблицу. Вы можете найти SQL-дампы в Интернете, в которых уже есть это для вас (например, как этот).
-
Создайте модель UsState в CakePHP.
/** * 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'));
}
И, по вашему мнению, вы можете отобразить меню выбора для этого следующим образом:
echo $this->Form->select('us_state_id', $stateOptions);
Ответ №4:
Я бы выбрал класс в папке Lib. Довольно ясно, как работать с библиотечным классом, который имеет только статические методы. Итак, я опускаю этот случай. Приемлемым решением для создания экземпляра класса может быть его создание в контроллере и помещение в реестр. Если вам действительно нужно получить доступ к CakeRequest, CakeResponse и 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() {...}
}
Ответ №5:
хорошо, вы хотите использовать одну функцию в компоненте и помощнике, я могу придумать 3 вещи, которые вы можете сделать:
- Вызов функции из компонента в вашем помощнике.
- Вызов функции из помощника в вашем компоненте.
- Создайте модель или используйте существующую модель, в которую вы помещаете функцию, и вы можете использовать эту функцию в своем компоненте или справке.
Вариант № 3: в вашем помощнике и компоненте вам необходимо импортировать модель, предполагая, что ваша функция находится в модели «StateList»:
как вы вызываете функцию модели «StateList» в вашем помощнике, так:
App::import("Model", "StateList");
$model = new StateList();
$model->UsaStateList();
как вы вызываете функцию модели «StateList» в вашем компоненте, так:
$model = ClassRegistry::init('StateList');
$model->UsaStateList();
и если вы хотите использовать ту же функцию в контроллере, просто:
$this->loadModel('StateList');
$this->StateList->UsaStateList();
Комментарии:
1.
$model = new StateList();
это плохо.$model = ClassRegistry::init('StateList');
подходит из любого места.