2011-11-08 47 views
40

Tôi hơi bối rối về các cuộc gọi mà tôi thấy là Mage::getSingleton và tôi hy vọng ai đó có thể giúp tôi hiểu rõ hơn một chút.Magento getSingleton nhầm lẫn

Tôi đã thấy một đoạn mã cốt lõi mà thực hiện điều này:

Mage::getSingleton('customer/session')->isLoggedIn() 

Tôi không biết PHP, nhưng tôi nghĩ rằng tôi có thể làm cho một giả định an toàn từ getSingleton tên phương pháp đó sẽ có chỉ có một thể hiện của lớp được chỉ định (lớp được quy định như một tên lớp nhóm, và giải quyết để app/code/core/Mage/Customer/Model/Session.php - chứa lớp Mage_Customer_Model_Session

Câu hỏi 1 -.

Phương pháp getSingleton biết cách tìm trong thư mục Mô hình cho lớp học như thế nào?

Câu hỏi 2 -

Vì vậy, có một thể hiện của lớp cho cả ... Tôi muốn nói JVM như Tôi đến từ một nền tảng Java, nhưng tôi sẽ nói PHP engine với hy vọng rằng đó là mơ hồ các thuật ngữ chính xác; Mage_Customer_Model_Session không được chuyển trong id khách hàng hoặc bất kỳ số nhận dạng nào như vậy, nhưng chúng tôi gọi phương thức isLoggedIn()! Cung cấp cho không phải là một cá thể Mage_Customer_Model_Session cho mỗi khách hàng, làm thế nào chúng ta có thể hỏi một singleton nếu một khách hàng đăng nhập khi chúng tôi không nói cho nó biết khách hàng chúng ta đang nói về cái gì?

Câu hỏi 3 -

Tôi đã nhìn thấy các cuộc gọi đến Mage::getSingleton('core/session')Mage::getSingleton('customer/session') - sự khác biệt là gì?

Cảm ơn bạn đã được trợ giúp.

Trả lời

97

Đầu tiên, trước khi chúng tôi truy cập Magento, điều quan trọng là phải hiểu rằng PHP có mô hình quy trình hoàn toàn khác với Java. Một singleton PHP (bất kể sự tham gia của Magento) là một cá thể duy nhất của một lớp theo Yêu cầu HTTP. Một chương trình PHP không liên tục trong bộ nhớ giống như một chương trình Java, do đó, điều chỉnh mong đợi của bạn về một "singleton" cho phù hợp.Tiếp theo, điều quan trọng là phải hiểu rằng Magento là một khung được xây dựng trên đầu trang của PHP, sử dụng PHP, và trong nhiều trường hợp các nhà phát triển Magento ban đầu muốn đẩy mọi thứ vào một kiến ​​trúc giống Java hơn. Vì vậy, bạn sẽ thấy những thứ trông quen thuộc, quen thuộc, nhưng có thể khác biệt theo một số cách chính từ những gì bạn đang sử dụng bởi vì họ vẫn cần phải đi đến phiên bản của vũ trụ PHP.

Magento sử dụng mẫu nhà máy để khởi tạo các lớp Helpers, Blocks và "Model". Chuỗi

core/session 

là bí danh lớp. Bí danh này được sử dụng để tra cứu tên lớp trong cấu hình của Magento. Tóm lại, chuỗi này được chuyển đổi thành các biểu thức đường dẫn tìm kiếm các tệp cấu hình của Magento để lấy ra một tên lớp, dựa trên ngữ cảnh (helper, block, model) mà nó được gọi. Trong một phiên bản dài hơn, hãy xem bài viết Magento's Class Instantiation Autoload của tôi.

Khái niệm về "Mô hình" hơi mờ trong Magento. Trong một số trường hợp, các mô hình được sử dụng làm miền hoặc mô hình dịch vụ. Trong các trường hợp khác, chúng được sử dụng như một mô hình cơ sở dữ liệu trung gian bền vững hơn. Sau khi làm việc với hệ thống trong một vài năm, tôi nghĩ rằng cách an toàn nhất để suy nghĩ về Mô hình là họ đang cố gắng của Magento để làm đi với instantiation lớp trực tiếp.

Có hai cách để khởi tạo lớp mô hình.

Mage::getModel('groupname/classname'); 
Mage::getSingleton('groupname/classname'); 

Biểu mẫu đầu tiên sẽ giúp bạn có một phiên bản lớp mới. Dạng thứ hai sẽ giúp bạn có được một cá thể lớp đơn. Sự trừu tượng hóa Magento đặc biệt này cho phép bạn tạo ra một singleton ra khỏi bất kỳ lớp nào của mô hình Magento, nhưng chỉ khi bạn gắn bó với các phương thức instantiation của Magento. Nghĩa là, nếu bạn gọi

Mage::getSingleton('groupname/classname'); 

cuộc gọi sau đó tiếp theo để

Mage::getSingleton('groupname/classname'); 

sẽ trở lại mà dụ singleton. (Điều này được thực hiện với một mẫu đăng ký). Tuy nhiên, không có gì ngăn bạn trực tiếp khởi tạo một phiên bản mới của lớp học bằng cách

$o = Mage::getModel('groupname/classname'); 
$o = new Mage_Groupname_Model_Classname(); 

Điều này đưa chúng tôi đến phiên. Mô hình yêu cầu của PHP, như HTTP, ban đầu được thiết kế là không trạng thái. Mỗi yêu cầu đi vào hệ thống với và chỉ với thông tin từ người dùng. Khi ngôn ngữ (và web) chuyển sang một nền tảng ứng dụng, một hệ thống cho phép thông tin được duy trì được giới thiệu để thay thế các hệ thống phát triển trong nhà đang được cắt xén. Hệ thống này được gọi là phiên. Các phiên PHP hoạt động bằng cách trưng ra một mảng siêu toàn cầu $ _SESSION cho người lập trình người dùng cuối cho phép thông tin được lưu trữ trên cơ sở mỗi người dùng web. Phiên được triển khai bằng cách đặt ID duy nhất làm cookie trên đầu người dùng và sau đó sử dụng cookie đó làm khóa tra cứu (cũng là thực hành tiêu chuẩn cho các ứng dụng web)

Lần lượt, hệ thống Magento xây dựng sự trừu tượng trên đầu trang của PHP phiên trừu tượng. Trong Magento, bạn có thể tạo một "mô hình phiên" kế thừa từ một lớp phiên cơ sở, thiết lập các thành viên dữ liệu trên đó và lưu/tải các thành viên dữ liệu đó giống như bạn làm với mô hình kiên trì cơ sở dữ liệu. Sự khác biệt là thông tin được lưu trữ trong phiên thay vì kho lưu trữ cơ sở dữ liệu. Khi bạn thấy

core/session 
customer/session 

đây là hai mô hình phiên khác nhau, mỗi mô hình lưu trữ dữ liệu khác nhau.Một thuộc về mô-đun Mage_Core, phần còn lại thuộc về mô hình Mage_Customer. Hệ thống này cho phép các mô-đun thiết lập và thao tác một cách an toàn dữ liệu phiên của riêng chúng, mà không vô tình bước lên các ngón chân của mô-đun khác, và cung cấp các phương thức lớp logic để thao tác dữ liệu đó.

Hy vọng rằng sẽ trả lời các câu hỏi bạn đã hỏi, cũng như những câu hỏi bạn đã không hỏi.

+2

Cảm ơn bạn đã dành thời gian trả lời đầy đủ. Điều đó rất thông tin. – user265330

+1

Alan, giải thích tuyệt vời - nhưng thông tin về cuộc gọi ban đầu tới getSingleton() theo sau là các cuộc gọi tới getModel() không hoàn toàn chính xác. Vi phạm mẫu Singleton, lệnh gọi thứ hai (để getModel()) trong một phạm vi thực thi đã cho sẽ trả về một cá thể hoàn toàn mới. Các cuộc gọi tiếp theo để getSingleton() tuy nhiên sẽ trả về đối tượng singleton như được mô tả. – benmarks

+0

Lạ lùng, không chắc làm thế nào tôi có được một chút (sai) của singleton voodoo trong đầu tôi. Đã sửa văn bản. –

11
  1. getSingleton của Magento gần giống như getModel. Sự khác biệt là getModel luôn trả về một cá thể mới của một lớp, và getSingleton tạo một cá thể mới của một lớp chỉ một lần và sau đó luôn trả về cá thể này. Xem các phương thức Mage::getSingletonMage::getModel. Magento biết về việc tìm đến thư mục Mô hình vì các cấu hình trong tệp config.xml (f.e. Mage/Customer/etc/config.xml). Xem Magento wiki for developers để biết thêm về cách định cấu hình tệp.

  2. Bạn không chỉ định trực tiếp khách hàng. Nó được thực hiện tự động bởi Magento trong các lớp cha của Mage_Customer_Model_Session (xem phương pháp Mage_Core_Model_Session_Abstract_Varien::start())

  3. Magento không có một lớp phiên để phân biệt dữ liệu phiên. Ví dụ: ID khách hàng được lưu trữ trong Mage_Customer_Model_Session và thông báo lỗi flash 'Sản phẩm không khả dụng' sẽ được lưu trữ trong lớp Mage_Catalog_Model_Session.