2014-06-17 16 views
8

Chúng tôi đã quen thuộc với các thành phần và trình trợ giúp trong CakePHP.cách sử dụng chức năng chung trong trợ giúp và thành phần Trong CakePHP

Tôi có một thành phần ABC và trợ giúp XYZ và cả hai đều có cùng chức năng (khoảng 2000 dòng tổng 4000 dòng). có bất kỳ cách nào để sử dụng cùng chức năng trong Bộ điều khiển và tệp .CTP. nó không tốt để sử dụng cùng một chức năng 2 thời gian.

bất kỳ phương pháp nào để tôi có thể sử dụng chức năng Thành phần/Trình trợ giúp trong Trình trợ giúp/Thành phần mà không viết lại?

cùng phương pháp thành phần và helper >>

Component

lớp DATAComponent kéo dài Component {

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

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

Helper

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

Trả lời

7

Vâng, bạn sẽ phải viết lại một cái gì đó, nó sẽ không tự giải quyết.

CakePHP vẫn là PHP, vì vậy bạn có thể dễ dàng áp dụng các mẫu phổ biến để giữ mọi thứ KHÔ. Cách chuyển tiếp thẳng thắn nhất có lẽ là di chuyển chức năng được chia sẻ vào một lớp tiện ích mà thành phần và trợ giúp của bạn có thể sử dụng cả trong khi vẫn không thay đổi API công khai của họ.

Một số người giúp đỡ CakePHPs làm điều tương tự, hãy kiểm tra ví dụ như trình trợ giúp thời gian.

Traits có thể là một lựa chọn quá, tùy thuộc vào số lượng các chức năng được chia sẻ và bao nhiêu nó được gắn liền với việc sử dụng trong một thành phần/helper .

+0

tôi đã nhận thấy upvotes sắp tới trong câu trả lời khá cũ của tôi và phát hiện tiền thưởng. Nó có thể không được rõ ràng, nhưng câu trả lời này đã được thêm vào lâu trước khi tiền thưởng, tức là nó không phải là một chi tiết, kinh điển mà @trante đang tìm kiếm (không chắc chắn chính xác những gì anh ta đang tìm kiếm). – ndm

2

Tôi muốn sử dụng một thành phần bên trong trình trợ giúp. Vì vậy, tôi đã đưa ra giải pháp sau.

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

} 
+3

Nếu bạn đang sử dụng các thành phần trong trình trợ giúp, bạn đang làm Bánh MVC sai. Các thành phần dành cho Bộ điều khiển và Trình trợ giúp dành cho Chế độ xem. – BadHorsie

1

ok bạn muốn sử dụng một chức năng duy nhất trong thành phần và helper, tôi có thể nghĩ đến 3 điều bạn có thể làm:

  1. Gọi một chức năng từ thành phần trong helper của bạn.
  2. Gọi hàm từ người trợ giúp trong thành phần của bạn.
  3. Tạo mô hình hoặc sử dụng mô hình hiện có nơi bạn đặt chức năng và bạn có thể sử dụng chức năng này trong thành phần của bạn hoặc trợ giúp của bạn.

Lựa chọn numbre 3: Trong helper và thành phần của bạn, bạn cần phải nhập khẩu một mô hình, giả định rằng chức năng của bạn được trong một mô hình "StateList":

cách bạn gọi funcion của mô hình "StateList" trong helper của bạn, vì vậy:

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

cách bạn gọi funcion của mô hình "StateList" trong thành phần của bạn, vì vậy:

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

ans nếu bạn muốn sử dụng các chức năng tương tự trong một bộ điều khiển chỉ:

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

'$ model = new StateList();' là xấu. '$ model = ClassRegistry :: init ('StateList');' là tốt từ mọi nơi. – bancer

2

tôi sẽ đi với một lớp trong thư mục Lib. Nó là khá rõ ràng làm thế nào để đối phó với một lớp thư viện mà chỉ có phương pháp tĩnh. Vì vậy, tôi bỏ qua trường hợp này. Một giải pháp khả thi để khởi tạo lớp có thể là tạo ra nó trong bộ điều khiển và đặt nó vào sổ đăng ký. Nếu bạn thực sự cần truy cập CakeRequest, CakeResponse và CakeSession (hãy lưu ý rằng CakeSession có nhiều phương thức tĩnh, vì vậy bạn thường không cần một cá thể của lớp đó) từ lớp đó bạn có thể đặt nó từ bộ điều khiển:

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

Sau đó, từ quan điểm hay bất cứ nơi nào khác bạn sẽ chỉ nhận được một thể hiện của mylib từ registry:

ClassRegistry::getObject('MyLib'); 

hoặc đơn giản là

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

Vì vậy, lớp học của bạn sẽ được một cái gì đó như thế này:

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

đơn giản trả lời

Đối với các chức năng phổ biến trên ứng dụng của bạn, thêm một Lib hoặc lớp Utility.

app/Lib/MyClass.php

class MyClass { 

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

Sau đó thêm này ở phía trên cùng của tập tin nào bạn muốn truy cập vào các chức năng:

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

Và gọi chức năng của bạn bất cứ nơi nào bạn thích :

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

Better trả lời

Có vẻ với tôi như vấn đề cụ thể của bạn là bạn muốn có thể để có được một danh sách các tiểu bang Hoa Kỳ trong cả hai điều khiển của bạn và xem bạn. Cách tốt nhất để làm điều này là có một bảng cơ sở dữ liệu của các tiểu bang Hoa Kỳ.

  1. Tạo bảng trong cơ sở dữ liệu của bạn được gọi là us_states.

    Ví dụ 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. Chèn tất cả các tiểu bang như dữ liệu trong bảng đó. Bạn có thể tìm thấy các bãi chứa SQL trên Internet đã có sẵn cho bạn (ví dụ: Like this one).

  3. Tạo mô hình USState trong CakePHP.

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

gì bạn có thể làm là truy cập vào các tiểu bang từ điều khiển của bạn chỉ bằng cách sử dụng mô hình.

/** 
    * 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'); 
     } 

    } 

Và nếu bạn muốn truy cập các trạng thái đó trong Chế độ xem, bạn nên chuyển dữ liệu đó như bình thường với bất kỳ biến nào khác.

Tôi tưởng tượng bạn muốn làm điều đó để có thể có một thực đơn lựa chọn các tiểu bang của Hoa Kỳ.

 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')); 
     } 

Và theo quan điểm của bạn, bạn có thể hiển thị một menu chọn cho điều đó như thế này:

echo $this->Form->select('us_state_id', $stateOptions); 
Các vấn đề liên quan