Câu hỏi của tôi ngắn gọn: Tôi có thể sử dụng một Nhà máy duy nhất cho nhiều bộ điều khiển không?Nhà máy đơn lẻ cho nhiều bộ điều khiển?
Thông tin chi tiết:
Tôi có một số cài đặt cụ thể phi mô-đun trên toàn cầu trong /config/autoload/global.php mà trông như thế này:
return array(
'settings' => array(
'setting_a' => 'foo',
'setting_b' => 'bar'
),
// More ZF default configuration ...
);
Bây giờ tôi muốn thực hiện các thiết lập này có thể truy cập trong mọi bộ điều khiển mà không phải gọi số $this->getServiceLocator()->get('config')
mọi lúc.
Vì vậy, ý tưởng của tôi là giới thiệu thuộc tính lớp $settings
trong số AbstractController
thuộc tính được tiêm vào mảng cấu hình. Tôi đã cố gắng tìm nạp cấu hình trực tiếp trong hàm tạo của AbstractController
. Tuy nhiên getServiceLocator()
dường như không sẵn sàng vào thời điểm đó và trả về NULL.
tôi có thể xây dựng nhà máy điều khiển cho mỗi bộ điều khiển và tiêm các thiết lập như thế này:
class ControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('config');
return new \MyModule\Controller\MyController($config['settings']);
}
}
Nhưng nó sẽ là như nhau hơn và hơn nữa. Vì vậy, câu hỏi của tôi là: Tôi có thể sử dụng một Nhà máy duy nhất cho nhiều bộ điều khiển không?
Trong module.config.php tôi tôi có thể xác định một lớp nhà máy duy nhất cho nhiều bộ điều khiển:
return array(
'controllers' => array(
'factories' => array(
'MyModule\Controller\MyControllerA' => 'MyModule\Factory\ControllerFactory',
'MyModule\Controller\MyControllerB' => 'MyModule\Factory\ControllerFactory',
'MyModule\Controller\MyControllerC' => 'MyModule\Factory\ControllerFactory',
)
),
);
Nhưng trong nhà máy Tôi cần phải trả lại đối tượng điều khiển thực tế bằng tay (xem ví dụ ở trên) mà tất nhiên chỉ hoạt động với một Nhà máy trên mỗi Bộ điều khiển.
Hy vọng, tôi đã giải quyết vấn đề của mình rõ ràng.
CẬP NHẬT 2013/03/24:
Mặc dù đầu tiên tôi đi theo giải pháp gợi ý bằng cách tạo ra một khởi tạo, tôi không bao giờ thực sự thích sử dụng nó chỉ dành riêng cho việc tiêm cấu hình.
Vì vậy, tôi tiếp tục tìm hiểu và tạo ra một Plugin điều khiển để nhận cài đặt.
Mã cho plugin trông như thế này:
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
class Settings extends AbstractPlugin
{
protected $settings;
public function __invoke()
{
$config = $this->getController()->getServiceLocator()->get('Config');
if (isset($config['settings']) && is_array($config['settings'])) {
$this->settings = $config['settings'];
}
return $this->settings;
}
}
Sau khi thêm plugin trong module.config.php với
'controller_plugins' => array(
'invokables' => array(
'settings' => 'My\Controller\Plugin\Settings',
)
),
tôi có thể dễ dàng truy cập các thiết lập của tôi trong một bộ điều khiển bằng chỉ cần gọi số $this->settings()
. Hy vọng điều này sẽ giúp bất cứ ai.
Cám ơn ý tưởng của bạn. Trình tự khởi tạo hoạt động giống như bạn mô tả, tuy nhiên khi tôi thêm nó vào mảng 'bộ điều khiển', ánh xạ điều khiển bằng cách nào đó bị mất và tôi nhận được lỗi nói * "Bộ điều khiển được yêu cầu không thể ánh xạ tới lớp bộ điều khiển hiện có." dường như cả 'invokables' và 'initializers' trong 'controllers' đều cắn nhau. Bạn có đề nghị nào không? – Rob
Tôi sẽ tua lại chỉ để invokables sau đó áp dụng initializer - sau đó gỡ lỗi nếu initializer là nhận được một ví dụ. Thông báo lỗi được đưa ra có thể do một số lý do, đảm bảo tất cả các định nghĩa sử dụng đều chính xác và không có lỗi. Để khai thác sâu hơn, tôi cũng sẽ xem xét \ Zend \ Mvc \ Service \ ControllerLoaderFactory.php và làm theo nó thông qua \ Zend \ Mvc \ Controller \ ControllerManager.php - Tôi hy vọng điều đó sẽ giúp ích cho bạn. – DrBeza
Tìm ra nguyên nhân: Đó là cuộc gọi '$ serviceLocator-> get ('Config')' trong Initializer :: initialize() mà ném một * dịch vụ không tìm thấy ngoại lệ *. Vì vậy, có vẻ như cấu hình chưa sẵn sàng ở giai đoạn khởi tạo. Và tôi vẫn không thể có được các thiết lập của tôi vào bộ điều khiển :-(Sẽ thử một cách giải quyết ngay bây giờ – Rob